How to write a "Natural-looking" pixel shader

Started by
1 comment, last by Dawoodoz 12 years, 6 months ago
Hi,
I am in trouble of writing a simple pixel shader.
Here is my code

//Vertex Input
struct VS_INPUT
{
float4 position : POSITION0;
float3 normal : NORMAL;
float2 tex0 : TEXCOORD0;
};

//Vertex Output / Pixel Shader Input
struct VS_OUTPUT
{
float4 position : POSITION0;
float3 normalW : TEXCOORD0;
float2 tex0 : TEXCOORD1;
float shade : TEXCOORD2;
float3 toEyeW : TEXCOORD3;
float color : COLOR0;
};

//Vertex Shader
VS_OUTPUT vs_lighting(VS_INPUT IN)
{
VS_OUTPUT OUT = (VS_OUTPUT)0;

//getting the position of the vertex in the world
float4 posWorld = mul(IN.position, matW);
float4 normal = normalize(mul(IN.normal, matW));

//getting to position to object space
OUT.position = mul(posWorld, matVP);

OUT.shade = max(dot(normal, normalize(lightPos - posWorld)), 0.2f);

OUT.tex0 = IN.tex0;

OUT.normalW = normal;

OUT.toEyeW = gEyePosW - posWorld;



return OUT;
}

//Pixel Shader
float4 ps_lighting(VS_OUTPUT IN) : COLOR0
{
IN.normalW = normalize(IN.normalW);
IN.toEyeW = normalize(IN.toEyeW);

float3 lightVecW = gLight.dirW;

float3 r = reflect (-lightVecW, IN.normalW);

float t = pow(max(dot(r, IN.toEyeW), 0.0f), gMtrl.specPower);

float s = max(dot(lightVecW, IN.normalW), 0.0f);

float3 spec = t*(gMtrl.spec*gLight.spec).rgb;
float4 diffuse = s*(gMtrl.diffuse*gLight.diffuse).rgba;
float4 ambient = (gMtrl.ambient*gLight.ambient).rgba;

float4 color = (ambient + diffuse);

float4 texColor = tex2D(DiffuseSampler, IN.tex0);

// float3 colorF = color * texColor.rgb + spec;
//return float4(colorF * IN.shade, gMtrl.diffuse.a);
return float4(color.rgb, gMtrl.diffuse.a);
}





DirLight l;
l.diffuse.a = 1.0f;
l.diffuse.r = 0.5f;
l.diffuse.g = 0.5f;
l.diffuse.b = 0.5f;
l.ambient = l.diffuse;
l.spec.a = 0.0f;
l.spec.r = 0.0f;
l.spec.g = 0.0f;
l.spec.b = 0.0f;
l.dirW = D3DXVECTOR3(0.0, -1.0, 0.0);

What I don't need is texture. I need a material color from each object.
As you see, I calculate the lights and materials based on global variables passed in.
Then I just add up ambient color and diffuse color to get the result.
However, the picture I show you is really unnatural. How do I modify this "barely minimal" simple pixel shader?
The problem is especially serious on the forklifts. See picture below
Any help is greatly appreciated.

http://imageshack.us.../psproblem.png/

Thanks
Jack
Advertisement
I ran into a strange situation. When I disable the fixed pipeline including alpha blending and source + dest blending, the forklift is displayed correctly.
So I split the shader into 2 parts. 1st for rendering things with alpha and 2nd one for rendering the forklift.
I put the constants

Lighting = true;
AlphaBlendEnable = true;
DestBlend = INVSRCALPHA;
SrcBlend = SRCALPHA;


so that the transparent objects render correctly.
I then put

Lighting = false;
AlphaBlendEnable = false;
DestBlend = ZERO;
SrcBlend = ZERO;

into the second technique. No matter what I tried, the forklift colors just look dull. Sounds like transparent more or less
Strangely enough, when I cancel everything including the fixed pipeline code, the forklift is rendered correctly.
So where should I be starting to look at to attack this problem?
Thanks
Jack
Make sure that you render opaque items before transparent items so that opaque items can be seen behind transparent items.
A generic grid texture, dark edges, shadows and fog can give more depth to the scene.

This topic is closed to new replies.

Advertisement