I am newcomer to Panda 3D but a long time Python and game programmer. My experiences with panda so far have been great
I do however have a question. I am using a GeoMipTerrain and I am using a pixel shader to do some texture splatting, I then tried to add vertex lighting for an ambient and directional light however I am having no luck. Everything runs however I am not seeing the terrain lit like I would expect from the directional light i.e. it is all the same lighting intensity.
If I turn my shader off and use the built in lighting then everything looks like I would expect (just without texture splatting of course). It appears to me that I am getting incorrect normals from the terrain, I was just wondering whether this can be ruled out as a problem or not?
On a side note I was wondering whether people mainly use lightmaps or realtime lighting for terrains?
Yeah I understand that once I write a custom shader that I need to handle lighting calculations myself. That is what I thought I was doing in the shader below as well as doing my texture splatting with 3 textures and the alpha maps packed into the rgb channels of 1 texture.
//Cg
//Cg profile arbvp1 arbfp1
void vshader(in float4 vtx_position : POSITION,
in float3 vtx_normal : NORMAL,
in float2 vtx_texcoord0 : TEXCOORD0,
in uniform float4x4 mat_modelproj,
in uniform float4x4 trans_model_to_world,
in uniform float4 k_lightvec,
in uniform float4 k_lightcolor,
in uniform float4 k_ambientlight,
out float l_brightness,
out float2 l_texcoord0 : TEXCOORD0,
out float4 l_position : POSITION)
{
l_position = mul(mat_modelproj, vtx_position);
l_texcoord0 = vtx_texcoord0;
// lighting
float3 N = normalize(vtx_normal);
float3 L = normalize(k_lightvec.xyz);
l_brightness = (max(dot(-N, L), 0.0f)* k_lightcolor) + k_ambientlight;
}
void fshader( in float4 l_position : POSITION,
in float2 l_texcoord0 : TEXCOORD0,
in float l_brightness,
in uniform sampler2D tex_0 : TEXUNIT0,
in uniform sampler2D tex_1 : TEXUNIT1,
in uniform sampler2D tex_2 : TEXUNIT2,
in uniform sampler2D tex_3 : TEXUNIT3,
out float4 o_color : COLOR )
{
float4 texelColor0 = tex2D(tex_0, l_texcoord0 * 35.0);
float4 texelColor1 = tex2D(tex_1, l_texcoord0 * 35.0);
float4 texelColor2 = tex2D(tex_2, l_texcoord0 * 35.0);
float4 blendColor = tex2D(tex_3, l_texcoord0);
o_color = (texelColor0 * blendColor.x) + (texelColor1 * blendColor.y) + (texelColor2 * blendColor.z);
o_color = texelColor0 * l_brightness;
o_color.a = 1.0;
}
Provided I supply the correct shader inputs, do you see any reason why this shader is not working for a GeoMipTerrain?
Hmm, looks right at first glance. You could try isolating the problem by first checking if the normal is correct (by setting the normal vector as o_color), if that is correct, check k_lightvec, then the dot product by outputting them as color. Then you’ll be able to isolate the problem.
I output the normal vector as a color and it is constant blue for a terrain with a big hill in the middle.
Are the normals supposed to get scaled when you do a terrain_node.setSz()?
If not how could I go about getting correct normals?
All right, here’s the problem. vtx_normal just copies the raw vertex normal from the model - so this is not scaled along with the terrain.
You can fix this by transforming the normals yourself in the shader.