Deferred renering point light artifact based upon depth

Started by
4 comments, last by judeclarke 5 years, 4 months ago

Based upon where my how far back from the camera is there will be a artifact of my point light.

Here is what I mean before going into details

image.png.cb7a4759942a00c87d9af13c475a68f1.png

 

I have a flat rectangle and a standing rectangle of 20x20 dimensions with a point light of 22 radius. My camera currently sits at -76 but if I were to move the camera to -75 then even in the most extreme example of point light z = 3.0 from above will no longer have the artifact.

 

I am not sure what could be causing it but I have tried several idea to avail. The one with the biggest benefit seemed to be scaling my world matrix for rendering the point lights sphere by a small modifier like 1.1 in addition to the radius.That seemed to only mask the issue for a little bit.

 

When looking at the render targets in RenderDoc going into the lighting pass the render targets seem correct so my guess is that it is my shading code.

image.png.2ef3021baf9d3ea42e03f655c22f3949.png

 

I am not sure what other details would be beneficial to detailing the problem but if there is something mentioned I will post it.

 

Shader Code


Texture2D NormalMap : register( t0 );
Texture2D DiffuseAlbedoMap : register( t1 );
Texture2D SpecularAlbedoMap : register( t2 );
Texture2D PositionMap : register(t3);

cbuffer WorldViewProjCB : register( b0 )
{
	matrix WorldViewProjMatrix;
	matrix WorldViewMatrix;
}

cbuffer CameraPosition : register ( b2 )
{
	float3 CameraPosition;
}

cbuffer LightInfo : register ( b3 )
{
	float3 LightPosition;
	float3 LightColor;
	float3 LightDirection;
	float2 SpotLightAngles;
	float4 LightRange;
};

struct VertexShaderInput
{
	float4 Position : POSITION;
};

struct VertexShaderOutput
{
	float4 PositionCS : SV_Position;
	float3 ViewRay : VIEWRAY;
};

VertexShaderOutput VertexShaderFunction(in VertexShaderInput input)
{
	VertexShaderOutput output;
	output.PositionCS = mul( input.Position, WorldViewProjMatrix );
	float3 positionVS = mul( input.Position, WorldViewMatrix ).xyz;
	output.ViewRay = positionVS;
	return output;
}

void GetGBufferAttributes(in float2 screenPos, out float3 normal,
			out float3 position,
			out float3 diffuseAlbedo,
			out float3 specularAlbedo,
			out float specularPower)
{
	int3 sampleIndices = int3(screenPos.xy, 0);

	normal = NormalMap.Load(sampleIndices).xyz;
	position = PositionMap.Load(sampleIndices).xyz;
	diffuseAlbedo = DiffuseAlbedoMap.Load(sampleIndices).xyz;
	
	float4 spec = SpecularAlbedoMap.Load(sampleIndices);
	specularAlbedo = spec.xyz;
	specularPower = spec.w;
}

float3 CalcLighting(in float3 normal,
		in float3 position,
		in float3 diffuseAlbedo,
		in float3 specularAlbedo,
		in float specularPower)
{
	float3 L = 0;
	float attenuation = 1.0f;
	
	L = LightPosition - position;
	float dist = length(L);
	attenuation = max(0, 1.0f - (dist / LightRange.x));
	L /= dist;

	float nDotL = saturate(dot(normal, L));
	float3 diffuse = nDotL * LightColor * diffuseAlbedo;
	
	float3 V = CameraPosition - position;
	float3 H = normalize( L + V);
	float3 specular = pow(saturate(dot(normal, H)), specularPower) * LightColor * specularAlbedo.xyz * nDotL;

	return (diffuse + specular) * attenuation;
}

float4 PixelShaderFunction( in float4 screenPos : SV_Position ) : SV_Target0
{
	float3 normal;
	float3 position;
	float3 diffuseAlbedo;
	float3 specularAlbedo;
	float specularPower;
	
	GetGBufferAttributes(screenPos.xy, normal, position, diffuseAlbedo, specularAlbedo, specularPower);

	float3 lighting = CalcLighting(normal, position, diffuseAlbedo, specularAlbedo, specularPower);

	return float4(lighting, 1.0f);
}

 

image.png

Advertisement

When you render the sphere for the point light, do you have depth testing enabled?  What are your projection matrix values?  It almost looks like you're getting depth precision issues when rendering the light sphere.  You could try actually rendering the sphere to the screen and see if you get the same issues (instead of doing the lighting pass), just to visualize what's going on.

When I render my point light sphere my depth stencil has depth enabled. It is defined as


        D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
        ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

        depthStencilDesc.DepthEnable = true;
        depthStencilDesc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL;
        depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;

        depthStencilDesc.StencilEnable = true;
        depthStencilDesc.StencilReadMask = 0xFF;
        depthStencilDesc.StencilWriteMask = 0xFF;

        depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
        depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
        depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
        depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL;

        depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
        depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
        depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
        depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL;


        
My projection matrix values are


-        projectionMatrix    {_11=1.81066012 _12=0.000000000 _13=0.000000000 ...}    const Matrix4x4
        _11    1.81066012    float
        _12    0.000000000    float
        _13    0.000000000    float
        _14    0.000000000    float
        _21    0.000000000    float
        _22    2.41421342    float
        _23    0.000000000    float
        _24    0.000000000    float
        _31    0.000000000    float
        _32    0.000000000    float
        _33    1.01010096    float
        _34    1.00000000    float
        _41    0.000000000    float
        _42    0.000000000    float
        _43    -1.01010096    float
        _44    0.000000000    float


I renderd the sphere outside of my lighting pass and I do not have the same issue

It looks to me light you're rendering back-faces for the sphere mesh representing your point light, and that sphere is getting clipped by the far clipping plane of your camera. Does the issue go away if you increase the far clip plane?

Generally you want to render front-faces for your light proxy geo when your camera/near-plane aren't intersecting the light volume, since it avoids issues like this one.

On 12/7/2018 at 4:25 PM, MJP said:

It looks to me light you're rendering back-faces for the sphere mesh representing your point light, and that sphere is getting clipped by the far clipping plane of your camera. Does the issue go away if you increase the far clip plane?

Generally you want to render front-faces for your light proxy geo when your camera/near-plane aren't intersecting the light volume, since it avoids issues like this one.

I increased my far clip plane and it went away. Thanks for the help

This topic is closed to new replies.

Advertisement