Static lighting rotates with geometry
Posted: Tue May 08, 2018 5:30 pm
So firstly, this doesn't happen when I use shaders, it works as intended if I add a light scene node then enable lighting on my nodes. However, when I disable lighting and use my own shader the light moves with the planet.
Video: https://gyazo.com/a007cc2088c1a21e353d1bde49c1669a
The code to set my constants is below, and the light position here is hard coded so cannot move with anything.
Vertex shader, simply transforms the vertex position and normal and passes them over to the pixel shader
Pixel shader, figures out the UV coords and calculates lighting using the static light position passed through.
Edit: Some more info
Video: https://gyazo.com/a007cc2088c1a21e353d1bde49c1669a
The code to set my constants is below, and the light position here is hard coded so cannot move with anything.
Code: Select all
void TerrainShader::OnSetConstants(IMaterialRendererServices *services, s32 userData) {
IVideoDriver *driver = services->getVideoDriver();
matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
vector3df lightPos = vector3df(-500.0f, 0.0f, -500.0f);
video::SColorf col(1.0f, 1.0f, 1.0f, 0.0f);
matrix4 world = driver->getTransform(video::ETS_WORLD);
world = world.getTransposed();
services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
services->setVertexShaderConstant("mWorld", world.pointer(), 16);
services->setPixelShaderConstant("mLightPos", reinterpret_cast<f32*>(&lightPos), 3);
services->setPixelShaderConstant("mLightColour", reinterpret_cast<f32*>(&col), 4);
}
Code: Select all
float4x4 mWorldViewProj;
float4x4 mWorld;
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float3 WorldPos : TEXCOORD0;
float3 Normal : NORMAL;
};
struct VS_INPUT {
float4 vPosition : POSITION;
float3 vNormal : NORMAL;
};
VS_OUTPUT main(VS_INPUT v_in) {
VS_OUTPUT Output;
Output.Position = mul(v_in.vPosition, mWorldViewProj);
Output.WorldPos = mul(v_in.vPosition, mWorld);
Output.Normal = normalize(mul(v_in.vNormal, mWorld));
return Output;
}
Code: Select all
float3 mLightPos;
float4 mLightColour;
struct VS_OUTPUT {
float4 Position : SV_POSITION;
float3 WorldPos : NORMAL; // HLSL 3.0 pixel shaders don't support POSITION semantic
float3 Normal : NORMAL;
};
static const float PI = 3.14159265f;
sampler2D tex0;
float4 main(VS_OUTPUT v) : SV_Target {
float2 tex;
tex.x = 0.5f + (atan2(v.Normal.z, v.Normal.x) / (2.0f * PI));
tex.y = 0.5f - (asin(v.Normal.y) / PI);
float3 lightDir = normalize(mLightPos - v.WorldPos);
float3 diffuse = mLightColour * saturate(dot(v.Normal, lightDir));
return tex2D(tex0, tex) * float4(diffuse, 1.0f);
}
- I'm using custom meshes using SMeshBuffers
- Planet is rendered using Quadtree's for the LOD
- Each quadtree has it's own scene node, so I rotate the top level scene node only and the rest follow