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.