I have a deferred rendering system: first there is the G buffer generation, then there is the lighting or shading calculation on that gbuffer data.
However there seems to be an issue with various rendering algorithms and I can’t determine why that is. I think it’s because my normal’s Gbuffer texture or other G buffer texture does not have the proper format or space in terms of world space, tangent space etc.
The algorithms that rely on normal information such as normal oriented ambient occlusion and parallax occlusion mapping don’t work they just look wrong And not what they’re supposed to be by a long shot.
In the G buffer generation stage, my vertex shader simply passes along world space vertex positions and world space normals to the Gbuffer's fragment shader. I do this by multiplying the world matrix or model matrix by the normal and by the position. In the fragment shader I then write these out as is to the G buffer.
Is this correct? Should I be passing along the Raw position & normals to the fragment shader and then multiplying the matrices in the fragment shader instead?
Edit 1:
Ok, So using the "normalMatrix" didn't change anything. Here is a screen shot of my ambient-occlusion pass demonstrating the issue. There is a screen space split that basically inverts the colors. and some other oddities.
The SSAO Shader is As Follows.
void main()
{
vec3 WorldPosition = texture(GPositionsTexture, In_TexCoords).xyz;
vec3 WorldNormal = normalize(UnScaleNormal( texture( GNormalsTexture, In_TexCoords ).xyz ));
vec3 Random = texture(KernalNoiseTexture, In_TexCoords * KernelNoiseScale).xyz;
vec3 Tangent = normalize(Random - WorldNormal * dot(Random, WorldNormal));
vec3 BiTangent = cross(WorldNormal, Tangent);
mat3 TBN = mat3(Tangent, BiTangent, WorldNormal);
float Occlusion = 0.0;
for (int i = 0; i < KERNEL_SIZE; ++i)
{
// get sample position:
vec3 Sample = TBN * Kernel[i];
Sample = Sample * Radius + WorldPosition;
// project sample position:
vec4 Offset = vec4(Sample, 1.0);
Offset = CamData.Projection * CamData.View * Offset;
Offset.xy /= Offset.w;
Offset.xy = Offset.xy * 0.5 + 0.5;
// get sample depth:
float SampleDepth = texture(GPositionsTexture, Offset.xy).z;
// range check & accumulate:
float RangeCheck= abs(WorldPosition.z - SampleDepth) < Radius ? 1.0 : 0.0;
Occlusion += (SampleDepth <= Sample.z ? 1.0 : 0.0) * RangeCheck;
}
Occlusion = 1 - (Occlusion / KERNEL_SIZE);
Out_Diffuse = pow(Occlusion, Power);
}