Advertisement

SharpDX Directx11 How to add normal mapping ?

Started by September 18, 2017 01:59 PM
8 comments, last by gomidas 7 years, 4 months ago

I am trying to add normal map to my project I have an example of a cube: 

I have normal in my shader I think. Then I set shader resource view for texture (NOT BUMP)


            device.ImmediateContext.PixelShader.SetShaderResource(0, textureView);
            device.ImmediateContext.Draw(VerticesCount,0);

What should I do to set my normal map or how it is done in dx11 generally example c++?

Normal mapping usually works like this:

You have a normal map which is a texture containing tangent space normal vectors in the red and green components (XY). You have to transform it to world space (XYZ) and replace your vertex normal with this. All your following light calculations should use this new normal vector. That's it.

The trickiest part is the basis transformation from tangent space to world space which you have to do in the pixel shader. Usually games provide tangent and binormal (also called bitangent) vectors in the vertex buffers for the mesh. Or just store the tangent and calculate the bitangent like this:


bitangent = cross(normal, tangent)

For calculating tangent vectors for the vertices, there is an open source library called mikktspace written in C++. You can derive a C# implementation if there is not one already available. An other option is that you can provide a quaternion representing the tangent space. And the final option is that you can calculate the tangent space inside the pixel shader from screen space derivatives, like this.

When you have you normal, tangent and binormal vectors, which are unit vectors, you can assemble the tangent space transform matrix like so:


tangentBasis = float3x3(tangent, binormal, normal)

If you multiply your tangent space normal vectors which came from the normal map texture, you get the world space normal vector.

Advertisement
2 hours ago, turanszkij said:

Usually games provide tangent and binormal (also called bitangent) vectors in the vertex buffers for the mesh.

Alternatively, you can use Tangent Space Normal Mapping without Precomputed Tangents. This does not require tangents (or bitangents) stored per vertex at the expense of doing all calculations in the pixel shader.

Info + GLSL

Since, I do not use GLSL myself, I also have an HLSL version.

Edit: My apologies, didn't read the full answer before posting

🧙

IT IS GOD DAMN HARD. I have to study history. I do not have that time. If I use hlsl sided one can I stay away from all of those calculations ? If I do it, will it work same about quality ?

30 minutes ago, gomidas said:

IT IS GOD DAMN HARD. I have to study history. I do not have that time.

So why bother then?

31 minutes ago, gomidas said:

stay away from all of those calculations

If you do not want to learn why and how things work, just reuse the code.

🧙

Just now, matt77hias said:

So why bother then?

I do not know. Seriously I do not know.

Advertisement
33 minutes ago, gomidas said:

If I do it, will it work same about quality ?

Same quality as what? As providing the coordinate frame yourself? It is not numerically the same, but that is not a real issue for your purposes. It is a perturbation (i.e. small scale), so that will be fine.

🧙

alright if unreal engine does it too no problem for me.

I get something wrong about the setting file I think.


public Texture2D T2D_DiffuseMap = "File.png";
public ShaderResourceView textureView;

textureView = new ShaderResourceView(device, T2D_DiffuseMap);
device.ImmediateContext.PixelShader.SetShaderResource(0, textureView);

So will I have a Texture2D array that keeps multiple files diffuse.png and normal.png then I will do it like : new ShaderResourceView(device, TextureData); //diffuse.png and normal.png ??? Then I will modifyshader file. Or I am getting it wrong ? I am asking because there is no source for c#.

This topic is closed to new replies.

Advertisement