Jump to content
  • Advertisement
Sign in to follow this  
faeX

HLSL Shader: Color by angle

This topic is 2500 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

Hi community,

as I'm new to shader programing this question might be pretty easy to solve. :D

What I want to have is like this:
The shader gets a light direction, the camera-position and a texture containing the color that should be drawn depending on the angle between (pixelpos - camerapos) and light direction. Pixelpos stands for the absolute position of the untransformed pixel in 3d space. The first step simply would be to calculate the brightness depending on that angle. In a next step I can think about using colors from the texture. But first of all I want the angle thing solved. It is necessary that the angle is calculated for every pixel individually (in the pixel shader). But i have no clue how to surrender the world position and the projected position to the pixel shader. :/

I already have read through a few HLSL tutorials so far and I have to admit that I haven't unterstood everything... For instance I haven't understood so far which roles the rasterizer and the interpolator play in detail. Furthermore I'd like to know which values the interpolator uses and what data it gives to the pixel shader. I tried to play around with some example shaders to figure that out, but the results just confused me... :(

I hope you have unterstood my problem. :) Sorry if my English hinders from unterstanding.
Thanks!

faeX

Share this post


Link to post
Share on other sites
Advertisement
You could just translate your camera position and light position (and direction or whatever) into the same space the vertex is in when sent to the pixel shader by multiplying them with the WorldViewProjection matrix, then send them to the pixel shader

Share this post


Link to post
Share on other sites
Just transform your vertex to world space in the vertex shader, and pass that to your pixel shader. You can then use that to calculate your pixelpos - camerapos vector, or whatever other direction vectors that you need.

Share this post


Link to post
Share on other sites
I can't access the POSITION-semantic in the pixel shader. If I pass the vertex position as a TEXCOORD, they arent interpolated by the interpolator and the vertex position is used instead. (I think that at least...)

This is my shader:

float4x4 worldViewProj; // World * View * Projection transformation
float4x4 transWorld; // Transposed world matrix
float3 lightDir; // Light direction
float3 viewPos; // camera position

struct VS_OUTPUT
{
float4 Position : POSITION0; // vertex position
float4 WorldPosition : TEXCOORD0;
float3 viewPos : TEXCOORD1;
float3 lightDir : TEXCOORD2;
};

VS_OUTPUT vertexMain( in float4 vPosition : POSITION0)
{
VS_OUTPUT Output;
Output.Position = mul(vPosition, worldViewProj);

float4 worldpos = mul(transWorld, vPosition);
Output.WorldPosition = worldpos;

Output.viewPos = viewPos;
Output.lightDir = lightDir;

return Output;
}

struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};

sampler2D tex0;

PS_OUTPUT pixelMain(float4 Position : POSITION0,
float4 WorldPosition: TEXCOORD0,
float3 viewPos : TEXCOORD1,
float3 lightDir : TEXCOORD2)
{
PS_OUTPUT Output;

float3 pos = float3(WorldPosition.x, WorldPosition.y, WorldPosition.z);
Output.RGBColor = float4(1, 1, 1, 0)*(dot(pos - viewPos, lightDir));
return Output;
}


What am I doing wrong?
The color is still interpolated linear between the vertices.
I expected to see something kinda like a bright center getting darker as more as the distance from this center increases...

Share this post


Link to post
Share on other sites
Passing a position through a TEXCOORD works fine, it will be linearly interpolated with perspective projection. Your problem is that you need to normalize your (pos - viewPos) direction vector in the pixel shader, otherwise a dot product won't give you the results you expect. Also you don't need to pass viewPos and lightDir as interpolants...you can just pass them as constants to your pixel shader.

Share this post


Link to post
Share on other sites
Thanks man!! :) :)

This is my shader now:

float4x4 worldViewProj; // World * View * Projection transformation
float3 lightDir; // Light direction
float3 viewPos; // camera position
float4x4 transWorld;

struct VS_OUTPUT
{
float4 Position : POSITION; // vertex position
float4 PixelPos : TEXCOORD0;
};

VS_OUTPUT vertexMain(in float4 vPosition : POSITION0)
{
VS_OUTPUT Output;
Output.Position = mul(vPosition, worldViewProj);
Output.PixelPos = mul(vPosition, transWorld);
return Output;
}

struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};

sampler2D tex0;

PS_OUTPUT pixelMain(float4 Position : POSITION,
float4 PixelPos : TEXCOORD0)
{
PS_OUTPUT Output;

float3 pos = float3(PixelPos.x, PixelPos.y, PixelPos.z);
Output.RGBColor = float4(1, 1, 1, 0)*(dot(normalize(pos - viewPos), lightDir));
return Output;
}



I think this is calculated for each pixel individually now. But when I add the normalize thing:

HLSL pixel shader compilation failed:
(39): warning X4707: texcoord inputs used directly (that is, other than sampling from textures) in shader body in ps_1_1 are always clamped from 0 to 1
(39): error X4532: cannot map expression to pixel shader instruction set[/quote] :(

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!