🔒 Locked
🎮 Unity
Lighting direction
Advertisement
Original Post
I've set up a basic shader with a normal map and a directional light. My light is behaving oddly however. Setting its direction to Vector3.Up lights it from where I'd consider Vector3.Backward to be. Vector3.Down results in Vector3.Forward. Vector3.Left and Right seem to work correctly however. I've checked my normal map and the channels are correct. This is how I do the basic lighting: float Light1Amount = dot(Light1Direction, NormalPixel); Colour.rgb = saturate(DiffusePixel.rgb * Light1Amount * Light1Diffuse); Obviously I need to invert or transpose something. Any idea what that should be? I tried doing inverse, transpose and inverse-transpose to my world matrix without any change in results. Perhaps I need to transform the light. Suggestions?
You don't have to use the inverse transpose matrix at all, for basic Phong/Blinn Phong lighting;
- Light Direction Vector
- Surface Normal
- View Vector (for calculating specular reflection
Here's some code that I've been using to render geometry with a simple shadder
And how you might want to implement it (basically, just the variables that I give it before rendering objects);
the eye matrix is used in creating the view matrix, so just make sure that you can access it.
Note, SetValue is a template function I wrote just to make it easier to pass in variables, but no doubt you get what is meant, any questions, please ask =)
EDIT: apologies, I forgot to talk about the light direction. Now, say I pass in this vector for light direction
Then I will get a directional light that is facing straight down the z axis (go into the screen basically). If I changed that vector to
Then it would be a light shinning in your eyes basically, another example, if I were to create a vector like this
Then a light be shone down the x axis, from your right, with the light going left, in other words, the light is going in this direction
<---
and the opposite direction;
would be a light shinning in this direction
--->
- Light Direction Vector
- Surface Normal
- View Vector (for calculating specular reflection
Here's some code that I've been using to render geometry with a simple shadder
//-----------------------------------------------------------------------------// Global varaibles supplied by the app//-----------------------------------------------------------------------------uniform extern float4x4 g_matWorldViewProj;uniform extern float4x4 g_matWorld;uniform extern float4 g_vecLightDirection;uniform extern float3 g_vecEyePosition;uniform extern float4 g_DiffuseLight;uniform extern float4 g_AmbientLight;uniform extern float g_fPhongExponent;uniform extern texture g_tTexture;//-----------------------------------------------------------------------------// Texture samplers//-----------------------------------------------------------------------------sampler2D TextureSampler = sampler_state{ Texture = <g_tTexture>; AddressU = Clamp; AddressV = Clamp; MinFilter = Anisotropic; MagFilter = Linear; MipFilter = Linear;};//-----------------------------------------------------------------------------// Vertex shader output structure//-----------------------------------------------------------------------------struct VS_OUTPUT{ float4 Position : POSITION; float3 LightDirection : TEXCOORD0; float3 Normal : TEXCOORD1; float3 View : TEXCOORD2; float2 TexCoord : TEXCOORD3;};//-----------------------------------------------------------------------------// Vertex Shader : ambient, diffuse and specular light//-----------------------------------------------------------------------------VS_OUTPUT TransformScene(float4 Position : POSITION, float3 Normal : NORMAL){ VS_OUTPUT Out = (VS_OUTPUT)0; Out.Position = mul(Position, g_matWorldViewProj); // Transform Position Out.LightDirection = g_vecLightDirection; // L float3 PosWorld = normalize(mul(Position, g_matWorld)); Out.Normal = normalize(mul(Normal, g_matWorld)); // N Out.View = g_vecEyePosition - PosWorld; // V return Out;}//-----------------------------------------------------------------------------// Pixel Shader//-----------------------------------------------------------------------------float4 BlinnPhong(float3 LightDir : TEXCOORD0, float3 Norm : TEXCOORD1, float3 View : TEXCOORD2) : COLOR{ float3 Normal = normalize(Norm); float3 LightDirection = normalize(LightDir); float3 ViewDirection = normalize(View); float4 diff = saturate(dot(Normal, LightDirection)); // diffuse component // compute self-shadowing term so that the back isn't white float shadow = saturate(4* diff); // R = 2 * (N.L) * N - L float3 reflect = normalize(2 * diff * Normal - LightDirection); float4 specular = pow(saturate(dot(reflect, ViewDirection)), g_fPhongExponent); // R.V^n // I = Ambient Colour + Diffuse Colour * N.L + (R.V)n return g_AmbientLight + shadow * (g_DiffuseLight * diff + specular);}And how you might want to implement it (basically, just the variables that I give it before rendering objects);
// Pass the mWorldViewProj matrix to the effect hr = SetEffectValue(mWorldViewProj, "g_matWorldViewProj", g_pBlinnPhong); if(FAILED(hr)) return hr; // Pass the g_mWorld matrix to the effect hr = SetEffectValue(g_mWorld, "g_matWorld", g_pBlinnPhong); if(FAILED(hr)) return hr; // Pass the eye position vector to the effect hr = SetEffectValue(g_vEye, "g_vecEyePosition", g_pBlinnPhong); if(FAILED(hr)) return hr; // Pass in ambient material D3DXHANDLE hAmbientLight = g_pBlinnPhong->GetParameterByName(0, "g_AmbientLight"); hr = g_pBlinnPhong->SetValue(hAmbientLight, &matRedPlastic.Ambient, sizeof(D3DXCOLOR)); if (FAILED(hr)) return hr; // Pass in diffuse material D3DXHANDLE hDiffuseLight = g_pBlinnPhong->GetParameterByName(0, "g_DiffuseLight"); hr = g_pBlinnPhong->SetValue(hDiffuseLight, &matRedPlastic.Diffuse, sizeof(D3DXCOLOR)); if(FAILED(hr)) return hr; // Pass in specular power D3DXHANDLE hPhongExponent = g_pBlinnPhong->GetParameterByName(0, "g_fPhongExponent"); hr = g_pBlinnPhong->SetFloat(hPhongExponent, matRedPlastic.PhongExponent); if(FAILED(hr)) return hr;the eye matrix is used in creating the view matrix, so just make sure that you can access it.
Note, SetValue is a template function I wrote just to make it easier to pass in variables, but no doubt you get what is meant, any questions, please ask =)
EDIT: apologies, I forgot to talk about the light direction. Now, say I pass in this vector for light direction
D3DXVECTOR4 g_LightDirection = D3DXVECTOR4(0.0f, 0.0f, -1.0f, 1.0f);Then I will get a directional light that is facing straight down the z axis (go into the screen basically). If I changed that vector to
D3DXVECTOR4 g_LightDirection = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);Then it would be a light shinning in your eyes basically, another example, if I were to create a vector like this
D3DXVECTOR4 g_LightDirection = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);Then a light be shone down the x axis, from your right, with the light going left, in other words, the light is going in this direction
<---
and the opposite direction;
D3DXVECTOR4 g_LightDirection = D3DXVECTOR4(-1.0f, 0.0f, 0.0f, 1.0f);would be a light shinning in this direction
--->
While I'm at it, I'll provide a couple more complex lighting examples, so far I've only shown you directions that are on one of the 3 axis going in one of two ways, but let's say we had a more complex direction, like this;
Now we have the Y axis as well as the z axis in our direction, now, as you may remember, -1.0 on the z axis was directly down the line away from us, and 1.0 on the y axis would be a line straight down, now if we mix the two we would get a light going directly down the x axis, but 45 degrees upwards, so from a side on view it would go down diagonally.
not particularly good examples I know, but I hope that helps with your light direction vector problems.
D3DXVECTOR4 g_LightDirection = D3DXVECTOR4(0.0f, 1.0f, -1.0f, 1.0f);Now we have the Y axis as well as the z axis in our direction, now, as you may remember, -1.0 on the z axis was directly down the line away from us, and 1.0 on the y axis would be a line straight down, now if we mix the two we would get a light going directly down the x axis, but 45 degrees upwards, so from a side on view it would go down diagonally.
not particularly good examples I know, but I hope that helps with your light direction vector problems.
XNA has keywords for various directions that I've been using. Vector3.Forward is the same as Vector(0, 0, 1), Vector3.Up is the same as Vector3(0, 1, 0). I usually combine two or more present directions to get the lights I want. They work great with BasicEffect, hence why I assumed I missed a transformation.
The answer is probably hidden in your code, I've been fumbling my way through the lighting process so I'll get my head around what you've done. Cheers! :)
The answer is probably hidden in your code, I've been fumbling my way through the lighting process so I'll get my head around what you've done. Cheers! :)
"Vector3.Forward is the same as Vector(0, 0, 1), Vector3.Up is the same as Vector3(0, 1, 0)", this seems almost dangerous to use, you should really explicitly declare the direction of a particular vector as it is entirely dependent on how you have set up your graphics system, forward, up, left, right or whatever, it's all heavily abstracted, and yes, 0, 0, 1 is usually considered the up vector (but not always and never forced to), but waying that 0,1,0 is forward seems a complete waste of time to me, what if you are facing the behind face (-z) of a cube map, or even slightly rotated around a point? 0,1,0 is no longer your view vector, and I doubt that for most of the time your application is running will it be that either, you need to get the look at vector from your view matrix to actually provide the correct vector, simply passing 0,1,0 will only give you correct lighting in the rare case that you are infact facing 0,1,0.
Quote:
Original post by leet bix
In XNA Vector.Up is Vector3(0,1,0) and that's all there is to it. No room for argument, really. Why anyone using XNA would choose a coordinate system where Vector3(0,0,1) was up (for example) then use the alias Vector3.Up is beyond me. The only situation where it would matter is if Z is the vertical axis in HLSL. Is this the case?
The question remains as to what internal transformations are performed in BasicEffect. It's actually reversed, light vectors indicate the direction the infinite light is pointing while most custom effects have a vector that points to the source, but either situation would be more acceptable.
There is most certainly room to argue, in both DirectX and XNA, up is an arbitrary direction that is defined by you, the programmer, it's most likely they only added this try and form some kind of standard OR to make XNA a little easier on programmers so they don't have to worry about as much of the math behind vector's and matricies.
Quote:
Original post by leet bix
There is most certainly room to argue, in both DirectX and XNA, up is an arbitrary direction that is defined by you, the programmer, it's most likely they only added this try and form some kind of standard OR to make XNA a little easier on programmers so they don't have to worry about as much of the math behind vector's and matricies.
Seriously, what is your point? You've disrupted a discussion on transformations to spout some basic rubbish about coordinate systems without saying anything meaningful. This is not what I'm trying to achieve in this thread.
Hi,
For one thing doesn't the light direction need a minus sign in front of it. I mean if it really is the direction of the light it usually is in the opposite direction of the object you see.
Object
|
|
|---> Normal <---- Light
|
Could you show the coordinates from the object itself (I assume you started with something simple like 1 or 2 triangles.
For one thing doesn't the light direction need a minus sign in front of it. I mean if it really is the direction of the light it usually is in the opposite direction of the object you see.
Object
|
|
|---> Normal <---- Light
|
Could you show the coordinates from the object itself (I assume you started with something simple like 1 or 2 triangles.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement