I'm casting shadows across a screenspace texture based on the values in another texture.
My "depth" texture, it's not really depth, just colour values that are sampled for heights, looks like this:
We can say that the red channel is my heightmap.
I draw this alongside a grass texture on a fullscreen quad with the following frag shader:
#version 400
layout(location=0) out vec4 frag_colour;
in vec2 texelCoords;
uniform sampler2D uTexture;
uniform sampler2D uTextureHeightmap;
uniform float uSunDistance = -10000000.0;
uniform float uSunInclination;
uniform float uSunAzimuth;
uniform float uQuality;
void main()
{
vec4 c = texture(uTexture,texelCoords);
vec2 textureD = textureSize(uTexture,0);
float d = max(textureD.x,textureD.y);
float aspectCorrection = textureD.x / textureD.y;
vec3 sunPosition = vec3(textureD.x/2,textureD.y/2,0) + vec3( uSunDistance*sin(uSunInclination)*cos(uSunAzimuth),
uSunDistance*sin(uSunInclination)*sin(uSunAzimuth),
uSunDistance*cos(uSunInclination) );
vec4 heights = texture(uTextureHeightmap, texelCoords);
float height = max(max(heights.r,heights.g),heights.b);
vec3 direction = normalize(vec3(texelCoords,height) - sunPosition);
direction.y *= aspectCorrection;
float sampleDistance = 0;
float samples = d*uQuality;
float stepSize = 1.0 / ((samples/d) * d);
for(int i = 0; i < samples; i++)
{
sampleDistance += stepSize;
vec3 newPoint = vec3(texelCoords,height) + direction * sampleDistance;
if(newPoint.z > 1.0)
break;
vec4 h = texture(uTextureHeightmap,newPoint.xy);
float base = h.r;
float middle = h.g;
float top = h.b;
if(newPoint.z < base)
{
c *= 0.5;
break;
}
if(newPoint.z >= middle && newPoint.z <= top)
{
c *= 0.5;
break;
}
}
frag_colour = c;
}
A sample of the output is:
The striation is not wanted. I can use this same method with sharper "edges" instead of smooth contours, and everything looks great. It's the gradients like this that cause problems.