HLSL & PS 1.1 Issue

Started by
1 comment, last by weewoo 17 years, 7 months ago
Hello All, I am working on implenting a tangent based dot3 bump mapping shader using PS 1.1. I am testing everything in Nvidia FX Composer and my problem is this... My normal mapping works fine when the angles of the light are coming from the right side of the object but as soon as i move the light on the left side i no longer really see any sort of bump mapping. It almost looks like a horrible color map instead with flat lines. Now if i change the compile target to be PS 1.4 or higher, then everything looks as it should. I cannot figure out why this is happening in PS 1.1. My other question is, why in PS 1.4 or higher do I not need a self shadowing multiplier for the normal map and I do in PS 1.3 or less. Example, without the self shadowing, when the light is facing away from the object I see the bump mapping since the normals are still facing the light since the light is now in that vertex' tangent space. Obviously the solution to this is to implement self-shadowing, but it seems not necessary in PS 1.4 or higher. Anyone know the reason to this? Thanks in advance for any one who can shed some light on this... My attached FX file source code:

//------------------------------------
float4x4 WorldViewProj : WorldViewProjection;
float4x4 World   : World;
float4x4 WorldInverseTranspose : WorldInverseTranspose;
float4x4 ViewInverse : ViewInverse;

texture NormalMap : Diffuse
<
    string ResourceName = "LowPolyNormalsMap.tga";
>;

texture TextureMap : Diffuse
<
    string ResourceName = "Texture.tga";
>;

float4 lightDir : Direction
<
    string Object = "DirectionalLight";
    string Space = "World";
> = {1.0f, -1.0f, 1.0f, 0.0f};

float3 lightColor : Diffuse
<
    string UIName = "Diffuse Light Color";
    string Object = "DirectionalLight";
> = {1.0f, 1.0f, 1.0f};

float4 lightAmbient : Ambient
<
    string UIWidget = "Ambient Light Color";
    string Space = "material";
> = {0.0f, 0.0f, 0.0f, 1.0f};

//------------------------------------
struct AppInput {
    float4 Pos			: POSITION;
    float3 Normal		: NORMAL;
    float3 Tangent 		: TANGENT;
    float2 TexCoords	: TEXCOORD;
};

struct PSInput {
    float4 Pos			: POSITION;
    float2 TexCoords	: TEXCOORD0;
    float2 TexCoords2	: TEXCOORD1;
    float3 Light		: TEXCOORD2;
    float3 Normal		: TEXCOORD3;
};


//------------------------------------
PSInput VS( AppInput In ) 
{
    PSInput Out;
    Out.Pos = mul( In.Pos, WorldViewProj );
    Out.TexCoords = In.TexCoords;
    Out.TexCoords2 = In.TexCoords;
    
    float3x3 WorldToTangent;
    WorldToTangent[0] = mul( In.Tangent, World );
    WorldToTangent[1] = mul( cross( In.Tangent, In.Normal ), World );
    WorldToTangent[2] = mul( In.Normal, World );
    
    Out.Light = normalize( mul( WorldToTangent, -lightDir ) );
    Out.Normal = normalize( mul( WorldToTangent, WorldToTangent[2] ) );
    
    return Out;
}

//------------------------------------
sampler NormalMapSampler = sampler_state 
{
    texture = <NormalMap>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

sampler TextureMapSampler = sampler_state 
{
    texture = <TextureMap>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

//-----------------------------------
float4 PS( PSInput In ): COLOR
{
	float3 Normal = ( 2 * tex2D( NormalMapSampler, In.TexCoords ) ) - 1;
	float4 Texture = tex2D( TextureMapSampler, In.TexCoords2 );
	
	float SelfShadow = saturate( 4 * dot( In.Normal, In.Light ) );
	float NormalMapDiffuse = saturate( dot( Normal, In.Light ) );
	return SelfShadow * float4( lightColor * NormalMapDiffuse * Texture , 1.0f );
}

//-----------------------------------
technique Diffuse
{
    pass p0 
    {
		VertexShader = compile vs_1_1 VS();
		PixelShader  = compile ps_1_1 PS();
    }
}


[Edited by - weewoo on September 15, 2006 2:51:02 PM]
Advertisement
vs.1.1 can only output values from 0 to 1 to ps.1.1 shader, except for when using a texcoord as an actual texcoord. Outputting as color, or reading a texcoord as value will clamp the values to a 0..1 range.

In the VS, multiply the normal and the light vector by 0.5, and add 0.5 (-1..1 into 0..1)

In the PS, multiply the normal and light vector by 2, and subtract 1 (0..1 into -1..1)

Also, be aware the FX composer only has tangents on one face of their primitives, making it a royal pain to debug with.
Thanks soooo much, it worked perfectly! I spent quite a few hours trying to figure this out. Now that i know about it, I still cannot find anythign regarding it in the documentaton... Go figure( The clamping that is ).

This topic is closed to new replies.

Advertisement