how to implement shadow in artoolkit

In an artoolkit demo, i want to draw virtual model’shadow on the real table on which it stands. i creat a vitual plane to receive shadow, it lay on the real table. but the problem is i want to hide the vitual plane to make the shadow looks like cast on the real table, how can i do that, i try to hide the plane and the shadow gone too. i am using shadow map.

I had the same Problem, check out this thread: discourse.panda3d.org/viewtopic … highlight=

ATM im using:

shadowplane.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MLessEqual))

The problem is, the shadow is not halftransparent with this, but completly black (also you cant use Colored-light or multiple lights, because the shadowplane will be no longer black and white).

The only real solution would be a custom shader as suggested in the mentioned thread… but this is more complicated…

thank you very much, sunday_coder. the blend method is simple but not the truth solution, i search articles about AR shadow, they modified the standar shadow volume or shadow map algorithm, looks very complex for me and i was stuck.

sunday_coder, would u mind show me your customize shader in your last project and how you do the hard-code:)

Well, im realy dont know much about writing shaders, it was mostly trial and error. I took the shader from this thread (discourse.panda3d.org/viewtopic … highlight=) and then modified it further.

So i would not recommend using this shader, because its slow and ugly and… but you asked for it, so here it comes:

shadow.sha:

//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_ambient,
             uniform float4 k_scale,
             uniform float4 k_push,

             out float4 l_position : POSITION,
             out float2 l_texcoord0 : TEXCOORD0,
             out float4 l_shadowcoord : TEXCOORD1,
         out float  l_smooth : TEXCOORD2,
         out float4 l_lightclip : TEXCOORD3
             )

{
float4 position = vtx_position * k_scale;

// vertex position
l_position = mul(mat_modelproj, position);

// Pass through texture coordinate for main texture.
l_texcoord0 = vtx_texcoord0;

// Calculate the surface lighting factor.
l_smooth = saturate(dot(vtx_normal, normalize(mspos_light - position)));

// Calculate light-space clip position.
float4 pushed = position + float4(vtx_normal * k_push, 0);
l_lightclip = mul(trans_model_to_clip_of_light, pushed);

// Calculate shadow-map texture coordinates.
l_shadowcoord = l_lightclip * float4(0.5,0.5,0.5,1.0) + l_lightclip.w * float4(0.5,0.5,0.5,0.0);
}


void fshader(in float2 l_texcoord0 : TEXCOORD0,
             in float4 l_shadowcoord : TEXCOORD1,
             in float  l_smooth : TEXCOORD2,
             in float4 l_lightclip : TEXCOORD3,
             uniform sampler2D tex_0 : TEXUNIT0,
             uniform sampler2D k_Ldepthmap : TEXUNIT1,
             uniform float4 k_ambient,
             uniform float4 k_sonly,
         uniform float4 k_texDisable,
             out float4 o_color:COLOR)
{
 
  
  float4 baseColor = saturate(tex2D(tex_0, l_texcoord0) + k_texDisable);
  float4 proj = l_shadowcoord / l_shadowcoord.w;
  float mapval = tex2D(k_Ldepthmap,proj.xy);
  float shade = (mapval > proj.z);
  if(k_sonly[0]==1){
  o_color = baseColor * (  shade * l_smooth + k_ambient.x );
  }
  else {
  o_color = baseColor*shade;
  o_color[3]=(o_color[3]-0.8)*-1;
  }
}

caster.sha:

//Cg

void vshader(float4 vtx_position : POSITION,
             uniform float4x4 mat_modelproj,
             uniform float4 k_scale,
	     out float4 l_position : POSITION,
             out float4 l_pos : TEXCOORD0
             )
{
  float4 position = vtx_position * k_scale;
  l_pos = mul(mat_modelproj, position);
  l_position = l_pos;
}

void fshader(in float4 l_pos : TEXCOORD0,
             out float4 o_color:COLOR)
{
  float z = (l_pos.z / l_pos.w) * 0.5 + 0.5;
  o_color = float4(z,z,z,1);
}

example:
(have not test this, but it should be everything you need to use the shader(s))

shadowCamMask = BitMask32.bit(0)

#Make shadowplane:
cm=CardMaker('')
cm.setFrame(-25,6.8,-25,25)
splane = render.attachNewNode(PandaNode("splane"))
splaneNode = splane.attachNewNode(cm.generate())
splaneNode.setP(-90)
splane.setColor(1,1,1,0.5)

splane.setShaderInput("texDisable",1,1,1,0.5)
splane.setShaderInput('sonly',0,0,0,0)
splane.reparentTo(self.char1)
splane.hide(shadowCamMask)  
              splane.setTransparency(TransparencyAttrib.MAlpha)     
splane.setBin("fixed", 1)                        
splane.setDepthTest(False)                        


#shadow-camera
winprops = WindowProperties.size(2048,2048)
props = FrameBufferProperties()
props.setRgbColor(1)
props.setAlphaBits(1)
props.setDepthBits(1)
LBuffer = base.graphicsEngine.makeOutput(
base.pipe, "offscreen buffer", -2,
props, winprops,
GraphicsPipe.BFRefuseWindow,
base.win.getGsg(), base.win)
            
                
Ldepthmap = Texture()
LBuffer.addRenderTexture(Ldepthmap, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPDepthStencil)
                               
LCam=base.makeCamera(LBuffer)
LCam.node().setScene(render)
LCam.node().getLens().setFov(40)
LCam.node().getLens().setNearFar(10,100)
                
ambient=0.20
        
cameraSelection = 0
lightSelection = 0
            
render.setShaderInput('light',LCam)
render.setShaderInput('Ldepthmap',Ldepthmap)
        render.setShaderInput('ambient',ambient,0,0,1.0)
render.setShaderInput('sonly',1,1,1,1)
render.setShaderInput('texDisable',0,0,0,0)
render.setShaderInput('scale',1,1,1,1)
render.setShaderInput('push',0.04,0.04,0.04,0)
             render.setShaderInput('alp',0.02,0.02,0.02,0.02)    
                
lci = NodePath(PandaNode("Light Camera Initializer"))
lci.setShader(Shader.load('shader/caster.sha'))
LCam.node().setInitialState(lci.getState())
                 
        self.char.setShader(Shader.load('shader/shadow.sha'))  
splane.setShader(Shader.load('shader/shadow.sha'))   

base.cam.reparentTo(render)
        
LCam.node().hideFrustum()
                
LCam.node().setCameraMask(shadowCamMask)
      
        
        
LCam.setPos(10,-4,0)
LCam.lookAt(0,0,0)
        
        
LCam.node().getLens().setNearFar(10,1000)

hope this works for you too ;D

greetingz!

Oh, I think i should find my cg book, i learned cg long ago but very limited. thank you very much. hope better solution in the future.