bgfx/examples/39-assao/cs_assao_prepare_depth_mip.sc
2018-12-14 22:09:37 +01:00

104 lines
4.3 KiB
Python

/*
* Copyright 2018 Attila Kocsis. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "bgfx_compute.sh"
#include "uniforms.sh"
IMAGE2D_RO(s_viewspaceDepthSource0, r16f, 0);
IMAGE2D_RO(s_viewspaceDepthSource1, r16f, 1);
IMAGE2D_RO(s_viewspaceDepthSource2, r16f, 2);
IMAGE2D_RO(s_viewspaceDepthSource3, r16f, 3);
IMAGE2D_WR(s_target0, r16f, 4);
IMAGE2D_WR(s_target1, r16f, 5);
IMAGE2D_WR(s_target2, r16f, 6);
IMAGE2D_WR(s_target3, r16f, 7);
// calculate effect radius and fit our screen sampling pattern inside it
void CalculateRadiusParameters( const float pixCenterLength, const vec2 pixelDirRBViewspaceSizeAtCenterZ, out float pixLookupRadiusMod, out float effectRadius, out float falloffCalcMulSq )
{
effectRadius = u_effectRadius;
// leaving this out for performance reasons: use something similar if radius needs to scale based on distance
//effectRadius *= pow( pixCenterLength, u_radiusDistanceScalingFunctionPow);
// when too close, on-screen sampling disk will grow beyond screen size; limit this to avoid closeup temporal artifacts
const float tooCloseLimitMod = saturate( pixCenterLength * u_effectSamplingRadiusNearLimitRec ) * 0.8 + 0.2;
effectRadius *= tooCloseLimitMod;
// 0.85 is to reduce the radius to allow for more samples on a slope to still stay within influence
pixLookupRadiusMod = (0.85 * effectRadius) / pixelDirRBViewspaceSizeAtCenterZ.x;
// used to calculate falloff (both for AO samples and per-sample weights)
falloffCalcMulSq= -1.0f / (effectRadius*effectRadius);
}
NUM_THREADS(8, 8, 1)
void main()
{
uvec2 dtID = uvec2(gl_GlobalInvocationID.xy);
uvec2 dim = uvec2(u_rect.zw);
if (all(lessThan(dtID.xy, dim) ) )
{
ivec2 baseCoords = ivec2(dtID.xy) * 2;
vec4 depthsArr[4];
float depthsOutArr[4];
// how to Gather a specific mip level?
depthsArr[0].x = imageLoad(s_viewspaceDepthSource0, baseCoords + ivec2( 0, 0 )).x ;
depthsArr[0].y = imageLoad(s_viewspaceDepthSource0, baseCoords + ivec2( 1, 0 )).x ;
depthsArr[0].z = imageLoad(s_viewspaceDepthSource0, baseCoords + ivec2( 0, 1 )).x ;
depthsArr[0].w = imageLoad(s_viewspaceDepthSource0, baseCoords + ivec2( 1, 1 )).x ;
depthsArr[1].x = imageLoad(s_viewspaceDepthSource1, baseCoords + ivec2( 0, 0 )).x;
depthsArr[1].y = imageLoad(s_viewspaceDepthSource1, baseCoords + ivec2( 1, 0 )).x;
depthsArr[1].z = imageLoad(s_viewspaceDepthSource1, baseCoords + ivec2( 0, 1 )).x;
depthsArr[1].w = imageLoad(s_viewspaceDepthSource1, baseCoords + ivec2( 1, 1 )).x;
depthsArr[2].x = imageLoad(s_viewspaceDepthSource2, baseCoords + ivec2( 0, 0 )).x;
depthsArr[2].y = imageLoad(s_viewspaceDepthSource2, baseCoords + ivec2( 1, 0 )).x;
depthsArr[2].z = imageLoad(s_viewspaceDepthSource2, baseCoords + ivec2( 0, 1 )).x;
depthsArr[2].w = imageLoad(s_viewspaceDepthSource2, baseCoords + ivec2( 1, 1 )).x;
depthsArr[3].x = imageLoad(s_viewspaceDepthSource3, baseCoords + ivec2( 0, 0 )).x;
depthsArr[3].y = imageLoad(s_viewspaceDepthSource3, baseCoords + ivec2( 1, 0 )).x;
depthsArr[3].z = imageLoad(s_viewspaceDepthSource3, baseCoords + ivec2( 0, 1 )).x;
depthsArr[3].w = imageLoad(s_viewspaceDepthSource3, baseCoords + ivec2( 1, 1 )).x;
const uvec2 SVPosui = uvec2( dtID.xy );
const uint pseudoRandomA = (SVPosui.x ) + 2 * (SVPosui.y );
float dummyUnused1;
float dummyUnused2;
float falloffCalcMulSq, falloffCalcAdd;
UNROLL
for( int i = 0; i < 4; i++ )
{
vec4 depths = depthsArr[i];
float closest = min( min( depths.x, depths.y ), min( depths.z, depths.w ) );
CalculateRadiusParameters( abs( closest ), vec2(1.0,1.0), dummyUnused1, dummyUnused2, falloffCalcMulSq );
vec4 dists = depths - closest.xxxx;
vec4 weights = saturate( dists * dists * falloffCalcMulSq + 1.0 );
float smartAvg = dot( weights, depths ) / dot( weights, vec4( 1.0, 1.0, 1.0, 1.0 ) );
const uint pseudoRandomIndex = ( pseudoRandomA + i ) % 4;
//depthsOutArr[i] = closest;
//depthsOutArr[i] = depths[ pseudoRandomIndex ];
depthsOutArr[i] = smartAvg;
}
imageStore(s_target0, ivec2(dtID.xy), depthsOutArr[0].xxxx);
imageStore(s_target1, ivec2(dtID.xy), depthsOutArr[1].xxxx);
imageStore(s_target2, ivec2(dtID.xy), depthsOutArr[2].xxxx);
imageStore(s_target3, ivec2(dtID.xy), depthsOutArr[3].xxxx);
}
}