Pixel shader - ghourad shading

Started by
9 comments, last by reltham 18 years, 8 months ago
I'm creating a shader that will eventually evolve into a phong shader, but currently I'm just trying to make a ghourad. Anyway, the problem is I suspect all vector components (x,y,z) are reduced to the interval [0, 1] thus making the calculations outside the first quadrant (or octant, since it's 3D) wrong (negative directions turn to 0). Why does it do this? My gfx card has vs 1.1 and ps 1.3. Vertex shader:

struct VS_IN
{
  float4 Position : POSITION;
  float3 Normal : NORMAL;
  float2 TexturePosition : TEXCOORD;
};

struct VS_OUT
{
  float4 Position : POSITION;
  float2 TexturePosition : TEXCOORD0;
  float3 Light : TEXCOORD1;
  float3 Normal : TEXCOORD2;
  float3 View : TEXCOORD3;
};

float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 ProjectionMatrix;
float4x4 ViewProjectionMatrix;
float4x4 WorldViewProjectionMatrix;
float4x4 InverseWorldMatrix;
float4x4 InverseViewMatrix;
float4x4 InverseProjectionMatrix;
float4x4 InverseViewProjectionMatrix;
float4x4 InverseWorldViewProjectionMatrix;
float4 CameraPosition;
float4 CameraDirection;
float4 AmbientColor;
float4 DiffuseColor;
float4 SpecularColor;

VS_OUT main(VS_IN In)
{
  VS_OUT Out;

  float3 WorldPosition = normalize(mul(In.Position, WorldMatrix));

  Out.Position = mul(In.Position, WorldViewProjectionMatrix);
  Out.TexturePosition = In.TexturePosition;
  Out.Light = -CameraDirection;
  Out.Normal = normalize(mul(In.Normal, WorldMatrix));
  Out.View = normalize(CameraPosition - WorldPosition);

  return Out;
}


Pixel shader:

struct PS_IN
{
  float4 Position : POSITION;
  float2 TexturePosition : TEXCOORD0;
  float3 Light : TEXCOORD1;
  float3 Normal : TEXCOORD2;
  float3 View : TEXCOORD3;
};

struct PS_OUT
{
  float4 Color : COLOR;
};

float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 ProjectionMatrix;
float4x4 WorldViewProjectionMatrix;
float4 CameraPosition;
float4 CameraDirection;
float4 AmbientColor;
float4 DiffuseColor;
float4 SpecularColor;

sampler2D Texture;

PS_OUT main(PS_IN In)
{
  PS_OUT Out;

  Out.Color = AmbientColor + DiffuseColor * saturate(dot(In.Light, In.Normal));
  Out.Color.a = 1.0f;

  return Out;
}


----------------------------------------MagosX.com
Advertisement
If you use the TEXCOORD registers to transfer data from the VS to the PS, the data won't be clamped. Only the COLOR registers clamp to [0,1]. You're using the TEXCOORD registers, so that's not the problem. Come to think of it, what is the problem? I don't think you ever said!

BTW, it's "Gouraud," not "Ghourad" ;)
_______________________________________________________________________Hoo-rah.
The lighting in the first octant is fine (top left pic), but if you look at the lighted pixels in the other octants they are much darker. In the 8th octant (where all x,y,z are negative it's pitch black, apart from the ambient light) (top right pic).

I thought maybe the normals were clamped since that would give the same effect. I've printed both the camera (light) direction and the generated normal map and they seem correct.

----------------------------------------MagosX.com
For 1.1-1.3 cards I have always had to do the scale and bias thing for TEXCOORD output values as well as COLOR output values.

In the vs you would need to scale and bias the Light, Normal, and View values to be between 0 and 1. Then, in your pixel shader reverse it (2 * value - 1 <-- will convert to the _bx2 modifier in 1.x pixel shaders).

Also, keep in mind that 1.x pixel shader arithmatic has limited range for values (it's a cap you can check: PixelShader1xMaxValue) that is usually small like +/- 1 or 8.
Thanks reltham, your suggestion worked!
----------------------------------------MagosX.com
Quote:In the vs you would need to scale and bias the Light, Normal, and View values to be between 0 and 1. Then, in your pixel shader reverse it (2 * value - 1 <-- will convert to the _bx2 modifier in 1.x pixel shaders).


Why do you need to do this? You can have texture coordinates values outside the range [0, 1]--for tiling, for instance. The only time I thought you had to do that was when you were using a normal map for instance, where each normal component is stored in an 8-bit range 0-255.

-----Quat
Does anyone have a PS 1.3 phong shader? Implementing it the traditional way is too complex for PS 1.3...
----------------------------------------MagosX.com
sorru guys, what is an octant ?
In 2D graphing, you have four quadrants - upper-right, where both x and y are positive; upper-left, where x is negative and y is positive; lower-left where both x and y are negative; and lower-right, where x is positive and y is negative. In 3D, the same thing applies, but since there is a third dimension, there are eight "octants" instead of four "quadrants." It just has to do with combinations of negative and positive coordinates on each of the axes.

Magos - I just looked it up in the ASM shader docs, and it seems that the vertex shader TEXCOORD outputs are not normalized, but the TEXCOORD inputs in the pixel shader are. For ps1.3, they are limited to - MaxTextureRepeat to + MaxTextureRepeat, which is at least [-1,1] on ps1.3 hardware. I never knew that, and sorry for misleading you ;) I'm just so used to ps2.0, where TEXCOORD inputs to pixel shaders can be any large number that the VS can put out.
_______________________________________________________________________Hoo-rah.
Hey, i was wondering if you could email me your project so far. it's Stiffler_shade@yahoo.com i just want to learn about shaders. Thanks alot
~Mark Schadler

This topic is closed to new replies.

Advertisement