strange texture merge using shadow map/proj texturing

I am trying to use Shadow mapping (from this thread) and I have strange texture lookup problem.

Basically, the displayed textured are not what they should be.
Note that I am no shader expert, but It looked quite solid. I am puzzled.
Ideas are welcome.

Here follows screenshots with and without the shader.

First the python code :

class CameraShadow(CameraQuake):
    def __init__(self, *args, **kw):
        CameraQuake.__init__(self, *args, **kw)
        self.firsttime = True

    def start(self):
        if self.firsttime :
            self.firstactivation()
            self.firsttime = False
        #==
        CameraQuake.start(self)
        self.activate_shader()

    def stop(self):
        CameraQuake.stop(self)
        self.deactivate_shader()

    def firstactivation(self):
        self.cutout = CutoutMgr()
        # creating dummy nodes to hold the light
        spotDum=render.attachNewNode('spot')
        spotholder=spotDum.attachNewNode('holder')
        spotholder.setPos(100,100,100)
        spotholder.lookAt(0,0,0)
        
        mapsize=1024   # depth map size
        mapscale=1.0/mapsize;
        self.Ldepthmap = Texture()
        # IMPORTANT !
        self.Ldepthmap.setFormat(Texture.FDepthComponent)  # to store depth value instead of color
        self.Ldepthmap.setMinfilter(Texture.FTShadow)      # to use OpenGL SGIX_shadow extension
        self.Ldepthmap.setMagfilter(Texture.FTShadow)
        LBuffer=base.win.makeTextureBuffer('depthmap', mapsize, mapsize,self.Ldepthmap)
        self.LCam=base.makeCamera(LBuffer)
        self.LCam.reparentTo(spotholder)
        self.LCam.node().setScene(render)
#        self.LCam.node().getLens().setFov(40)
#        self.LCam.node().getLens().setNearFar(.1,1000)
        self.LCam.node().showFrustum()
        ratio = 4/3.0
        size = 2
#        self.ortho_lens = OrthographicLens()
#        self.ortho_lens.setFilmSize(size*ratio,size)
#        self.LCam.node().setLens(self.ortho_lens)
        # WARNING !  scale the camera accordingly to match your scene size
        self.LCam.setScale(8)

        # default values
        self.lightIntensity=1.8
        self.Xoffset=0.0009765
        self.Yoffset=0.0009765
        self.Doffset=-0.0000239
        # set the shadow weight according to the light intensity, change the contrast here
        self.shadowWeight=.25

    def deactivate_shader(self):
        render.clearShader()

    def activate_shader(self):
        if not self.shaderSupport():
            OnscreenText(text = 'Shadow does not supported by your graphics hardware.', fg=(1,1,1,1),scale=.1)
            return
        #==
        self.base.setFrameRateMeter(1)# pour voir les fps

        # shader setup
        shadowshader = Shader.load('HW shadow 2Lights_mine.sha')
        render.setShader(shadowshader)
        render.setShaderInput('light',self.LCam)
        render.setShaderInput('Ldepthmap',self.Ldepthmap)
        render.setShaderInput('cutout',self.cutout.images[0])
        render.setShaderInput('offset',Vec4(self.Xoffset,self.Yoffset,self.Doffset,0))
        render.setShaderInput('lightIntensity',Vec4(self.lightIntensity,0,0,0))
        render.setShaderInput('shadowWeight',Vec4(self.lightIntensity*self.shadowWeight,0,0,0))
        render.setShaderInput('texScale',Vec4(1,1,0,0))
        RGB = changelight(self.lightIntensity)
        lightcolor=Vec4(*RGB)
        render.setShaderInput('lightcolor',lightcolor)

    def shaderSupport(self):
        return self.base.win.getGsg().getSupportsDepthTexture() and self.base.win.getGsg().getSupportsShadowFilter()

And the Shader :

//Cg



