#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 = wash lift, y = receiveShadow (unread), z = contour weight, w = ink 0..1 layout(location = 7) in vec4 aInstFx; // x = wet, y = paper seed, z = flat (1 = line art, no shading), w = unused #include "_graphics_uniforms.glsl" out highp vec3 vNormal; out highp vec3 vWorldPos; out vec4 vColor; out vec3 vSurface; // x = wash lift, y = contour weight, z = ink out vec3 vPen; // x = wet, y = paper seed, z = flat vec3 quatRotate(vec4 q, vec3 v) { return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); } void main() { vec3 local = aPos * aInstScale; vec3 world = quatRotate(aInstRot, local) + 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; vSurface = vec3(aInstParams.x, aInstParams.z, aInstParams.w); vPen = aInstFx.xyz; }