#version 300 es

precision mediump float;

// Input attributes
in vec4 aPosition;
in vec2 aTextureCoord;
in vec3 aNormal;
in vec4 aTransform;// xy: position offset, zw: scale factors
in vec4 aEndTransform;// xy: position offset, zw: scale factors
in vec4 aUVTransform;// Instance UV transform: xy=scale, zw=offset
in vec4 aLockUVTransform;// Instance UV transform: xy=scale, zw=offset
in vec4 aExtra;

// Uniforms
uniform mat4 uMVPMatrix;
uniform vec4 u_uv_trans;
uniform float uScale;
uniform float uRate;
uniform float u_aspect_ratio;
uniform float uRandomMin;// Minimum random range value
uniform float uRandom;// Random seed value

// Viewport dimensions for UV calculation

// Outputs to fragment shader
out vec2 v_originTexCoord_local;
out vec2 v_originTexCoord;
out vec2 v_lockOriginTexCoord;
out vec2 v_viewportUV;  // 新增：视口空间的UV坐标
out vec3 vONormal;
out vec3 vNormal;
out float vRandom;
out float isEdge;

const float PI = 3.141592653589793;

// Optimized random function
float rand(vec2 co) {
    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}


void main() {
    float revRate = 1.0 - uRate;
    float instanceID = float(gl_InstanceID + 1);

    // Interpolate transform based on rate
    vec4 currentTransform = mix(aTransform, aEndTransform, revRate);

    // Extract scale factors
    vec2 scale = currentTransform.zw;

    // Build transformation matrices
    mat3 scaleMatrix = mat3(
    scale.x, 0.0, 0.0,
    0.0, scale.y, 0.0,
    0.0, 0.0, 1.0
    );

    // Calculate rotation
    float rotation = aExtra.x > 0.0 ? 0.0 : mix(PI, 0.0, uRate);
    float cosA = cos(rotation);
    float sinA = sin(rotation);
    mat3 rotationMatrix = mat3(
    cosA, 0.0, sinA,
    0.0, 1.0, 0.0,
    -sinA, 0.0, cosA
    );

    // Apply transformations
    vec3 position = rotationMatrix * scaleMatrix * vec3(aPosition.xyz);
    position.xy += currentTransform.xy;
    //  补偿cell厚度不同 0.45  public final static float CELL_Z = 0.1f;
    position.z += -5.0 + 0.45;

    // Final position
    gl_Position = uMVPMatrix * vec4(position, aPosition.w);

    // UV coordinates
    v_originTexCoord_local = aTextureCoord;
    v_originTexCoord = vec2(1.0 - aTextureCoord.x, aTextureCoord.y) * aUVTransform.xy + aUVTransform.zw;
    v_lockOriginTexCoord = vec2(1.0 - aTextureCoord.x, aTextureCoord.y) * aLockUVTransform.xy + aLockUVTransform.zw;

    // Normal and random calculations
    vONormal = normalize(aNormal);
    // float randomMin = uRandomMin * uRate + min(uRandomMin, 0.5 * revRate);
    float randomMin = uRandomMin * uRate;
    vRandom = rand(vec2(instanceID + uRandom)) * (1.0 - randomMin) + randomMin;

    isEdge = aExtra.x;
}
