#version 410 uniform float yRatio; // height/width uniform float eyePos; uniform mat4 cameraMatrix; in vec3 pos; in float partId; // part attrs uniform sampler2D partValues; // part transform, in four columns uniform float partIndex_xform1; uniform float partIndex_xform2; uniform float partIndex_xform3; uniform float partIndex_xform4; in float partSlot; out vec4 fragColorV; void main(void) { // part matrix mat4 partMatrix = mat4( texture(partValues, vec2(partIndex_xform1, partSlot)), texture(partValues, vec2(partIndex_xform2, partSlot)), texture(partValues, vec2(partIndex_xform3, partSlot)), texture(partValues, vec2(partIndex_xform4, partSlot))); float yRatioScaler = yRatio > 1.0 ? 1.0 : yRatio; float xMore = yRatio / yRatioScaler; float yMore = 1.0 / yRatioScaler; float zFixer = -150.0; // we flip & compress Z for the final depth write. Our world is all in RHS, negative Z from screen. Device is +Z. // matrix is actually transpose of how it "looks" here... mat4 projectionMatrix = mat4(xMore, 0, 0, 0, 0, yMore, 0, 0, 0, 0, 1.0 / zFixer, -1.0 / eyePos, 0, 0, eyePos/ zFixer, 0); mat4 viewMatrix = cameraMatrix * partMatrix; mat4 transformMatrix = projectionMatrix * viewMatrix; vec4 transformedPos = transformMatrix * vec4(pos, 1.0); gl_Position = transformedPos; // encode the partId as rgb, expecting later 8-bit resolution. int partIdI = int(partId); int partId00 = (partIdI >> 0) % 256; int partId08 = (partIdI >> 8) % 256; int partId16 = (partIdI >> 16) % 256; // offset the blue a little bit, so even low partIds are visible. partId16 += 64; fragColorV.r = float(partId00) / 255.0; fragColorV.g = float(partId08) / 255.0; fragColorV.b = float(partId16) / 255.0; fragColorV.a = 1.0; }