Fog and setShaderAuto

If I use fog with setShaderAuto(), I get the following error:
Shader Generator does not support Fog yet.

How can I mix the fog with other effect that need the default shaders ?

You can perhaps write a custom shader that provides the combination of features you need. The auto-shader generator, after all, is simply generating a shader that you could have written directly.


A workaround would be to let the auto shader generate a shader, grab it, print it out, add your fog code, and then use it as custom shader.

Thank you. Looks like shader is a must learn topic.

Hi pro-rsoft

After I grab the shader:
sg = ShaderGenerator.getDefault()
shader = sg.synthesizeShader(render.getState()).getShader()

Is it usually that I have to modify it case by case ? Or in general I can make a generic fog shader to integrate with generated shader ?

The shader generated by Panda handles many attributes. If I am not going to make a shader generator, does it mean that I have to make very specific shader for my particular requirement (say a uniform Fog).

Uh, yes. Whenever you add a light or so, the shader has to be re-generated.

I grab the shader from the normal mapping tutorial in runtime by:

sg = ShaderGenerator.getDefault()
shader = sg.synthesizeShader(render.getState()).getShader()

The shader I get is like this:

void vshader(
	 in float4 vtx_color : COLOR,
	 out float4 l_color : COLOR,
	 uniform float4x4 trans_model_to_view,
	 uniform float4x4 tpose_view_to_model,
	 in float4 vtx_normal : TEXCOORD0,
	 out float4 l_normal : TEXCOORD1,
	 out float4 l_pos : TEXCOORD0,
	 float4 vtx_position : POSITION,
	 out float4 l_position : POSITION,
	 uniform float4x4 mat_modelproj
) {
	 l_position = mul(mat_modelproj, vtx_position);
	 l_color = vtx_color;
	 l_pos = mul(trans_model_to_view, vtx_position); = mul((float3x3)tpose_view_to_model,;
	 l_normal.w = 0;

void fshader(
	 in float3 l_normal : TEXCOORD1,
	 in float4 l_pos : TEXCOORD0,
	 uniform float4 alight_alight0,
	 uniform float4x4 plight_plight0_rel_view,
	 out float4 o_color : COLOR0,
	 in float4 l_color : COLOR
) {
	 float4 result;
	 // Fetch all textures.
	 // Correct the surface normal for interpolation effects
	 l_normal = normalize(l_normal);
	 // Begin view-space light calculations
	 float ldist,lattenv,langle;
	 float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;
	 float4 tot_ambient = float4(0,0,0,0);
	 float4 tot_diffuse = float4(0,0,0,0);
	 // Ambient Light 0
	 lcolor = alight_alight0;
	 tot_ambient += lcolor;
	 // Point Light 0
	 lcolor = plight_plight0_rel_view[0];
	 lspec  = plight_plight0_rel_view[1];
	 lpoint = plight_plight0_rel_view[2];
	 latten = plight_plight0_rel_view[3];
	 lvec   = lpoint - l_pos;
	 ldist = length(float3(lvec));
	 lvec /= ldist;
	 lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);
	 lcolor *= lattenv * saturate(dot(l_normal,;
	 tot_diffuse += lcolor;
	 // Begin view-space light summation
	 result = float4(0,0,0,0);
	 result += tot_ambient * l_color;
	 result += tot_diffuse * l_color;
	 result = saturate(result);
	 // End view-space light calculations
	 o_color = result * 1.000001;

The shader seems only taking care of the lights but not the texture. Why ?

Maybe because “render” didn’t have any textures applied?

There is only one model under render. If I grab the shader from the abstract room node, the shader program is even short !

Only call it for the actual node which has the texture. You can check which one that is by calling

Hi pro-rsoft,

I’ve made a scene graph navigator and walk through all nodes in the scene graph to grab the auto shader text generated by panda. So far I still not able to get a correct shader from any of the node.
Do you have any small working example ?

Hmm, not really. But there must be some node which has the render state with the generated shader applied.

I do more tests and have some findings and questions:

Do a

PandaNode render S:(CullFaceAttrib LightAttrib RenderModeAttrib RescaleNormalAtt
rib ShaderAttrib)
  PandaNode camera T:m(pos 58.1848 -58.8497 19.8081 hpr 39.6 2.2 0)
    Camera cam (PerspectiveLens)
      PerspectiveLens fov = 39.3201 30
  ModelRoot abstractroom.egg
      GeomNode polySurface2 (3 geoms: TextureAttrib)

I thought that the TextureAttrib shall be at GeomNode polySurface 2. But it is not.
I can get it at that geom node by calling getGeomState(0)

Thus the render state for the auto shader at that geomnode shall be:
geomnodepath.getNetState() + geomnode.getGeomState(0)

Since it is possible for getGeomState return different states for different geoms in this geom node, does it mean that the autoshader will generate a different shader for each geom in that geomnode instead of just one shader for one geomnode ?

Hmm, I think it should be either gnp.getNetState() or gnp.getNetState().compose(gn.getGeomState(n)). I don’t know.

Thank you for your help. It can produce something useful with the new code. Looks like it need to compute the net state for each Geom under each Geom node.