Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: [SOLVED] Specular does not work in tangent space  (Read 758 times)
Mietze
Community Member
*
Posts: 415

Pleeease, don't let it crash!


WWW
« on: July 28, 2009, 01:55:56 PM »

Problem has been solved. The binormal vector was not included in the mesh vertex data. Computing it via the cross product works fairly well, but its a bit faster to store it in the vertex directly. This can be done via "SetMeshFormat((int)(CONST_TV_MESHFORMAT.TV_MESHFORMAT_TEX1 | CONST_TV_MESHFORMAT.TV_MESHFORMAT_BUMPMAPINFO));"




Hi there,

I have been fooling around with tangent space normal mapping the last days and got real headaches with specular highlights. All calculations are done in tangent space and diffuse only lightning via the good old lambertian term and it works like a charm, but the specular stuff. I have tried most of the specular lightning models that are around and I have finally given up. The problem is, that the specular calculations work in world space, but not in tangent space. Thus the tangent space must be broken in some kind. The specular highlights appear where they should not do.

First of all, here are some screenies. The light direction is simply top-down:

Light:


View:


Normal:


Halfway:

So this is wrong, as you can see.

Result:


And here is some shader footage:

Code:
//=============================================================================
// Global variables
//=============================================================================
float4x4 g_mViewProjection : VIEWPROJECTION;
float4x4 g_mWorld : WORLD;
float4 g_vViewPosition : VIEWPOSITION;
float3 g_vLightDirection = float3(0, -1, 0);

//=============================================================================
// Vertex shader input structure
//=============================================================================
struct VS_INPUT
{
    float4 objectSpacePosition : POSITION;
    float3 normal : NORMAL;
    float2 uv : TEXCOORD0;
    float3 tangent : TANGENT;
    float3 binormal : BINORMAL;
};

//=============================================================================
// Vertex shader output structure
//=============================================================================
struct VS_OUTPUT
{
    float4 clipSpacePosition : POSITION;
    float2 uv : TEXCOORD0;
    float3 light : TEXCOORD1;
    float3 view : TEXCOORD2;
};

//=============================================================================
// Vertex Shader
//=============================================================================
VS_OUTPUT VS(VS_INPUT IN)
{
    VS_OUTPUT OUT;
    float4 worldSpacePosition = mul(IN.objectSpacePosition, g_mWorld);
   
    float3x3 tbn = float3x3
    (
        mul(IN.tangent,  g_mWorld).xyz,
        mul(IN.binormal, g_mWorld).xyz,
        mul(IN.normal,   g_mWorld).xyz
    );

    OUT.clipSpacePosition = mul(worldSpacePosition, g_mViewProjection);
    OUT.uv = IN.uv;
    OUT.view = mul(tbn, g_vViewPosition - worldSpacePosition.xyz);
    OUT.light = mul(tbn, -g_vLightDirection);

    return OUT;
}

#define PS_INPUT VS_OUTPUT

//=============================================================================
// Textures and samplers
//=============================================================================
texture texAlbedoMap : TEXTURE0;
texture texNormalMap : TEXTURE1;

sampler2D sampAlbedoMap = sampler_state
{
    Texture = (texAlbedoMap);
};

sampler2D sampNormalMap = sampler_state
{
    Texture = (texNormalMap);
};

//=============================================================================
// Pixel Shader
//=============================================================================
float4 PS(PS_INPUT IN) : COLOR0
{
    float4 finalColor;
    float3 view = normalize(IN.view);
    float3 light = normalize(IN.light);
    float3 normal = tex2D(sampNormalMap, IN.uv) * 2.0f - 1.0f; // a normalize here does not help
    float halfLambert = dot(normal, light) * 0.5f + 0.5f ;
    float3 halfway = normalize(light + view);
    float specular = pow(saturate(dot(normal, halfway)), 8);

    finalColor.rgb = specular.rrr;
    finalColor.a = 1.0f;
 
    return finalColor;
}

//=============================================================================
// Techniques
//=============================================================================
technique standard
{
    pass p0
    {
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();
    }
}

Hopefully you guys have an idea Smiley
« Last Edit: July 29, 2009, 02:20:43 AM by Mietze » Logged

Check out my blog at www.e-studioz.de - The finest in gross trash Wink
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks