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.

David

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()
text=shader.getText()

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()
text=shader.getText()

The shader I get is like this:

//Cg
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);
	 l_normal.xyz = mul((float3x3)tpose_view_to_model, vtx_normal.xyz);
	 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, lvec.xyz));
	 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 ?
[/code]

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 render.ls().

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 render.ls()

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
    PandaNode
      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.

discourse.panda3d.org/viewtopic.php?t=5942#34338

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.