Deferred Shading, Can you do Bump mapping?

Started by
20 comments, last by Namethatnobodyelsetook 18 years, 8 months ago
If you use yer render targets for normal, position.xy, position.z, diffuse... You have no more targets. Bump mapping uses tangents right? So how do you access the tangents if you cant pass them in and dont know which pixel uses which bump mapping texture? Thanks, Brad
--X
Advertisement
You fetch can use the inverse (or transpose) of the tangent matrix to get the normal from the normal map out of tangent space, and into world space. This is the normal you store in one render target, not the normal from the model.

Or atleast, that's what I'd expect. I haven't implemented a deferred shader.
Quote:Original post by Namethatnobodyelsetook
You fetch can use the inverse (or transpose) of the tangent matrix to get the normal from the normal map out of tangent space, and into world space. This is the normal you store in one render target, not the normal from the model.

Or atleast, that's what I'd expect. I haven't implemented a deferred shader.


So Just inverse the tangent matrix and wallaa the pixel/vertex normal pops out huh? nice... Whats the quickest way in hlsl to invert a matrix? is there a function built in? Thanks alot for the reply I know I read that somewhere and totally forgot it.

EDIT: I found transpose(m) that translate well?

EDIT2: Also I do this:
	float3x3 worldToTangentSpace;	worldToTangentSpace[0]	= mul( Tangent, World );	worldToTangentSpace[1]	= mul( cross(Tangent, Normal), World );	worldToTangentSpace[2]	= mul( Normal, World );


Which uses my normal to make the matrix that I need to inverse to change the Tangent into the normal... so where does that leave me now?

[Edited by - xsirxx on August 10, 2005 9:56:48 PM]
--X
Usually in deferred shading, you want to move your bump map normals out of tangent space when rendering them out. View space is probably best. This way you don't have to store the tangent space matrices or re-render your scene geometry with the tangent info.

I do semi-deferred shading, so I re-render the scene geometry with the tangent space info in it everytime I light, so I leave my bump maps in tangent space.

Once you have the tangent matrix you need to multiply the normal from the normal map by the transpose tangent matrix. The transpose is where the rows and columns are swapped. But its the exact same operation to multiply the tangent matrix by the normal. It's more efficient this way because you dont ned to compute the transpose.

mul(vNormal,matTangent) in HLSL

That gets your normal into world space. When you do regular dot3 bump mapping you usually transform everything into tangent space. For deffered shading the way you are doing you need everything in world space.
Quote:Original post by Leafteaner
That gets your normal into world space. When you do regular dot3 bump mapping you usually transform everything into tangent space. For deffered shading the way you are doing you need everything in world space.



Well im confused on how to build the tangent matrix now without needed both a tangent and a normal... :( I got how to do the transpose basically... swap the vector/matrix? But how do I build the tangent matrix without a normal and a tangent?


Quote:Original post by SimmerD
Usually in deferred shading, you want to move your bump map normals out of tangent space when rendering them out. View space is probably best. This way you don't have to store the tangent space matrices or re-render your scene geometry with the tangent info.


Ok forgive me, im sorta new to shaders, but when you say I want them in view space instead... do you simply mean take the normals and put them in view space? If I put my normals in view space, what should my positions be stored as? World still? Or should I take them over to view as well? And my light vectors?

I understand the view space basically... I have been dealing with world to world (being same space for lighting positions and model positions.) And the Normals I simply took against the object rotation matrix. Then against the tangent matrix... I guess this is where I i get lost, instead of using the tangent matrix...

Also, thanks for the help, ive been on this for 3 weeks :(.
--X
It seems like you are outputting your interpolated vertex normals into your "normals" render target, which might not be your goal, since it seems like you want to do normal mapping (or bump mapping, nvm). You have to output the surface normals in the first pass to your normal RT, ie. transform them from tangent space (in case of bump mapped surfaces) or model space (per-vertex interpolated normals) to view space, and write the per-pixel, view space normal to your normal RT in the first pass. You will use this surface-local normal to do your (lighting) calculations in your deferred pass. You only need the tangent/binormal vectors to transform the tangent-space normal to model space, not directly in your calculations.

Also, your position can be in view space or world space as long as you do your calculations in the good space, ie. a dot product between two vectors of the same space, computing the distance between two points in the same space (point lighting ?) and so on.
Heres one way to do normal mapping using deferred shading...

in first pass (building your buffers):
- Transform your interpolated vertex normal and your tangent by either the world matrix (if you want things in world-space) or by the world-view matrix (if you want things in view-space)
- Build the tangent matrix the same way you have been
- Read in tangent-space normal from a normal map
- mul(vNormal,matTangent) in HLSL (see my other reply for explanation)
- renormalize the normal (may not be nessecary)
- store it in one of your render targets

After that the normal will be ready to use as is during the shading pass. Just make sure that all your vectors (eye/view, position, normal etc) are in the same space (be it world or view). There is no need to build another tangent matrix in this pass.

By putting them in view space he means transforming them by a matrix to get them in view space (ie. the world matrix multiplied by the view matrix). I just leave things in world space because its usually simpler and involves less instructions in my engine, but either way is fine. The results will be the same. Hope this helps.
Tangent space & view space have some advantages over world/object space when you are filtering.

So, if multisampling is used, then view space or tangent space are better than world space.

For positions, view space is also better than world space, b/c you can perform this in the vertex shader, and retain more precision on the pixel side when outputting the depth ( or position ) in fp16.
Quote:Original post by Leafteaner

After that the normal will be ready to use as is during the shading pass. Just make sure that all your vectors (eye/view, position, normal etc) are in the same space (be it world or view). There is no need to build another tangent matrix in this pass.


This gives me my tangent or normal but that goes into my deferred shading and I would still have to extract the other one from the matrix, still requiring both right?

My problem Is bump mapping requires you have both a normal and a tangent normal right? OR one or the other and a Tangent matrix? Well If I cant have both how do I do bump mapping/or point lighting in the final(deferred) phase?

So, that said, It sounds like you all know of a way to do bump mapping without a tangent in the final phase? It looks as though you both said alls I need is the normal Or the normal in tangent space. BTW right now, I use the positions in world space in RT.
--X

This topic is closed to new replies.

Advertisement