#version 300 es layout(location = 0) in vec3 aPos; layout(location = 1) in vec3 aNormal; layout(location = 2) in vec4 aInstRot; layout(location = 3) in vec3 aInstPos; layout(location = 4) in vec3 aInstScale; layout(location = 5) in vec4 aInstColor; layout(location = 6) in vec4 aInstParams; // x = emissive, y = receiveShadow, z = fresnel, w = custom0 (unread here) #include "_graphics_uniforms.glsl" out highp vec3 vNormal; out highp vec3 vWorldPos; out vec4 vColor; out float vEmissive; out float vReceiveShadow; out float vFresnel; vec3 quatRotate(vec4 q, vec3 v) { return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); } void main() { vec3 world = quatRotate(aInstRot, aPos * aInstScale) + aInstPos; // inverse-transpose of a diagonal scale is 1/scale — exact for axis-aligned box normals vNormal = quatRotate(aInstRot, normalize(aNormal / aInstScale)); gl_Position = u_viewProjection * vec4(world, 1.0); vWorldPos = world; vColor = aInstColor; vEmissive = aInstParams.x; vReceiveShadow = aInstParams.y; vFresnel = aInstParams.z; }