#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);
}