Normal Interpolations?

Started by
3 comments, last by NickGomes 12 years, 9 months ago
Hey so I recently decided to start playing around with DirectX 11. I have some previous experience with fixed-function OpenGL. Right now I'm having some trouble getting DirectX to interpolate my model's (a low poly sphere) normals. In a fixed function pipeline i remember you just called ShadeMode(smooth) and it would automatically interpolate your normals. I read around and saw that DirectX is able to automatically interpolate your normals between the vertex and pixel shaders using interpolation modifiers. However despite hours of messing around and searching i have yet to find a solution.

My set up is pretty simple:

A low poly sphere lit with a basic directional light with only an ambient and diffuse component. I have set up some buffers to include specular light but i don't want to set that up yet without figuring out how to interpolate the model's normals.

Here is my pixel shader

Texture2D shaderTexture;
SamplerState sampleType;

cbuffer LightBuffer
{
float4 ambientColor;
float4 diffuseColor;
float4 specularColor;
float specularPower;
float3 lightDirection;
};

struct PixelInput
{
float4 position: SV_POSITION;
float2 tex: TEXCOORD0;
float3 viewDirection: TEXCOORD1;
float3 normal: NORMAL;
};

float4 LightPixelShader(PixelInput input):SV_TARGET
{
float4 finalColor;
float4 textureColor;
float3 lightDir;
float lightIntensity;


textureColor = shaderTexture.Sample(sampleType, input.tex);

textureColor = textureColor * textureColor;

finalColor = ambientColor;

lightDir = -lightDirection;
lightIntensity = saturate(dot(input.normal, lightDir));

if(lightIntensity > 0.0f)
{
finalColor += (diffuseColor * lightIntensity);
}

return finalColor;
}
Advertisement
You'd want to take a look at the HLSL interpolation modifiers introduced in SM 4.0. However, by default normals (and vertex shader outputs in general) are linearly interpolated, so really for basic lightning you don't have to do anything - just pass your vertex normal as output from the vertex shader. So most likely something else is going on - maybe include the complete effect (the vertex shader), a picture of the problem, or run the app through PIX - maybe your normals are just messed up to begin with?
Normals passed through an interpolator technically need to be normalized again before use in the pixel shader, but depending on the art and how far they deviate from the correct value, it can be skipped as an optimization.

In either case, if for some reason you are have mixed positive and negative z values for you surface-local vertex normals, you can end up with a singularity case for a pixel or two where the pixel interpolated value hits 0,0,0 and cannot be normalized. This turns out to be a very rare case unless your artists are a bit strange, and we all know, some of them are.
http://www.gearboxsoftware.com/
just thought i would also mention something (i'm not sure if this is the problem), since normals can automatically be interpolated, if your having problems where it looks like they're not, you might be using face normals, where every vertices normal is actually the face normal. You will want to average your vertices normals, so that the normals of all the faces sharing a vertex will be averaged together, then normalized. That will give you nice smooth lighting across faces.
Thanks for the quick replies, PIX revealed the problem almost instantly. The issue appears when parsing a .obj model to the engine's model format. Every vertex of a given face is assigned the FACE normal and not it's own normal. So if every vertex of a face has the same normal...........that means interpolating the normals has no effect. This would also explain some very weird bug I'm having creating a simple silhouette edge.

This topic is closed to new replies.

Advertisement