viewer/shaders/vertex.glsl.js
export const VERTEX_SHADER_SOURCE = `
precision highp int;
precision highp float;
#ifdef WITH_QUANTIZEVERTICES
uniform mat4 vertexQuantizationMatrix;
in ivec3 vertexPosition;
#else
in vec3 vertexPosition;
#endif
#ifdef WITH_LINEPRIMITIVES
#ifdef WITH_QUANTIZEVERTICES
in ivec3 nextVertexPosition;
#else
in vec3 nextVertexPosition;
#endif
in float direction;
#endif
#ifndef WITH_PICKING
#ifndef WITH_LINES
#ifdef WITH_QUANTIZENORMALS
#ifdef WITH_OCT_ENCODE_NORMALS
in ivec2 vertexNormal;
#else
in ivec3 vertexNormal;
#endif
#else
in vec3 vertexNormal;
#endif
#endif
#endif
#ifndef WITH_USEOBJECTCOLORS
#ifndef WITH_PICKING
#ifndef WITH_LINES
#ifdef WITH_QUANTIZECOLORS
in uvec4 vertexColor;
#else
in vec4 vertexColor;
#endif
#endif
#endif
#endif
#ifdef WITH_INSTANCING
in mat4 instanceMatrices;
uniform uint numContainedInstances;
uniform uint containedInstances[256];
uniform uint containedMeansHidden;
#ifndef WITH_PICKING
#ifndef WITH_LINES
in mat3 instanceNormalMatrices;
#endif
#endif
#endif
#ifdef WITH_PICKING
#ifdef WITH_INSTANCING
in uvec4 instancePickColors;
#else
in uvec4 vertexPickColor;
#endif
flat out uvec4 color;
#else
#ifndef WITH_LINEPRIMITIVES
uniform LightData {
vec3 dir;
vec3 color;
vec3 ambientColor;
float intensity;
} lightData;
#endif
out vec4 color;
#endif
#ifdef WITH_USEOBJECTCOLORS
uniform vec4 objectColor;
#endif
#ifdef WITH_LINEPRIMITIVES
uniform vec4 inputColor;
uniform mat4 matrix;
uniform float aspect;
uniform float thickness;
#else
#ifndef WITH_LINES
uniform mat3 viewNormalMatrix;
#endif
#endif
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 postProcessingTranslation;
out vec3 worldCoords;
vec3 octDecode(vec2 oct) {
vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y));
if (v.z < 0.0) {
v.xy = (1.0 - abs(v.yx)) * vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0);
}
return normalize(v);
}
void main(void) {
#ifndef WITH_INSTANCING
#ifdef WITH_QUANTIZEVERTICES
vec4 floatVertex = vec4(postProcessingTranslation, 0) + vertexQuantizationMatrix * vec4(float(vertexPosition.x), float(vertexPosition.y), float(vertexPosition.z), 1);
#else
vec4 floatVertex = vec4(postProcessingTranslation, 0) + vec4(vertexPosition, 1);
#endif
#endif
#ifndef WITH_PICKING
#ifndef WITH_LINES
#ifdef WITH_QUANTIZENORMALS
#ifdef WITH_OCT_ENCODE_NORMALS
vec2 normal = vec2(float(vertexNormal.x), float(vertexNormal.y));
if (normal.x < 0.0) {
normal.x = normal.x / 128.0;
} else {
normal.x = normal.x / 127.0;
}
if (normal.y < 0.0) {
normal.y = normal.y / 128.0;
} else {
normal.y = normal.y / 127.0;
}
vec3 floatNormal = octDecode(normal);
#else
vec3 floatNormal = vec3(float(vertexNormal.x) / 127.0, float(vertexNormal.y) / 127.0, float(vertexNormal.z) / 127.0);
// floatNormal = vec3(0.0, 0.0, 1.0);
#endif
#else
vec3 floatNormal = vertexNormal;
#endif
#endif
#endif
#ifdef WITH_USEOBJECTCOLORS
vec4 floatColor = objectColor;
#else
#ifndef WITH_PICKING
#ifndef WITH_LINES
#ifdef WITH_QUANTIZECOLORS
vec4 floatColor = vec4(float(vertexColor.x) / 255.0, float(vertexColor.y) / 255.0, float(vertexColor.z) / 255.0, float(vertexColor.w) / 255.0);
#else
vec4 floatColor = vertexColor;
#endif
#endif
#endif
#endif
#ifdef WITH_INSTANCING
#ifdef WITH_QUANTIZEVERTICES
vec4 floatVertex = vec4(postProcessingTranslation, 0) + instanceMatrices * vertexQuantizationMatrix * vec4(float(vertexPosition.x), float(vertexPosition.y), float(vertexPosition.z), 1);
#else
vec4 floatVertex = vec4(postProcessingTranslation, 0) + instanceMatrices * vec4(vertexPosition, 1);
#endif
#ifndef WITH_PICKING
#ifndef WITH_LINES
floatNormal = instanceNormalMatrices * floatNormal;
#endif
#endif
#endif
#ifdef WITH_LINEPRIMITIVES
// tfk: todo: line matrix could be same as instanceMatrix?
vec2 aspectVec = vec2(aspect, 1.0);
mat4 viewModel = viewMatrix * matrix;
mat4 projViewModel = projectionMatrix * viewModel;
vec4 currentProjected = projectionMatrix * viewModel * floatVertex;
vec2 currentScreen = currentProjected.xy / currentProjected.w * aspectVec;
#ifdef WITH_QUANTIZEVERTICES
vec4 nextVertexPositionFloat = vertexQuantizationMatrix * vec4(float(nextVertexPosition.x), float(nextVertexPosition.y), float(nextVertexPosition.z), 1);
#else
vec4 nextVertexPositionFloat = vec4(nextVertexPosition, 1);
#endif
vec4 nextProjected = projViewModel * (vec4(postProcessingTranslation, 0) + nextVertexPositionFloat);
vec2 nextScreen = nextProjected.xy / nextProjected.w * aspectVec;
vec2 dir = normalize(nextScreen - currentScreen);
vec2 normal = vec2(-dir.y, dir.x);
vec4 offset = vec4(normal / aspectVec * float(direction) * thickness * currentProjected.w, 0.0, 0.0);
vec4 offset2 = vec4(dir / -2. / aspectVec * thickness * currentProjected.w, 0.0, 0.0);
gl_Position = currentProjected + offset + offset2;
color = inputColor;
#else
gl_Position = projectionMatrix * viewMatrix * floatVertex;
#ifdef WITH_INSTANCING
// Move the vertex off-screen when hidden
bool contained = false;
for (int i = 0; i < int(numContainedInstances); ++i) {
if ((containedInstances[i] == uint(gl_InstanceID))) {
contained = true;
break;
}
}
if (contained == (containedMeansHidden == uint(1))) {
gl_Position = vec4(-10., -10., -10., -10.);
return;
}
#endif
#ifdef WITH_PICKING
#ifdef WITH_INSTANCING
color = instancePickColors;
#else
color = vertexPickColor;
#endif
#else
#ifdef WITH_LINES
// Line rendering color
color = vec4(0.3, 0.3, 0.3, 1);
#else
vec3 viewNormal = normalize(viewNormalMatrix * floatNormal);
// This does not seem to work, I think the "abs" results in the model being dark on 2 sides, and being light on the other 2 sides
// float lambert1 = abs(dot(floatNormal, normalize(lightData.dir)));
float lambert2 = abs(max(dot(-viewNormal, normalize(lightData.dir)), 0.0));
// color = vec4((lambert1 * 0.85 + lambert2 * 0.2 + 0.3) * floatColor.rgb, floatColor.a);
color = vec4((lambert2 * 0.7 + 0.3) * floatColor.rgb, floatColor.a);
// color = floatColor;
#endif
#endif
#endif
worldCoords = floatVertex.xyz;
}
`