/** * Author: Kaj Dijksta */ attribute vec3 position; attribute vec2 uv; uniform mat4 viewProjection; varying vec2 v_textureCoord; void main(void) { v_textureCoord = uv; gl_Position = viewProjection * vec4(position, 1.0); } // #keplerEngine - Split precision highp float; uniform sampler2D positionSampler; uniform sampler2D shadowDepthSampler; uniform sampler2D shadowNoiseSampler; uniform sampler2D ambientOcclusionSampler; uniform float bias; uniform float minVariance; uniform vec3 lightPosition; uniform mat4 lightViewProjection; varying vec2 v_textureCoord; float DecodeFloatRGBA( vec4 rgba ) { return (rgba).x; //return dot( rgba, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0) ); } float poissonPCFmultitap(vec4 projCoords, float shadowDepth, vec2 uv) { const mediump float step = 1.0 - 1.0 / 8.0; const mediump float fScale = 0.025; // 0.025 mediump float n = 0.0; mediump vec3 directions[8]; float vSampleScale = 1.0 / 2048.0; directions[0] = normalize(vec3( 1.0, 1.0, 1.0))*fScale*(n+=step); directions[1] = normalize(vec3(-1.0,-1.0,-1.0))*fScale*(n+=step); directions[2] = normalize(vec3(-1.0,-1.0, 1.0))*fScale*(n+=step); directions[3] = normalize(vec3(-1.0, 1.0,-1.0))*fScale*(n+=step); directions[4] = normalize(vec3(-1.0, 1.0 ,1.0))*fScale*(n+=step); directions[5] = normalize(vec3( 1.0,-1.0,-1.0))*fScale*(n+=step); directions[6] = normalize(vec3( 1.0,-1.0, 1.0))*fScale*(n+=step); directions[7] = normalize(vec3( 1.0, 1.0,-1.0))*fScale*(n+=step); mediump vec3 randomSample = texture2D(shadowNoiseSampler, vec2(64.0, 64.0) * uv.xy / 4.0).xyz * 2.0 - 1.0; float sum = 0.0; // for( int i = 0; i < 4; i++ ) { // vec3 sampler = reflect(directions[0], randomSample) * vSampleScale; float pixelDepth = DecodeFloatRGBA( texture2D(shadowDepthSampler, projCoords.xy ) ) ; // + sampler.xy + sampler.z if( pixelDepth + bias > shadowDepth) { sum += 1.0; } else { sum += 0.5; } // } return sum; } float shadow_sample(sampler2D depthMap, vec2 coord) { return ( texture2D(depthMap, coord.xy).x ); } vec2 DoubleSampleRotated(sampler2D depthMap, vec4 p, vec4 rotMatr, vec4 kernel) { vec4 rotatedOff; rotatedOff = rotMatr.xyzw * kernel.xxww + rotMatr.zwxy * kernel.yyzz; vec4 fetchPos = p.xyxy + rotatedOff;// + rotatedOff vec2 result; result.x = shadow_sample(depthMap, fetchPos.xy); result.y = shadow_sample(depthMap, fetchPos.zw); return result; } float PCF(sampler2D depthMap, vec4 p, vec2 randDirTC, float depth) { vec2 kernelRadius = vec2(4.0); vec4 irreg_kernel_2d[8]; irreg_kernel_2d[0] = vec4(-0.556641,-0.037109,-0.654297, 0.111328); irreg_kernel_2d[1] = vec4(0.173828,0.111328,0.064453, -0.359375); irreg_kernel_2d[2] = vec4(0.001953,0.082031,-0.060547, 0.078125); irreg_kernel_2d[3] = vec4(0.220703,-0.359375,-0.062500, 0.001953); irreg_kernel_2d[4] = vec4(0.242188,0.126953,-0.250000, -0.140625); irreg_kernel_2d[5] = vec4(0.070313,-0.025391,0.148438, 0.082031); irreg_kernel_2d[6] = vec4(-0.078125,0.013672,-0.314453, 0.013672); irreg_kernel_2d[7] = vec4(0.117188,-0.140625,-0.199219, 0.117188); vec2 vInvShadowMapWH = vec2(1.0 / 2048.0); const int kernelSize = 8; mediump float P_Z = depth; // p.z; vec4 p0 = vec4(p.xyz, 1.0); mediump vec2 rotScale = vec2(kernelRadius.y * 2.0); float shadowTest = 0.0; #define KERNEL_STEP_SIZE 2 vec2 rotSample = 2.0 * texture2D(shadowDepthSampler, randDirTC.xy).xy - 1.0; rotSample.xy = normalize(rotSample.xy); rotSample.xy *= (kernelRadius.xy * vInvShadowMapWH.xy); vec4 rot = vec4(rotSample.x, -rotSample.y, rotSample.y, rotSample.x); const int kernelOffset = 0; for(int i=kernelOffset; i 1.0) { return 0.0; } if(projCoords.y < 0.0 || projCoords.y > 1.0) { return 0.0; } //if(projCoords.z < 1.0) { // return 0.0; //} //return ChebyshevUpperBound(moments.xy, shadowDepth); //return poissonPCFmultitap(projCoords, shadowDepth, uv); return PCF( shadowDepthSampler, projCoords, randomSample, shadowDepth ); } void main() { vec3 position = texture2D( positionSampler, v_textureCoord ).xyz; float shadow = calculateShadowOcclusion( position, v_textureCoord ); float ambientOcclusion = texture2D( ambientOcclusionSampler, v_textureCoord ).x; gl_FragColor = vec4(ambientOcclusion, shadow, 0.0, 1.0); }