acdream/src/AcDream.App/Rendering/Shaders/mesh_instanced.vert
Erik 31d3a4678f fix(lighting): port ACME lighting constants replacing guessed values
Replace guessed sun direction (0.5, 0.4, 0.6) with ACME's verified
value (0.5, 0.3, -0.3) from GameScene.cs:238. Replace hardcoded
ambient/diffuse (0.25/0.75) with ACME's ambient intensity 0.45 from
LandscapeEditorSettings.cs:108.

Terrain shaders now match ACME Landscape.vert/frag pattern:
- Vertex shader computes Lambert term with xLightDirection uniform
- Fragment shader applies: color * (clamp(lambert, 0, 1) + xAmbient)

Static object shader matches ACME StaticObject.vert:
- LightingFactor = max(dot(N, -L), 0) + ambient
- Removed separate uDiffuseIntensity (ACME doesn't have one)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:01:28 +02:00

40 lines
1.5 KiB
GLSL

#version 430 core
// Per-vertex attributes
layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoord;
// Per-instance model matrix, split across four vec4 attribute slots.
// A mat4 consumes 4 consecutive attribute locations, so locations 3-6 are
// all occupied by this single logical matrix. The C# side must call
// VertexAttribPointer four times (one per row) and VertexAttribDivisor(loc, 1)
// on each of the four slots.
layout(location = 3) in vec4 aInstanceRow0;
layout(location = 4) in vec4 aInstanceRow1;
layout(location = 5) in vec4 aInstanceRow2;
layout(location = 6) in vec4 aInstanceRow3;
uniform mat4 uViewProjection;
uniform vec3 uLightDirection; // world-space light direction (points FROM sun, matching ACME)
uniform float uAmbientIntensity;
out vec2 vTex;
out vec3 vWorldNormal;
out float vLightingFactor;
void main() {
// Reconstruct the per-instance model matrix from its four row vectors.
mat4 model = mat4(aInstanceRow0, aInstanceRow1, aInstanceRow2, aInstanceRow3);
vec4 worldPos = model * vec4(aPosition, 1.0);
gl_Position = uViewProjection * worldPos;
// Transform normal into world space.
vWorldNormal = normalize(mat3(model) * aNormal);
vTex = aTexCoord;
// Lambert + ambient matching ACME StaticObject.vert:
// LightingFactor = max(dot(Normal, -uLightDirection), 0.0) + uAmbientIntensity;
vLightingFactor = max(dot(vWorldNormal, -uLightDirection), 0.0) + uAmbientIntensity;
}