#version 430 layout (binding = 0) uniform sampler3D noiseSamp; layout (binding = 1) uniform sampler2D textureSamp; layout (binding = 2) uniform sampler2D bumpSamp; layout (binding = 3) uniform sampler2D normalSamp; layout (binding = 4) uniform sampler2D depthSamp; layout (binding = 5) uniform sampler2D depthSamp2; uniform float height; uniform vec3 viewPos; uniform int steps; uniform int fineSteps; uniform float heightScale; uniform bool kajetan; in vec3 varPositionG; in vec4 varShadowPositionG; in vec2 varTextureG; out vec4 color; const vec3 light = vec3(-0.746, -0.373, -0.224); const float minVariance = 1.84582e-7; const float cutoff = 0.9999; float chebyshevUpperBound(vec2 moments, float t) { float variance = moments.y - (moments.x * moments.x); variance = max(variance, minVariance); float d = t - moments.x; float pMax = variance / (variance + d * d); return max(pMax, float(t < moments.x)); } float linstep(float from, float to, float v) { return clamp((v - from) / (to - from), 0.0, 1.0); } float reduceLightBleeding(float light, float Amount) { return linstep(Amount, 1.0, light); } float getShadow(vec2 varTex, float distanceToLight) { vec2 Moments = texture(depthSamp, varTex).xy; return reduceLightBleeding(chebyshevUpperBound(Moments, distanceToLight), cutoff); } void main(void) { vec2 tex = varTextureG + vec2(0.0, height); vec2 eye = -normalize(viewPos - varPositionG).xy * heightScale; // kajetans variant if(kajetan) { eye *= texture(bumpSamp, tex).x; tex += eye; } else { // lecture float h = 1.0; float prev_hits = 0; float hit_h = 0; vec2 mTex = tex; float step = 1.0 / steps; vec2 stepEye = eye / steps; for (int it = 0; it < steps; it++) { h -= step; mTex += stepEye; float h_tex = texture(bumpSamp, mTex).x; float is_first_hit = float((h_tex - h - prev_hits) > 0.0); hit_h += is_first_hit * h; prev_hits += is_first_hit; } hit_h = max(0.0, hit_h - step); h = hit_h; prev_hits = 0; mTex = tex + stepEye * hit_h; hit_h = 0; step /= fineSteps; stepEye = eye / fineSteps; for (int it = 0; it < fineSteps; it++) { h -= step; mTex += stepEye; float h_tex = texture(bumpSamp, mTex).x; float is_first_hit = float((h_tex - h - prev_hits) > 0.0); hit_h += is_first_hit * h; prev_hits += is_first_hit; } tex += eye * hit_h; } vec3 normal = texture(normalSamp, tex).xyz; normal = normalize(normal * 2.0 - 1.0); float l = max(dot(-light, normal), 0.0) * 0.7 + 0.3; color = vec4(texture(textureSamp, tex).xyz * l, 1.0); vec3 pos = varShadowPositionG.xyz / varShadowPositionG.w; float shadow = getShadow(pos.xy, pos.z); //float shadow = float(texture(depthSamp2, pos.xy).r + 0.00001 > pos.z); shadow = shadow * 0.6 + 0.4; color *= shadow; }