Sign in to follow this  
lucky6969b

How to write a "Natural-looking" pixel shader

Recommended Posts

Hi,
I am in trouble of writing a simple pixel shader.
Here is my code
[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);
}


[/code]

[code]
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);
[/code]
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.

[url="http://imageshack.us/photo/my-images/193/psproblem.png/"]http://imageshack.us.../psproblem.png/[/url]

Thanks
Jack

Share this post


Link to post
Share on other sites
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
[code]
Lighting = true;
AlphaBlendEnable = true;
DestBlend = INVSRCALPHA;
SrcBlend = SRCALPHA;
[/code]

so that the transparent objects render correctly.
I then put
[code]
Lighting = false;
AlphaBlendEnable = false;
DestBlend = ZERO;
SrcBlend = ZERO;
[/code]
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this