Shaders: Simple lighting question

I have a model that I load in using loadModel, it has a texture referenced in the egg.

I am trying to write a shader that will handle the ambient and diffuse lighting per pixel.
I have the ambient and diffuse lights that I have defined, but not actually put into the scene because I want the shader to handle all the lighting for me instead of the opengl lighting.

I believe I have some of it correct, but the model renders black, and when I roll around it flickers, as if the texture input I am using is giving me corrupt data or something of the sort. I thought about setting a shader input for the texture manually, like I do with the geoMipTerrain’s splut shader, but since the egg is already referencing and loading in a texture on the model I am not sure what to use.

I am thinking that I somehow need to override the automatic application of the texture somehow, and apply it myself in the shader… but I am unsure as how to go about this.

I don’t understand what you mean here. Once you apply a shader, you completely replace the standard fixed-function pipeline, including light and texture application. It all becomes your responsibility–all of it. There is no automatic application of lights or textures.

So, whether the lights are in the scene graph or not means nothing; your model will be illuminated by the lights if and only if your shader includes code to apply the illumination. Similarly, your model will be textured if and only if your shader includes the code to apply the texture.

Now, it is true that if you apply a texture on the scene graph (because it was loaded from an egg file, for instance), then that texture is then available as a shader input. But whether you actually apply the texture or not is up to you.


I see, so I should be creating the lights and setting them on the nodes that I want to be lit, they will use the FF pipeline until I apply the shader, then it will automagically start using the shader for lighting rather than the FF pipeline. I’ll try that.

As far as I can tell, Panda3d will consolidate the texture stages into the appropriate list of texcoords/samplers for your shaders at runtime. Depending on the priority sorting value of each stage is what texcoord it will actually be assigned to.

When a model is loaded, it generates one or more of its own texture stages, depending on what is defined in the Egg file. If you want to ensure that you are automatically passing those stages in the correct order to your shader, then you can use the sort scalar for the entity.

You can mix and match the FF pipeline and shaders in any manner you want, just as you said. Before I decided to switch over to autoshaders in my current project, I was using FF for most of my rendering, and then overriding it for only the parts I needed.

Ok I still cant seem to get it working correctly, this is what I see

this is what I have for the shader // ignore the positional, I am trying to get dlight to work as well, but I can’t even seem to get it texturing correctly as a first step


void vshader( in float4 vtx_position  : POSITION,
				in float2 vtx_texcoord0 : TEXCOORD0,
				in uniform float4x4 mat_modelproj,
				out float4 l_position  : POSITION,
				out float2 l_texcoord0 : TEXCOORD0)
	 l_position = mul(mat_modelproj,vtx_position);
	 l_texcoord0 = vtx_texcoord0;

void fshader( in float4 l_position  : POSITION,
				in float2 l_texcoord0 : TEXCOORD0,
				in uniform sampler2D k_tex_0 : TEXUNIT0,
				uniform float4 alight_alight0,
				out float4 o_color : COLOR )

	o_color = tex2D(k_tex_0, l_texcoord0.xy) * alight_alight0;

here is what I used to load the model/shader

self.model = Actor("demo_stryker/assets/models/m1126_stryker")
shader = loader.loadShader('demo_stryker/assets/shaders/basic.sha')
self.model.setShader(shader) # 2 steps for debugging
self.model.setShaderInput("alight0", self.parent.att_ambientLight.light)
self.model.setShaderInput("dlight0", self.parent.att_directionalLight.light)

the model has a texture applied (if I dont use the shader, everything is FF and peachy…)
I am not using the AutoShader because this is more of a learning experience at this point, rather than just getting something to work, you know?

Ok, this is about as raw as I can make it, and I see random flickers of whatever was left in the video card just before the texture rendered (the image is but one example of what I see, none of which is any good)

ugh, k_ gets me every time…
so close, but so far away… I remove the k_ in my variable names and bingo, it works.

Now onto directional lighting!