Skip to content

Commit

Permalink
- Fix shadow rendering (fix light camera setting mistake)
Browse files Browse the repository at this point in the history
- Add depth and shadow texture coordinates checking
- Improve performance by selecting front faces for forward pass and back faces for shadow pass
  • Loading branch information
NEDJIMAbelgacem authored and nyalldawson committed Jan 31, 2022
1 parent 9ba642f commit 15d48a1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
22 changes: 18 additions & 4 deletions src/3d/qgsshadowrenderingframegraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,17 @@ Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructForwardRende
mForwardClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );
mForwardClearBuffers->setClearDepthValue( 1.0f );

mFrustumCulling = new Qt3DRender::QFrustumCulling( mForwardClearBuffers );
Qt3DRender::QRenderStateSet *forwaredRenderStateSet = new Qt3DRender::QRenderStateSet( mForwardClearBuffers );

Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
forwaredRenderStateSet->addRenderState( depthTest );

Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
cullFace->setMode( Qt3DRender::QCullFace::CullingMode::Back );
forwaredRenderStateSet->addRenderState( cullFace );

mFrustumCulling = new Qt3DRender::QFrustumCulling( forwaredRenderStateSet );

return mMainCameraSelector;
}
Expand Down Expand Up @@ -133,7 +143,7 @@ Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructShadowRender
mShadowRenderStateSet->addRenderState( shadowDepthTest );

Qt3DRender::QCullFace *shadowCullFace = new Qt3DRender::QCullFace;
shadowCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
shadowCullFace->setMode( Qt3DRender::QCullFace::CullingMode::Front );
mShadowRenderStateSet->addRenderState( shadowCullFace );

return mLightCameraSelectorShadowPass;
Expand All @@ -142,7 +152,7 @@ Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructShadowRender
Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructPostprocessingPass()
{
mPostProcessingCameraSelector = new Qt3DRender::QCameraSelector;
mPostProcessingCameraSelector->setCamera( mMainCamera );
mPostProcessingCameraSelector->setCamera( mLightCamera );

mPostprocessPassLayerFilter = new Qt3DRender::QLayerFilter( mPostProcessingCameraSelector );
mPostprocessPassLayerFilter->addLayer( mPostprocessPassLayer );
Expand Down Expand Up @@ -419,7 +429,11 @@ void calculateViewExtent( Qt3DRender::QCamera *camera, float shadowRenderingDist
QVector3D( 0.0f, 0.0f, depth ),
QVector3D( 0.0f, 1.0f, depth ),
QVector3D( 1.0f, 0.0f, depth ),
QVector3D( 1.0f, 1.0f, depth )
QVector3D( 1.0f, 1.0f, depth ),
QVector3D( 0.0f, 0.0f, 0 ),
QVector3D( 0.0f, 1.0f, 0 ),
QVector3D( 1.0f, 0.0f, 0 ),
QVector3D( 1.0f, 1.0f, 0 )
};
maxX = std::numeric_limits<float>::lowest();
maxY = std::numeric_limits<float>::lowest();
Expand Down
14 changes: 10 additions & 4 deletions src/3d/shaders/postprocess.frag
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ float CalcShadowFactor(vec4 LightSpacePos)
UVCoords.y = 0.5 * ProjCoords.y + 0.5;
float z = 0.5 * ProjCoords.z + 0.5;

if ( UVCoords.x < 0 || UVCoords.x > 1 || UVCoords.y < 0 || UVCoords.y > 1 )
return 1.0;

// percentage close filtering of the shadow map
float shadow = 0.0;
int k = 1;
Expand Down Expand Up @@ -109,14 +112,17 @@ float edlFactor(vec2 coords)

void main()
{
vec3 worldPosition = WorldPosFromDepth(texture(depthTexture, texCoord).r);
float depth = texture(depthTexture, texCoord).r;
vec3 worldPosition = WorldPosFromDepth( depth );
vec4 positionInLightSpace = projectionMatrix * viewMatrix * vec4(worldPosition, 1.0f);
positionInLightSpace /= positionInLightSpace.w;
vec3 color = texture(colorTexture, texCoord).rgb;
// if shadow rendering is disabled or the pixel is outside the shadow rendering distance don't render shadows
if (renderShadows == 0 || worldPosition.x > shadowMaxX || worldPosition.x < shadowMinX || worldPosition.z > shadowMaxZ || worldPosition.z < shadowMinZ) {
fragColor = vec4(color.rgb, 1.0f);
} else {
if (renderShadows == 0 || depth >= 1 || worldPosition.x > shadowMaxX || worldPosition.x < shadowMinX || worldPosition.z > shadowMaxZ || worldPosition.z < shadowMinZ)
{
fragColor = vec4(color, 1.0f);
} else
{
float visibilityFactor = CalcShadowFactor(positionInLightSpace);
fragColor = vec4(visibilityFactor * color, 1.0f);
}
Expand Down

0 comments on commit 15d48a1

Please sign in to comment.