NeomerArcana

10-01-2017, 09:00 PM

I've making a top-down scene where I want a heightmap to cast shadows on itself.

Basically; it's a full screen quad. Here's my heightmap:

https://i.stack.imgur.com/fIViN.png

Combined with a grass texture and I get:

https://i.stack.imgur.com/LBdzx.jpg

The actual shader is here:

#version 330

precision highp float;

layout(location=0) out vec4 frag_colour;

varying vec2 texelCoords;

uniform sampler2D uTexture;

uniform sampler2D uTextureHeightmap;

uniform float uSunDistance = -10000000.0;

uniform float uSunInclination - 0.15;

uniform float uSunAzimuth = 5.148;

uniform float uQuality = 1.0;

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;

float minStepSize = 1.0f / d;

vec3 sunPosition = vec3(textureD.x/2.0f,textureD.y/2.0f,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 samples = 100;//d*uQuality;

float maxDistance = (1.0f - height) * length(direction.xy) / abs(direction.z);

float stepSize = max(minStepSize, maxDistance / samples);

float shadow = 0.3f;

vec3 startPoint = vec3(texelCoords, height);

for(float sampleDistance = stepSize; sampleDistance <= maxDistance; sampleDistance += stepSize)

{

vec3 newPoint = startPoint + direction * sampleDistance;

vec4 h = texture(uTextureHeightmap,newPoint.xy);

float base = h.r;

float middle = h.g;

float top = h.b;

if(newPoint.z < base)

{

c *= shadow;

break;

}

if(newPoint.z >= middle && newPoint.z <= top)

{

c *= shadow;

break;

}

}

frag_colour = vec4(c.rgb,1.0);

//frag_colour = vec4(minStepSize,minStepSize,minStepSize,1.0);

}

I cannot figure out where the striation pattern is coming from. I thought it might be the "angle" of the sun, but even if I set it to just slightly off "directly above" is still has that pattern.

You can sort of ignore anything over the first channel in the heightmap; I'm using and checking multiple channels to allow overhangs and stuff. Even with just a single channel it still has the same result.

I'm sure it's not the step size, I've attempted to purposefully set this to be extremely low values.

Any help would be massively appreciated.

Basically; it's a full screen quad. Here's my heightmap:

https://i.stack.imgur.com/fIViN.png

Combined with a grass texture and I get:

https://i.stack.imgur.com/LBdzx.jpg

The actual shader is here:

#version 330

precision highp float;

layout(location=0) out vec4 frag_colour;

varying vec2 texelCoords;

uniform sampler2D uTexture;

uniform sampler2D uTextureHeightmap;

uniform float uSunDistance = -10000000.0;

uniform float uSunInclination - 0.15;

uniform float uSunAzimuth = 5.148;

uniform float uQuality = 1.0;

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;

float minStepSize = 1.0f / d;

vec3 sunPosition = vec3(textureD.x/2.0f,textureD.y/2.0f,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 samples = 100;//d*uQuality;

float maxDistance = (1.0f - height) * length(direction.xy) / abs(direction.z);

float stepSize = max(minStepSize, maxDistance / samples);

float shadow = 0.3f;

vec3 startPoint = vec3(texelCoords, height);

for(float sampleDistance = stepSize; sampleDistance <= maxDistance; sampleDistance += stepSize)

{

vec3 newPoint = startPoint + direction * sampleDistance;

vec4 h = texture(uTextureHeightmap,newPoint.xy);

float base = h.r;

float middle = h.g;

float top = h.b;

if(newPoint.z < base)

{

c *= shadow;

break;

}

if(newPoint.z >= middle && newPoint.z <= top)

{

c *= shadow;

break;

}

}

frag_colour = vec4(c.rgb,1.0);

//frag_colour = vec4(minStepSize,minStepSize,minStepSize,1.0);

}

I cannot figure out where the striation pattern is coming from. I thought it might be the "angle" of the sun, but even if I set it to just slightly off "directly above" is still has that pattern.

You can sort of ignore anything over the first channel in the heightmap; I'm using and checking multiple channels to allow overhangs and stuff. Even with just a single channel it still has the same result.

I'm sure it's not the step size, I've attempted to purposefully set this to be extremely low values.

Any help would be massively appreciated.