Jump to content
  • Advertisement
Sign in to follow this  

How to write a "Natural-looking" pixel shader

This topic is 2920 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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)

//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.



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

Lighting = true;
AlphaBlendEnable = true;
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?

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
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!