Fixed shadow plopping effects and reeanbled vogel disk sampling

This commit is contained in:
Robert Beckebans 2022-04-02 11:57:33 +02:00
parent 51db69a19f
commit 0d9d13d6f0
3 changed files with 43 additions and 20 deletions

View file

@ -40,9 +40,11 @@ static const int ENVPROBE_CAPTURE_SIZE = 256;
static const int RADIANCE_OCTAHEDRON_SIZE = 512;
static const int IRRADIANCE_OCTAHEDRON_SIZE = 30 + 2;
// RB: shadow resolutions used in 1.3
//static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 };
// if we use higher resolutions than this than the shadow casting lights don't fit into the 16384^2 atlas anymore
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 1024, 512, 512, 256, 128 };
//static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 1024, 1024, 1024, 1024, 1024 };
class Framebuffer

View file

@ -1510,7 +1510,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
float screenCorrectionParm[4];
screenCorrectionParm[0] = 1.0f / ( JITTER_SIZE * shadowMapSamples ) ;
screenCorrectionParm[1] = 1.0f / JITTER_SIZE;
screenCorrectionParm[2] = 1.0f / vLight->imageSize.x; // atlas sample scale
screenCorrectionParm[2] = 1.0f / r_shadowMapAtlasSize.GetInteger(); // atlas sample scale
screenCorrectionParm[3] = vLight->parallel ? r_shadowMapSunDepthBiasScale.GetFloat() : r_shadowMapRegularDepthBiasScale.GetFloat();
SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor
@ -3885,7 +3885,7 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
int shadowIndex = 0;
idList<idVec2i> inputSizes;
idStrList inputNames;
//idStrList inputNames;
for( const viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next )
{
@ -3935,16 +3935,17 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
for( ; side < sideStop ; side++ )
{
inputSizes.Append( idVec2i( shadowMapResolutions[ vLight->shadowLOD ], shadowMapResolutions[ vLight->shadowLOD ] ) );
inputNames.Append( lightShader->GetName() );
//inputNames.Append( lightShader->GetName() );
shadowIndex++;
}
}
idList<idVec2i> outputPositions;
idVec2i totalSize;
idList<int> outputSizes;
//idVec2i totalSize;
#if 1
#if 0
RectAllocatorBinPack2D( inputSizes, inputNames, outputPositions, totalSize, r_shadowMapAtlasSize.GetInteger() );
@ -3954,6 +3955,7 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
// RB: we don't use RectAllocatorQuadTree here because we don't want to rebuild the quad tree every frame
outputPositions.SetNum( inputSizes.Num() );
outputSizes.SetNum( inputSizes.Num() );
idList<int> sizeRemap;
sizeRemap.SetNum( inputSizes.Num() );
@ -3977,6 +3979,7 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
idVec2i size = inputSizes[ shadowIndex ];
int area = Max( size.x, size.y );
//int area = 1024;
Tile tile;
bool result = tileMap.GetTile( area, tile );
@ -3984,18 +3987,26 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
if( !result )
{
outputPositions[ shadowIndex ].Set( -1, -1 );
outputSizes[ shadowIndex ] = area;
}
else
{
int imageSize = tile.size * r_shadowMapAtlasSize.GetInteger();
outputSizes[ shadowIndex ] = imageSize;
// convert from [-1..-1] -> [0..1] and flip y
idVec2 uvPos;
uvPos.x = tile.position.x * 0.5f + 0.5f;
uvPos.y = 1.0f - ( tile.position.y * 0.5f + 0.5f );
uvPos.y = tile.position.y * 0.5f + 0.5f;
idVec2i iPos;
iPos.x = uvPos.x * r_shadowMapAtlasSize.GetInteger();
iPos.y = uvPos.y * r_shadowMapAtlasSize.GetInteger();
// RB: this is really odd but necessary
iPos.x -= imageSize * 0.5f;
iPos.y -= imageSize * 0.5f;
outputPositions[ shadowIndex ].x = iPos.x;
outputPositions[ shadowIndex ].y = iPos.y;
}
@ -4060,8 +4071,11 @@ void idRenderBackend::ShadowAtlasPass( const viewDef_t* _viewDef )
sideStop = 0;
}
vLight->imageSize.x = shadowMapResolutions[ vLight->shadowLOD ];
vLight->imageSize.y = shadowMapResolutions[ vLight->shadowLOD ];
//vLight->imageSize.x = shadowMapResolutions[ vLight->shadowLOD ];
//vLight->imageSize.y = shadowMapResolutions[ vLight->shadowLOD ];
vLight->imageSize.x = outputSizes[ shadowIndex ];
vLight->imageSize.y = outputSizes[ shadowIndex ];
bool imageFitsIntoAtlas = true;

