
uniform vec3 cameraPosition;
uniform mat4 gbufferModelViewInverse;
uniform vec2 taaOffset;

#ifndef MC_GL_VENDOR_INTEL
	#define attribute in
#endif

attribute vec4 mc_Entity;
attribute vec4 at_tangent;

out vec4 tint;
out vec2 texcoord;
out vec3 minecraftPos;
out vec4 viewPos;

out vec2 lightmap;

flat out mat3 tbnMatrix;

flat out uint materialIDs;

#include "/Settings.glsl"

// ============================================================================
// PHYSICS OCEAN SUPPORT - MC 1.21.1+ Compatible
// ============================================================================
#define PHYSICS_OCEAN_SUPPORT

#ifdef PHYSICS_OCEAN
	#define PHYSICS_VERTEX
	#include "/lib/Water/PhysicsOceans.glsl"
#endif

void main() {
	tint = gl_Color;
	texcoord = mat2(gl_TextureMatrix[0]) * gl_MultiTexCoord0.xy + gl_TextureMatrix[0][3].xy;

	#ifdef PHYSICS_OCEAN
		// Get waviness from texture (measures shore proximity)
		physics_localWaviness = texelFetch(physics_waviness, ivec2(gl_Vertex.xz) - physics_textureOffset, 0).r;
		
		// Calculate wave displacement
		float waveDisplacement = physics_waveHeight(
			gl_Vertex.xz, 
			PHYSICS_ITERATIONS_OFFSET, 
			physics_localWaviness, 
			physics_gameTime
		);
		
		// Apply displacement to vertex position
		vec4 finalPosition = vec4(
			gl_Vertex.x, 
			gl_Vertex.y + waveDisplacement, 
			gl_Vertex.z, 
			gl_Vertex.w
		);
		
		// Pass position to fragment shader for per-pixel normals
		physics_localPosition = finalPosition.xyz;
		
		// Transform to view space
		viewPos = gl_ModelViewMatrix * finalPosition;
	#else
		// Standard vertex transformation without physics
		viewPos = gl_ModelViewMatrix * gl_Vertex;
	#endif
	
	// Project to clip space
	gl_Position = gl_ProjectionMatrix * viewPos;

	// Calculate world space position
	minecraftPos = mat3(gbufferModelViewInverse) * viewPos.xyz + gbufferModelViewInverse[3].xyz + cameraPosition;

	// Build TBN matrix for normal mapping
    tbnMatrix[2] = normalize(gl_NormalMatrix * gl_Normal);
    tbnMatrix[0] = normalize(gl_NormalMatrix * at_tangent.xyz);
    tbnMatrix[1] = cross(tbnMatrix[0], tbnMatrix[2]) * sign(at_tangent.w);

	// Apply TAA jitter if enabled
	#ifdef TAA_ENABLED
		gl_Position.xy += taaOffset * gl_Position.w;
	#endif

	// Process lightmap coordinates
	lightmap = clamp(gl_MultiTexCoord1.xy * (1.0 / 240.0), 0.0, 1.0);

	// Material ID processing (water is ID 17)
	materialIDs = max(uint(mc_Entity.x - 1e4), 16u);
}
