[SOLVED] Shader question


how would this code be translated into panda3d c++ ?

SHADER m_terrainVS.Init(Dev, "shaders/terrain.vs", VERTEX_SHADER);
D3DXHANDLE m_vsDirToSun = m_terrainVS.GetConstant("DirToSun");

I’ve loaded the shader so far like this

PT(Shader) mTerrainVS->load("Shaders/Terrain.vs", Shader::SL_GLSL);

but I haven’t found anything in the manual about getting variables (see GetConstant(…);

anyone knows ?


I use python for panda, but the shader would maybe translate to :

void vshader(uniform float4 vspos_sun) 
  //view space direction of the light
  float4 vs_lightray = vspos_sun;

Send the sun object with :

model.set_shader_input("sun", sun);

EDIT : give more info about your shader; here it is CG code.

Thanks for you suggestion Manou but I’m afraid you miss-understood the problem.

I have done some progress I think… would be nice if one of the developers could confirm if this code is correct :slight_smile:

	PT(Shader) mTerrainPS;
	PT(Shader) mTerrainVS;
	CPT(RenderAttrib) mTerrainRA;

	mTerrainPS->load("Shaders/Terrain.ps", Shader::SL_GLSL);
	mTerrainVS->load("Shaders/Terrain.vs", Shader::SL_GLSL);

	mTerrainRA = ShaderAttrib::make();
	const ShaderAttrib* pTerrainSA = DCAST(ShaderAttrib, mTerrainRA);
	mTerrainRA = pTerrainSA->set_shader_input("matrixWorld", NEED_GET_THIS_MATRIX_SOMEHOW);
	pTerrainSA = DCAST(ShaderAttrib, mTerrainRA);
	mTerrainRA = pTerrainSA->set_shader_input("matrixViewProjection", NEED_GET_THIS_MATRIX_SOMEHOW );
	pTerrainSA = DCAST(ShaderAttrib, mTerrainRA);
	mTerrainRA = pTerrainSA->set_shader_input("DirToSun", mDirToSun);
	pTerrainSA = DCAST(ShaderAttrib, mTerrainRA);
	mTerrainRA = pTerrainSA->set_shader(mTerrainVS);

couple of questions here :

  1. is this code correct ?
  2. can I store the PT(RenderAttrib) for each “variable” ?
  3. What’s the best way to get the 2 matrices that are missing ? (see NEED_GET_THIS_MATRIX_SOMEHOW)

I don’t know if I understand what you are asking clearly enough to answer your questions.

  1. I don’t see any obvious problems in the syntax. Whether it’s “correct” is, of course, a much more abstract question that I cannot answer.

  2. I don’t know what you mean. You can store any PT(RenderAttrib) objects you like. You don’t need a separate one for each shader variable, but I guess you could store them that way if you wanted to.

  3. I don’t know what matrices you are looking for here, so how can I tell you how to get them?


my bad I thought I was clear :slight_smile:

the two matrices I am looking for are :

“matrixWorld” which I usually get as follows in directX :

m_pDevice->SetTransform(D3DTS_WORLD, &world);

and “matrixViewProjection” which I compute like this :

D3DXMATRIX viewProjection = camera.GetViewMatrix() * camera.GetProjectionMatrix();

I was refering to the syntax indeed.
And I wanted to know if it is correct to set all my shader inputs on the same render attribute or if I should store a PT(RenderAttribute) for each shader input variable.

in directx I would usually set the shader variables on each “render” call - but panda hasn’t got a render call as such (so I will be doing it in my “update” loop).

In direct X I would get the handle to those shader variables and just set them through the handle.

hope that is clearer.

You can store them all in the same ShaderAttrib object; that’s the intended way to do it. But you might find it easier to use NodePath::set_shader_input(), which is a higher-level interface, instead constructing a ShaderAttrib laboriously by hand like you are doing.

It looks like you are loading the identity matrix for what you are calling “world”? In Panda, the identity matrix is LMatrix4f::ident_mat().

I guess you are computing the composition of the camera’s net transform and its lens’s projection mat for what you are calling “viewProjection”? Normally, Panda would do this for you; and if you use Cg, you can have Panda automatically compute the transform using the naming convention as described in the manual. Since you are re-using an existing shader, though, you can do something like camera.node()->get_lens()->get_projection_mat() * camera.get_net_transform()->get_mat() for this matrix. You might have to experiment to get precisely the value you are looking for. I can’t tell you precisely what you need to type since what you are doing is very specific to your own application.


okay think that answers most of my questions… one last one.

once I’ve set the “directionToSun” parameter like this

   mTerrainRA = pTerrainSA->set_shader_input("DirToSun", mDirToSun); 
   pTerrainSA = DCAST(ShaderAttrib, mTerrainRA); 

will this now automatically update the “sun parameter” in the shader everytime my mDirToSun is set in my code ?
(mDirToSun is a LVector3f )

or do I need set the shader input parameter each time I want to update its content ?

The value of mDirToSun is copied into the shader attrib, so if it changes in the future you will need to reassign it.