Advertisement

Problem with normals (DirectX 11)

Started by March 27, 2021 02:45 PM
4 comments, last by adam7 3 years, 7 months ago

Hi, I'm trying to write a shader that displays the normals of a mesh:

As you can see, the normals do not appear to be smooth. Why is this? Usually when I see people displaying the normals of their meshes, the normals appear to interpolate smoothly over the surface,

Sometimes I see people generating a TBN matrix when calculating the normals, which is what I tried to do here:

However, the normals are still not smooth and now the normals also rotate with the object as you can see in the image.

Here are my shaders, what am I doing wrong? Thanks.

Texture2D albedo;
Texture2D normalMap;

SamplerState SampleType;

cbuffer LightBuffer {
    float4 diffuseColor;
    float3 lightDirection;
};

struct PixelInputType {
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float3 binormal : BINORMAL;
    float3 worldPosition : WORLDPOSITION;
};

struct PS_OUTPUT {
    float4 worldPos : SV_Target0;
    float4 normals : SV_Target1;
    float4 albedo : SV_Target2;
};

PS_OUTPUT BumpMapPixelShader(PixelInputType input) : SV_TARGET{
    float4 textureColor;
    float4 bumpMap;
    float3 bumpNormal;
    float3 lightDir;
    float lightIntensity;
    float4 color;

    PS_OUTPUT output;

    float3 normals;
    float3 worldPos;

    float3 T;
    float3 B;
    float3x3 TBN;

    output.albedo = float4(1.0f, 1.0f, 1.0f, 1.0f);
    
    normals = input.normal;
    T = normalize(input.tangent - normals * dot(input.tangent, normals));
    B = cross(T, normals);


    TBN = float3x3(T, B, normals);
    normals = normalize(mul(normals, TBN));
   
    output.normals = float4(normals, 1.0f);
    

    worldPos = input.worldPosition;
    output.worldPos = float4(worldPos, 1.0f);

    return output;
}
cbuffer MatrixBuffer {
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};


struct VertexInputType {
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float3 binormal : BINORMAL;
};

struct PixelInputType {
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float3 binormal : BINORMAL;
    float3 worldPosition : WORLDPOSITION;
};

PixelInputType BumpMapVertexShader(VertexInputType input) {
    PixelInputType output;

    input.position.w = 1.0f;

    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);

    output.tex = input.tex;

    output.normal = mul(input.normal, (float3x3)worldMatrix);
    output.normal = normalize(output.normal);

    output.tangent = mul(input.tangent, (float3x3)worldMatrix);
    output.tangent = normalize(output.tangent);

    output.binormal = mul(input.binormal, (float3x3)worldMatrix);
    output.binormal = normalize(output.binormal);

    output.worldPosition = mul(input.position, worldMatrix).xyz;
    output.worldPosition = normalize(output.worldPosition);


    return output;
}

The tangents are not smooth if they are not computed from smooth normals, and you transform normal by TBN matrix.

Advertisement

@JohnnyCode Thanks, that makes sense. But why are the normals not smooth. Is it a problem with how I load the mesh or is the one of the shaders set up wrong?

The mesh asset needs to have normals smoothed in its definition.Are you sure they are smooth?

It looks like the normals are not smoothed as pointed out by @johnnycode .
The problem might be in either export or import of the mesh data.

The normals shown in your picture seems to be calculated from their respective triangle / quad they belong to.
Instead the normal should be a result from all the triangles the vertex is part of, thus achieving the smoothed normal.

@noxil @johnnycode The problem was indeed with the mesh importing. The tutorial I used to load meshes recalculated the normal by using the tangent and binormal vectors. I have changed it to use the normal data from the mesh file instead. The normals now appear smooth. Thanks for your help!

This topic is closed to new replies.

Advertisement