Page 1 of 1

Static lighting rotates with geometry

Posted: Tue May 08, 2018 5:30 pm
by matty9
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.

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);
}
 
Vertex shader, simply transforms the vertex position and normal and passes them over to the pixel shader

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;
}
 
Pixel shader, figures out the UV coords and calculates lighting using the static light position passed through.

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);
}
 
Edit: Some more info
  • 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
Am really stuck on this one, what am I doing wrong?

Re: Static lighting rotates with geometry

Posted: Wed May 09, 2018 7:08 pm
by matty9
FYI, I fixed it. I blame it on the tutorials. The shader tutorial passes through the transposed world matrix when I needed the normal world matrix. I now calculate the UV's using the Normal passed through as standard, but for the lighting multiply this normal by the normal world matrix.

https://gyazo.com/1c840c8b580b024314462f11f6cd1b4e :)

Re: Static lighting rotates with geometry

Posted: Wed May 09, 2018 10:13 pm
by Mel
Shading is always tricky, the rule of thumb is to keep everything always on the same space. If you use normal maps, pass every parameter to tangent space, or if you want to stay on view space, transform your normals and your lights into view space.

Re: Static lighting rotates with geometry

Posted: Wed May 09, 2018 10:56 pm
by matty9
Mel wrote:Shading is always tricky, the rule of thumb is to keep everything always on the same space. If you use normal maps, pass every parameter to tangent space, or if you want to stay on view space, transform your normals and your lights into view space.
Thanks for the tip, having trouble at the moment though trying to get atmospheric scattering to work, however I can't debug the HLSL shader through irrlicht. The graphics debugger won't let me capture any frames.