void vshader(float4 vtx_position : POSITION,
             float2 vtx_texcoord0: TEXCOORD0,
             float3 vtx_normal: NORMAL,
             uniform float4x4 trans_model_to_clip_of_light,
             uniform float4x4 mat_modelproj,
             uniform float4 mspos_light,
             uniform float4 k_offset,
             uniform float4 k_lightIntensity,
             uniform float4 k_shadowWeight,
             uniform float4 k_texScale,
             out float4 l_position : POSITION,
             out float2 l_texcoord0 : TEXCOORD0,
             out float4 l_texcoord1 : TEXCOORD1,
             out float l_downScaledSmooth,
             out float l_side_Self_Shadowing_Artifact_Removal
             )
{
float4x4 scaleBiasMatrix = {
0.5f,0.0f,0.0f, .5+k_offset.x,
0.0f,0.5f,0.0f, .5+k_offset.y,
0.0f,0.0f,0.5f, .5+k_offset.z,
0.0f,0.0f,0.0f, 1.0f};
// vertex position
l_position = mul(mat_modelproj, vtx_position);
// transformation to the light's clip space
float4x4 textureMat = mul(scaleBiasMatrix, trans_model_to_clip_of_light);
// apply texture transform on particular nodes, if changed on-the-fly
l_texcoord0 = vtx_texcoord0*k_texScale.xy;
l_texcoord1 = mul(textureMat, vtx_position);
/*  ------preserving smooth shading---------
 smooth = (vtx normal) dot (vector from vertex to the light) */
float smooth = dot(vtx_normal, normalize(mspos_light - vtx_position));
/*  scale down the smooth shading result and add shadowWeight,
to maintain visual rasionality against the lightweight shadows */
l_downScaledSmooth = (k_shadowWeight.x + (k_lightIntensity.x-k_shadowWeight.x)*.5*(smooth+1.0));
// uncomment the next line and comment the next one to see the difference
//l_side_Self_Shadowing_Artifact_Removal=smooth;
l_side_Self_Shadowing_Artifact_Removal = abs(smooth)*(smooth+.2);  // however, this is experimental, but the result is quite acceptable to cover self-shadowing artifact on objects' side
}

void fshader(float2 l_texcoord0 : TEXCOORD0,
             float4 l_texcoord1 : TEXCOORD1,
             in float l_downScaledSmooth,
             in float l_side_Self_Shadowing_Artifact_Removal,
             uniform sampler2D tex_0 : TEXUNIT0,
             uniform sampler2D k_Ldepthmap,
             uniform sampler2D k_cutout,
             uniform float4 k_shadowWeight,
             uniform float4 k_lightcolor,
             out float4 o_color:COLOR)
{
float4 baseColor = tex2D(tex_0, l_texcoord0)* l_downScaledSmooth;
// perspective divide, or switch from 4D to 3D
float3 shadowUV = l_texcoord1.xyz / l_texcoord1.w;
// only apply shadow & light inside light's frustum --> UV ranges 0..1
if(shadowUV.x>0.0  &&  shadowUV.x<1.0  &&  shadowUV.y>0.0  &&  shadowUV.y<1.0)
    {
    float4 cutout=tex2D(k_cutout,shadowUV)*k_lightcolor;    //// the light texture
    // hardware depth compare 
    // float shade = tex2Dproj(k_Ldepthmap, l_texcoord1);//shadowUV.xy);
    float shade = tex2D(k_Ldepthmap,shadowUV.xy);
    // if shade=0 (fully shadowed), shadowWeight is added to achieve lightweight shadows,
    // or else it would end up purely black 
    o_color.rgb = baseColor.rgb * ( cutout*shade*l_side_Self_Shadowing_Artifact_Removal + k_shadowWeight.x );
    }
// outside the light's frustum
else
    o_color.rgb = baseColor.rgb * k_shadowWeight.x;
// preserving textures' alpha channel
o_color.a =  baseColor.a;

this is due with texture stages. Panda does only switches the 1st texture stage if you have 2 texture stage on the model this happens:
model1:
stage1: texA
stage2: texB

(only stage1 cleard)
model2:
stage1: non color only
stage2: texB

this is realy odd if you have it switch render order on you and the second texture flickers like crazy flipping between stuff that is next to it.

The shader there is designed to work on textured models. It simply won’t work on a model that doesn’t have a texture — you can see right in the code for the shader that it expects a texture to be passed in. If you try to use this shader on an untextured model, it seems that it “finds” a texture somewhere and applies it. That’s kinda weird behavior, but there’s not much the shader can do - it was written to apply a texture.

I see. But is there any ways to correct the shader ?
Is it possible to test whether the texture (stage) is set or not ?
Is there a null value for texture or color ?

check out the shipped Josh’s shadow shader tutorial. He uses a shader input to mark the node which doesn’t have texture (the teapot).

I wouldn’t use that method. Instead, I would just texture everything. If a model doesn’t need a texture, then texture it anyhow, with a texture that’s just a colored square.

Thanks you for your answers, i am a bit farther but not yet arrived.

For now,I use the “trick” used in the shadow sample. a (shader) parameter named texDisable which is set to 1 for mesh that don’t have any texture.

The problem originally presented is gone.

But some mesh don’t have texture everywhere. Some of their vertices have only color information, the rest of them having texture info.
And I don’t see how to shade/manage this kind of mesh .
Maybe parsing the eggs and looking for the color info ? but then what ?

(Note that, for many reasons I cannot correct the meshes themselves).
( and yes, it’s a shame, that would be easier)