Godot Shader 2DTerrainShadow

35 Views Asked by At

Stumbled across a nice video on youtube with an approximation for shadows on a 2d terrain. I tried to implement it in Godot Visual Shaders (with ExpressionNode) but can't seem to get it to work. I am kind of struggling with conversions between UV/Vertex coordinates and the actual 3D world points.

float currentHeight = texture(heightMap, UV).r;
vec3 pixelWorldPosition = (vec4(VERTEX, 1.0) * VIEW_MATRIX).xyz;
vec3 currentPosition = vec3(pixelWorldPosition.x, currentHeight, pixelWorldPosition.z);
vec3 direction = normalize(sunPosition - currentPosition);

float isInShadow = 0.0;
for (int i=0; i<50; i++) {
    vec3 checkPosition = currentPosition + (direction * float(i));
    mat4 WORLD_TO_CLIP_MATRIX = PROJECTION_MATRIX * INV_VIEW_MATRIX;
    vec4 pixelClipPos = WORLD_TO_CLIP_MATRIX * vec4(checkPosition, 1.0);
    vec2 checkPositionUV = (pixelClipPos.xyz / pixelClipPos.w).xy * 0.5 + vec2(0.5, 0.5);
    
    float checkHeight = texture(heightMap, checkPositionUV).r;
    if (checkHeight > currentHeight) {
       isInShadow = 1.0;
       break;
    } else if (checkPosition.y > 1.0) {
       break;
   }
}

shadedValue = mix(unshadedValue, unshadedValue * shadowIntensity, isInShadow);

What Iam thinking is converting the actual pixelPosition to a worldPosition to calculate the sunDirection stuff and then convert the checkPosition back to pixelPositions to lookup the height on the texture.

enter image description here

Looks weird and not correct. The yellow circle is the sun worldPosition. Terrain is shaded by height from light green to darker green. The extra dark green blobs are "trees". Thank you for any help in advance :)

0

There are 0 best solutions below