View file

@ -226,10 +226,11 @@ void main( PS_IN fragment, out PS_OUT result )
shadowTexcoord.xyz /= shadowTexcoord.w;
shadowTexcoord.z = shadowTexcoord.z * rpScreenCorrectionFactor.w;
// receiver / occluder terminology like in ESM
float receiver = shadowTexcoord.z * rpScreenCorrectionFactor.w;
//shadowTexcoord.z = shadowTexcoord.z * 0.999991;
//shadowTexcoord.z = shadowTexcoord.z - bias;
shadowTexcoord.w = float( shadowIndex );
//shadowTexcoord.w = float( shadowIndex );
// multiple taps
@ -306,7 +307,7 @@ void main( PS_IN fragment, out PS_OUT result )
shadow *= stepSize;
#elif 0
#elif 1
#if 0
@ -331,7 +332,7 @@ void main( PS_IN fragment, out PS_OUT result )
float shadow = 0.0;
// RB: casting a float to int and using it as index can really kill the performance ...
float numSamples = 6.0;
float numSamples = 12.0;
float stepSize = 1.0 / numSamples;
float random = BlueNoise( fragment.position.xy, 1.0 );
@ -344,16 +345,19 @@ void main( PS_IN fragment, out PS_OUT result )
rot.y = sin( random );
float shadowTexelSize = rpScreenCorrectionFactor.z * rpJitterTexScale.x;
for( int i = 0; i < 6; i++ )
for( int si = 0; si < 12; si++ )
{
float2 jitter = poissonDisk[i];
float2 jitter = poissonDisk[si];
float2 jitterRotated;
jitterRotated.x = jitter.x * rot.x - jitter.y * rot.y;
jitterRotated.y = jitter.x * rot.y + jitter.y * rot.x;
float4 shadowTexcoordJittered = float4( shadowTexcoord.xy + jitterRotated * shadowTexelSize, shadowTexcoord.z, shadowTexcoord.w );
// [0 .. 1] -> rectangle in atlas transform
float2 shadowTexcoordAtlas = shadowTexcoord.xy * rpJitterTexScale.y + rpShadowAtlasOffsets[ shadowIndex ].xy;
shadow += idtex2Dproj( s_Shadow, t_ShadowMapArray, shadowTexcoordJittered.xywz );
float2 shadowTexcoordJittered = shadowTexcoordAtlas.xy + jitterRotated * shadowTexelSize;
shadow += t_ShadowAtlas.SampleCmpLevelZero( s_Shadow, shadowTexcoordJittered.xy, receiver );
}
shadow *= stepSize;
@ -379,9 +383,12 @@ void main( PS_IN fragment, out PS_OUT result )
{
float2 jitter = VogelDiskSample( si, numSamples, vogelPhi );
float4 shadowTexcoordJittered = float4( shadowTexcoord.xy + jitter * shadowTexelSize, shadowTexcoord.z, shadowTexcoord.w );
// [0 .. 1] -> rectangle in atlas transform
float2 shadowTexcoordAtlas = shadowTexcoord.xy * rpJitterTexScale.y + rpShadowAtlasOffsets[ shadowIndex ].xy;
shadow += t_ShadowMapArray.SampleCmpLevelZero( s_Shadow, shadowTexcoordJittered.xyw, shadowTexcoordJittered.z );
float2 shadowTexcoordJittered = shadowTexcoordAtlas + jitter * shadowTexelSize;
shadow += t_ShadowAtlas.SampleCmpLevelZero( s_Shadow, shadowTexcoordJittered.xy, receiver );
}
shadow *= stepSize;
@ -395,7 +402,7 @@ void main( PS_IN fragment, out PS_OUT result )
// [0 .. 1] -> rectangle in atlas transform
uvShadow = uvShadow * rpJitterTexScale.y + rpShadowAtlasOffsets[ shadowIndex ].xy;
float shadow = t_ShadowAtlas.SampleCmpLevelZero( s_Shadow, uvShadow.xy, shadowTexcoord.z );
float shadow = t_ShadowAtlas.SampleCmpLevelZero( s_Shadow, uvShadow.xy, receiver );
#if 0
if( shadowIndex == 0 )