I'm currently working on a Deferred shading project in DirectX. I noticed weird lighting when I create the final image;
With this light ray constantly shining from the top left. I looked at my gbuffers and noticed that my position only seems to take the UV coordinates of the screen (but flipped?) where objects are located.
Uv coordinate map for reference
This becomes way more apparent when I try to apply shadow mapping.
The answer is probably really easy, but I am staring myself blind at my code to find what's wrong. I'm posting my shader codes below, sorry if its a lot, I have implemented a working tesselator as well, and I think the problem either lies in the domain or pixelshader.
Vertex shader
struct VertexShaderInput
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct VertexShaderOutput
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
VertexShaderOutput DeferredVertexShader(VertexShaderInput input)
{
VertexShaderOutput output;
output.position = input.position;
output.texcoord = input.texcoord;
output.normal = input.normal;
return output;
}
Hull shader
cbuffer TessellationBuffer
{
matrix world;
float3 CamPos;
float padding;
};
struct HullShaderInput
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct ConstantOutput
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
struct HullShaderOutput
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
// PATCH OUTPUT FUNCTION
ConstantOutput PatchConstantFunction(InputPatch<HullShaderInput, 3> inputPatch, uint patchId : SV_PrimitiveID)
{
ConstantOutput output;
float3 center = (inputPatch[0].position + inputPatch[1].position + inputPatch[2].position) / 3.0f;
float3 centerW = mul(float4(center, 1.0f), world).xyz;
const float d = distance(centerW, CamPos);
const float d0 = 0.01f;
const float d1 = 10.0f;
float tessellationAmount = 12.0f * saturate((d1 - d) / (d1 - d0)) + 1;
output.edges[0] = tessellationAmount;
output.edges[1] = tessellationAmount;
output.edges[2] = tessellationAmount;
output.inside = tessellationAmount;
return output;
}
// Hull shader
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("PatchConstantFunction")]
HullShaderOutput DeferredHullShader(InputPatch<HullShaderInput, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID)
{
HullShaderOutput output;
output.position = patch[pointId].position;
output.texcoord = patch[pointId].texcoord;
output.normal = patch[pointId].normal;
return output;
}
Domain shader
cbuffer MatrixBuffer
{
matrix world;
matrix view;
matrix proj;
};
struct ConstantOutput
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
struct DomainShaderInput
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct DomainShaderOutput
{
float4 position : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
// DOMAIN SHADER
[domain("tri")]
DomainShaderOutput DeferredDomainShader(ConstantOutput input, const OutputPatch<DomainShaderInput, 3> patch, float3 barycentric : SV_DomainLocation)
{
float4 worldPos;
float3 vertexPosition, flatPosition;
DomainShaderOutput output;
output.texcoord = barycentric.x * patch[0].texcoord + barycentric.y * patch[1].texcoord + barycentric.z * patch[2].texcoord;
output.normal = barycentric.x * patch[0].normal + barycentric.y * patch[1].normal + barycentric.z * patch[2].normal;
vertexPosition = barycentric.x * patch[0].position + barycentric.y * patch[1].position + barycentric.z * patch[2].position;
float3 vecProj0 = dot(patch[0].position - vertexPosition, patch[0].normal) * patch[0].normal;
float3 vecProj1 = dot(patch[1].position - vertexPosition, patch[1].normal) * patch[1].normal;
float3 vecProj2 = dot(patch[2].position - vertexPosition, patch[2].normal) * patch[2].normal;
float3 vecOffset = barycentric.x * vecProj0 + barycentric.y * vecProj1 + barycentric.z * vecProj2;
vertexPosition += 0.5f * vecOffset;
worldPos = mul(vertexPosition, world);
output.position = mul(float4(vertexPosition, 1.0f), world);
output.position = mul(output.position, view);
output.position = mul(output.position, proj);
output.normal = mul(output.normal, (float3x3)world);
output.normal = normalize(output.normal);
return output;
}
Pixel shader
Texture2D diffuseTexture : register(t0);
Texture2D specularTexture : register(t1);
Texture2D ambientTexture : register(t2);
SamplerState sampleTypeWrap : register(s0);
cbuffer MaterialBuffer
{
float specularPower;
float3 pad3;
};
struct PixelShaderInput
{
float4 position : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct PixelShaderOutput
{
float4 position : SV_Target0;
float4 normal : SV_Target1;
float4 diffuse : SV_Target2;
float4 specular : SV_Target3;
float4 ambient : SV_Target4;
};
PixelShaderOutput DeferredPixelShader(PixelShaderInput input) : SV_TARGET
{
PixelShaderOutput output;
output.position = input.position;
output.position.w = 1.0f;
input.normal = normalize(input.normal);
output.normal = float4(input.normal, 1.0f);
output.diffuse = diffuseTexture.Sample(sampleTypeWrap, input.texcoord);
output.specular = specularTexture.Sample(sampleTypeWrap, input.texcoord);
output.ambient = ambientTexture.Sample(sampleTypeWrap, input.texcoord);
output.specular.w = specularPower;
return output;
}
`float4x4 lightView = lBuffer[index].lightView; float4x4 lightProj = lBuffer[index].lightProj; float4 lightViewPos = mul(float4(pos, 1.0f), lightView); lightViewPos = mul(lightViewPos, lightProj); float2 projUV; projUV.x = lightViewPos.x / lightViewPos.w / 2.0f + 0.5f; projUV.y = -lightViewPos.y / lightViewPos.w / 2.0f + 0.5f;` lBuffer holds all the lights information, and pos is a float3 from the position gBuffer – Charlie.Q Mar 12 '23 at 16:53