//////////////////////////////////////////////// // // ambient obscurance // //////////////////////////////////////////////// aotapoffsets = [ "-0.933103, 0.025116" "-0.432784, -0.989868" "0.432416, -0.413800" "-0.117770, 0.970336" "0.837276, 0.531114" "-0.184912, 0.200232" "-0.955748, 0.815118" "0.946166, -0.998596" "-0.897519, -0.581102" "0.979248, -0.046602" "-0.155736, -0.488204" "0.460310, 0.982178" ] ambientobscurancevariantshader = [ lineardepth = (>= (strstr $arg2 "l") 0) packeddepth = (>= (strstr $arg2 "p") 0) derivnormal = (>= (strstr $arg2 "d") 0) maxaotaps = $arg3 shader 0 $arg1 [ in vec4 vvertex; @(screentexcoord 0) @(screentexcoord 1) out vec2 texcoord0, texcoord1; void main(void) { gl_Position = vvertex; texcoord0 = vtexcoord0; texcoord1 = vtexcoord1; } ] [ @(gfetchdefs tex0 (&& $msaasamples [! $lineardepth]) gdepthfetch) @(gfetchdefs tex1 $msaasamples gnormfetch) @(gdepthunpackparams) uniform sampler2D tex2; uniform vec3 tapparams; uniform vec2 contrastparams; uniform vec4 offsetscale; uniform float prefilterdepth; @(? (! $derivnormal) [ uniform mat3 normalmatrix; ]) @(? $lineardepth [ #define depthtc gl_FragCoord.xy ] [ #define depthtc texcoord0 ]) uniform vec3 gdepthpackparams; in vec2 texcoord0, texcoord1; layout(location = 0) out vec4 fragcolor; void main(void) { @(if (&& $derivnormal [= $aodepthformat 1]) [result [ @(gdepthunpack depth [gnormfetch(tex1, texcoord0)] [ vec2 tapscale = tapparams.xy/depth; ] [ float w = depth*gdepthscale.y + gdepthscale.z; depth = gdepthscale.x/w; vec2 tapscale = tapparams.xy*w; ]) ]] [result [ @(gdepthunpack depth [gdepthfetch(tex0, depthtc)] [ vec2 tapscale = tapparams.xy/depth; ] [ float w = depth*gdepthscale.y + gdepthscale.z; depth = gdepthscale.x/w; vec2 tapscale = tapparams.xy*w; ] $lineardepth (? $lineardepth (! $aodepthformat) (= $gdepthformat 1)) packdepth) ]]) vec2 dpos = depthtc*offsetscale.xy + offsetscale.zw, pos = depth*dpos; @(if $derivnormal [result [ vec2 ddepth = vec2(dFdx(depth), dFdy(depth)); ddepth *= step(abs(ddepth), vec2(4.0)); vec3 normal; normal.xy = (depth+ddepth.yx)*offsetscale.yx; normal.z = normal.x*normal.y; normal.xy *= -ddepth; normal.z -= dot(dpos, normal.xy); normal = normalize(normal); ]] [result [ vec3 normal = gnormfetch(tex1, texcoord0).rgb*2.0 - 1.0; float normscale = inversesqrt(dot(normal, normal)); normal *= normscale > 0.75 ? normscale : 0.0; normal = normalmatrix * normal; ]]) vec2 noise = texture(tex2, texcoord1).rg*2.0-1.0; float obscure = 0.0; @(loopconcat i $maxaotaps [result [ vec2 offset@[i] = reflect(vec2(@(at $aotapoffsets $i)), noise); offset@[i] = depthtc + tapscale * offset@[i]; @(gdepthunpack [depth@[i]] [gdepthfetch(tex0, offset@[i])] [] [] $lineardepth (&& $lineardepth (! $aodepthformat))) vec3 v@[i] = vec3(depth@[i]*(offset@[i]*offsetscale.xy + offsetscale.zw) - pos, depth@[i] - depth); float dist2@[i] = dot(v@[i], v@[i]); obscure += step(dist2@[i], tapparams.z) * max(0.0, dot(v@[i], normal) + depth*1.0e-2) / (dist2@[i] + 1.0e-5); ]]) obscure = pow(clamp(1.0 - contrastparams.x*obscure, 0.0, 1.0), contrastparams.y); @(if $derivnormal [result [ vec2 weights = step(abs(ddepth), vec2(prefilterdepth)) * (2.0*fract((gl_FragCoord.xy - 0.5)*0.5) - 0.5); ]] [result [ vec2 weights = step(fwidth(depth), prefilterdepth) * (2.0*fract((gl_FragCoord.xy - 0.5)*0.5) - 0.5); ]]) obscure -= dFdx(obscure) * weights.x; obscure -= dFdy(obscure) * weights.y; @(if $packeddepth [ if $aodepthformat [result [ fragcolor.rg = vec2(obscure, depth); ]] [result [ @(if (&& (! $lineardepth) (!= $gdepthformat 1)) [gpackdepth packdepth depth]) fragcolor = vec4(packdepth, obscure); ]] ] [result [ fragcolor = vec4(obscure, 0.0, 0.0, 1.0); ]]) } ] ] ambientobscuranceshader = [ ambientobscurancevariantshader (format "ambientobscurance%1%2" $arg1 $arg2) $arg1 $arg2 ] shader 0 "linearizedepth" [ in vec4 vvertex; @(screentexcoord 0) out vec2 texcoord0; void main(void) { gl_Position = vvertex; texcoord0 = vtexcoord0; } ] [ @(gfetchdefs tex0 $msaasamples) uniform vec3 gdepthpackparams; in vec2 texcoord0; layout(location = 0) out vec4 fragcolor; void main(void) { @(if (! $aodepthformat) [ if (= $gdepthformat 1) [result [ fragcolor = gfetch(tex0, texcoord0); ]] [result [ @(gdepthunpack depth [gfetch(tex0, texcoord0)]) @(gpackdepth packdepth depth) fragcolor = vec4(packdepth, 1.0); ]] ] [result [ @(gdepthunpack depth [gfetch(tex0, texcoord0)]) fragcolor.r = depth; ]]) } ] bilateralvariantshader = [ linear = (>= (strstr $arg2 "l") 0) packed = (>= (strstr $arg2 "p") 0) upscaled = (>= (strstr $arg2 "u") 0) numtaps = $arg3 reduced = $arg4 filterdir = $arg5 shader 0 $arg1 [ in vec4 vvertex; @(if $reduced [result [ @(screentexcoord 0) out vec2 texcoord0; ]]) @(if $upscaled [result [ @(screentexcoord 1) out vec2 texcoord1; ]]) void main(void) { gl_Position = vvertex; @(? $reduced [texcoord0 = vtexcoord0;]) @(? $upscaled [texcoord1 = vtexcoord1;]) } ] [ @(gfetchdefs tex1 (&& $msaasamples [! $linear])) uniform sampler2DRect tex0; uniform vec2 bilateralparams; uniform vec3 gdepthpackparams; @(? $reduced [in vec2 texcoord0;]) @(? $upscaled [in vec2 texcoord1;]) layout(location = 0) out vec4 fragcolor; void main(void) { #define tc @(? $upscaled [texcoord1] [gl_FragCoord.xy]) #define depthtc @(? $reduced [texcoord0] [gl_FragCoord.xy]) #define tapvec(type, i) @(? (=s $filterdir "x") [type(i, 0.0)] [type(0.0, i)]) #define texval(i) textureRect(tex0, tc + tapvec(vec2, i)) #define texvaloffset(i) textureRectOffset(tex0, tc, tapvec(ivec2, i)) #define depthval(i) gfetch(tex1, depthtc + tapvec(vec2, i)) #define depthvaloffset(i) gfetchoffset(tex1, depthtc, tapvec(ivec2, i)) @(cond [$packed] [ if $aodepthformat [result [ vec2 vals = textureRect(tex0, tc).rg; #define color vals.x @(if $upscaled [gdepthunpack depth [gfetch(tex1, depthtc)]] [result [ #define depth vals.y ]]) ]] [result [ vec4 vals = textureRect(tex0, tc); #define color vals.a @(if $upscaled [gdepthunpack depth [gfetch(tex1, depthtc)]] [result [ float depth = dot(vals.rgb, gdepthunpackparams); ]]) ]] ] [$linear] [result [ float color = gfetch(tex0, tc).r; @(if $aodepthformat [result [ float depth = gfetch(tex1, depthtc).r; ]] [result [ float depth = dot(gfetch(tex1, depthtc).rgb, gdepthunpackparams); ]]) ]] [result [ float color = textureRect(tex0, tc).r; @(gdepthunpack depth [gfetch(tex1, depthtc)]) ]]) float weights = 1.0; @(loopconcat i (* 2 $numtaps) [ curtap = (- $i $numtaps) if (>= $curtap 0) [curtap = (+ $curtap 1)] curtapoffset = (* $curtap 2) curdepthoffset = (<< $curtapoffset $reduced) curtexval = [texval@(? (<= $mintexrectoffset $curtapoffset $maxtexrectoffset) "offset")(@(+f $curtapoffset))] curdepthval = [depthval@(? (<= $mintexrectoffset $curdepthoffset $maxtexrectoffset) "offset")(@(+f $curdepthoffset))] result [ @(cond [$packed] [ if $aodepthformat [result [ vec2 vals@[i] = @[curtexval].rg; #define color@[i] vals@[i].x #define depth@[i] vals@[i].y ]] [result [ vec4 vals@[i] = @[curtexval]; #define color@[i] vals@[i].a float depth@[i] = dot(vals@[i].rgb, gdepthunpackparams); ]] ] [$linear] [ result [ float color@[i] = @[curtexval].r; @(if $aodepthformat [result [ float depth@[i] = @[curdepthval].r; ]] [result [ float depth@[i] = dot(@[curdepthval].rgb, gdepthunpackparams); ]]) ] ] [ result [ float color@[i] = @[curtexval].r; @(gdepthunpack [depth@[i]] $curdepthval) ] ]) depth@[i] -= depth; float weight@[i] = exp2(@(-f 0 (* $curtap $curtap))*bilateralparams.x - depth@[i]*depth@[i]*bilateralparams.y); weights += weight@[i]; color += weight@[i] * color@[i]; ] ]) @(if (&& (=s $filterdir "x") $packed) [ if $aodepthformat [result [ fragcolor.rg = vec2(color / weights, depth); ]] [result [ @(if $upscaled [gpackdepth packdepth depth] [result [ #define packdepth vals.rgb ]]) fragcolor = vec4(packdepth, color / weights); ]] ] [result [ fragcolor = vec4(color / weights, 0.0, 0.0, 1.0); ]]) } ] ] bilateralshader = [ bilateralvariantshader (format "bilateralx%1%2" $arg1 $arg2) $arg1 $arg2 $arg3 x bilateralvariantshader (format "bilateraly%1%2" $arg1 $arg2) $arg1 $arg2 $arg3 y ]