Specular Mapping in Deferred Rendering

Started by
24 comments, last by Paul C Skertich 9 years, 9 months ago

Inside the vertex shader the tangent and normal space stored inside the gbuffer like this:



output.normal = mul((float3x3)modelWorld, input.normal);

output.tangent = mul((float3x3)modelWorld, input.tangent);

Brayzersoft tutorial for bump mapping uses model's normals for the tangents. the modelworld matrix is the matrix idenity of the model. Maybe I'm not understanding deferred lighting very much perhaps.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX
Advertisement

I would like to thank everyone for contributing their advice on this post! I finally have the issue at hand resolved. The final resulting image shows this - which matches up from a rastertek tutorial specular mapping for DirectX 11.

I solved the issue by just sending the normal mapped texture to the GBUFFER Render Target then with this:


float4 normalmap = Texture[1].Sample(ss, input.texcoord);
normalmap = (normalmap - 0.5) * 2.0;

I saw something on a forum or this forum about that slight caclulation above. It's giving me the results and I looked at the site you refered to Phil about the sphericalmapping encoding and decoding the X Y Z values. However, the guy was storing the render targets as R8G8B8A8 a single 32 bit render target. I'm storing as R32G32B32A32 render target. However, here's the final result:

Thanks for the help guys!

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX

Oops, i had to invert the light direction to get a more precise lighting. Here's the correct lighting with normal specular mapping inside the deferred shading system.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX

I don't see how this could be correct. From what you've described, the surface normal of your geometry never figures into your calculation (Does the lighting change when you rotate the cube or the direction of the light source?).

It seems like think you have it working successfully without actually achieving it, and without understanding why it's broken. You're trying random things without knowing why they do or don't work, and that's no way to learn. I'm not trying to be mean, but just offering advice. Here's an example:


I saw something on a forum or this forum about that slight caclulation above.

It maps the values [0, 1] to [-1,1]. This is needed since your normal map is likely in a standard RGBA format where each channel has values between 0 and 1. Do you want to learn? Sometimes it doesn't seem like it.

I would suggest to take a step back and try some simpler lighting tutorials first. Start with something simple and make sure you know what every part of your shader is doing and why. Otherwise you're just stumbling around in the dark.

I get you - Make sense because when outputing just regular normals the green (Y) is upward, red (Z) is facing you, blue is right handed (x) the calculation of the bitangents and the tangents might not calculated right. I believe I'm having issues when converting from tangent space to view space. When I attempt to do as suggested it funks up everything. The calculations make sense because to -1, 1 space 2.0f * normalmap -1.0f would give you ( 2.0 * 0.0 = 0 - 1.0 = -1.0. Then for the V 2 * 1 = 2 - 1 = 1. ) If you understand where I'm going at.

Here's the sniplet - the problem has to be converting everything back to view space after I'm done with it. The GBUFFER is the output render target correct? So all this talk about the GBUFFER is the output to render target?



input.normal = normalize(input.normal);

float4 normalmap = textureSampler[1].Sample(sampleState, input.texcoord);

float3 normalT =  normalize(normalmap * 2.0 - 1.0f); //-- Convert normal map to [-1, 1] space. 2 * -1 = -2 - 1 = -1. 2 * 1 = 2 - 1 = 1. 
float3 N = input.normal;
float3 T = normalize(input.tangent - dot(input.tangent , N) * N); //-- Substract the tangent (V) of the normals dot product of tangent and normal times by normal. 
float3 B = cross(N, T); //-- Find the biTangent by the cross dot product of normal and tangent. 
float3x3 TBN = float3x3(T,B,N); //-- Create a 3x3 matrix to store the tangent, biTangent and normal.
float3 bumpmap = normalize(mul(normalT, TBN)); //-- normalize the muliplied result of the normal inside 3x3 matrix.

float3 bumpVS = bumpmap * 0.5f + 0.5f; //-- take the bump map that is created and convert to 0,1 space. -1 * 0.5 = -.5 + 0.5 = 0. 1 * 0.5 = 0.5f + 0.5f = 1. 
output.normal = float4(bumpVS,1.0f);

This is you guys suggestion where as again messed up everything and starts me off at square 0. I don't know how in the world temporary fix solved everything. What I noticed is sometimes ti would have specular high lights but sometimes not depending how far or where I move the camera. I calculated the position of the light direction to be at and even then sometimes it won't light up as showned in the photo. Interestly enough I turned my render targets into R8G8B8A8 unsigned integar and noticed white little artifacts.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX

So, I realized my problem was the lack of understanding how deferred shading differs from forward pass rendering. Putting tangent data in a deferred engine wouldn't make sense where I can encode and decode the tangent and biTangent from the normal map already. That's what the spheremap exactly does. The math is confusing because I'm not a mathician and I hate math. I tried to break it down as much possibly why in the world it works the way it works. I believe it takes the colors from the normal map and translate it to object or world space.

In forward pass rendering where it calculates the light and the geometry data each draw call - that's what got me confused; What really confused me was the whole topic of this thread was about transforming tangent space into world or view space (object space) before rendering it out to the render target. Last night I've became frustrated on thinking how do you transform tangent space into view space. Transpose(TNB) gave me a closer idea what was going on. I stumbled upon this deferred shading demo that I downloaded and it had spherical normal mapping (spheremap). I plugged it in my gbuffer shader - now I can safely say it works. I looked at the code where the encoding and decoding parts to figure out how does it work. I suck at math but my guess is that it essentially transforms the normal map data into object space or view space.

Tangent normal maps look different than object space normal maps - thus giving them the effect of depth when lit.

So back to your question Phil - now does the specular lighting change when I"m in relation to the light? The light is at (0,-1,-1) inverted (0,1,1) When the light intensity is above 0.0 by the dot product ot the normal map and the light position then the reflection of the specular if full when I'm facing the object at 0,1,1 but dims when I'm viewing at position -5,1,1.

It doesn't pop back in nor pop back out like it use to - so I can safely say everything's in running condition. It wasn't just me that was confused about the difference of rendering normal mapping in deferred shading - a lot of people was unsure also.

So that's all for now. Thanks Julien and everyone who contributed to this thread. Also thanks for Phil for pushing me in the right direction.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX

This topic is closed to new replies.

Advertisement