Transparent videos

Hi there, following ThomasEgi idea, here is a snippet to get transparent videos in panda, the video for alpha is a red unshaded render of the video for diffuse.

files : http://dl.dropbox.com/u/13388237/Panda3D/alpha_video.zip

main class :

##################################################### 
##             Transparent Videos                  ## 
##################################################### 

# imports 
from panda3d.core import * 
loadPrcFileData('', 'dump-generated-shaders 0') 
loadPrcFileData('', 'compressed-textures 0') 
loadPrcFileData('', 'show-buffers 1') 
loadPrcFileData('', 'basic-shaders-only 1') 
import direct.directbase.DirectStart 

# colors 
GREY = Vec4(.2, .1, .0, .5) 
BLACK = Vec4(0, 0, 0, 1) 
WHITE = Vec4(1, 1, 1, 1) 
# media 
DIFFUSE_VIDEO = "diffuse.avi" 
ALPHA_VIDEO = "alpha.avi" 
MODEL = "sphere" 
# shaders 
VIDEO_SHADER = 'video_compositing.cg' 

class Application(): 

    def __init__(self): 
        
        # master nodes 
        master_scene = render.attachNewNode('scene') 
        master_video = render.attachNewNode('video') 
        master_scene.setPos(0,10,0) 
        master_video.setPos(0,5,0) 
        
        # 3D scene setup 
        model = loader.loadModel(MODEL) 
        model.setPos(0,0,0) 
        model.reparentTo(master_scene) 
        
        # video textures    
        diffuse_video = loader.loadTexture(DIFFUSE_VIDEO) 
        alpha_video = loader.loadTexture(ALPHA_VIDEO) 
               
        # cache video card 
        cm_cache = CardMaker("cache"); 
        cm_cache.setUvRange(alpha_video) 
        card_cache = NodePath(cm_cache.generate()) 
        card_cache.reparentTo(master_video) 
        card_cache.setTexture(diffuse_video) 
        card_cache.setTransparency(True) 
        ts = TextureStage('ts')
        card_cache.setTexture(ts, alpha_video)
        
        # composite video card 
        cm_composite = CardMaker("composite"); 
        cm_composite.setUvRange(alpha_video) 
        card_composite = NodePath(cm_composite.generate()) 
        card_composite.setShader(loader.loadShader(VIDEO_SHADER)) 
        card_composite.setShaderInput("alpha", alpha_video) 
        card_composite.setShaderInput("diffuse", diffuse_video) 
        card_composite.setShaderInput("power", Vec3(2,0.5,0)) 
        card_composite.setTransparency(True) 
        card_composite.reparentTo(master_video) 
        
        # hide unecessary card 
        card_cache.setAlphaScale(0) 
        
        # the 2 cards need to be at the exact same position 
        pos = Vec3(0,0,0) 
        card_cache.setPos(pos) 
        card_composite.setPos(pos) 
        
app = Application() 
run()

shader:

//Cg 

void vshader(in float4 vtx_position : POSITION, 
             uniform float4 texpad_diffuse, 
             float4 vtx_texcoord0: TEXCOORD0, 
             uniform float4x4 mat_modelproj, 
             out float4 l_position : POSITION, 
             out float2 l_texcoord : TEXCOORD0, 
             out float4 l_screenpos : TEXCOORD1) 
{ 
    l_position = mul(mat_modelproj, vtx_position); 
    l_texcoord = vtx_texcoord0; 
    l_screenpos = l_position; 
} 

void fshader(in float2 l_texcoord : TEXCOORD0, 
             in float4 l_screenpos  : TEXCOORD1, 
             uniform sampler2D k_diffuse : TEXUNIT1, 
             uniform sampler2D k_alpha : TEXUNIT2, 
             uniform float3 k_power,
             out float4 o_color : COLOR) 
{ 

    float4 diffuse = tex2D(k_diffuse, l_texcoord); 
    float4 alpha = tex2D(k_alpha, l_texcoord); 

    o_color.xyz = diffuse.xyz; 
    
    alpha.r = alpha.r*k_power.x - k_power.y;
    o_color.a = alpha.r;
 
}

This looks great, nice work.

I’m having trouble with the power input to the shader on the Mac.

    card_composite.setShaderInput("power", Vec3(2.0,0.5,0)) 
TypeError: Arguments must match one of:
setShaderInput(non-const NodePath this, const ShaderInput inp)
setShaderInput(non-const NodePath this, non-const InternalName id)
setShaderInput(non-const NodePath this, string id)
setShaderInput(non-const NodePath this, non-const InternalName id, const Vec4 v)

I can get this to work by hard coding the k_power variables in the shader file.

Also, what did you use to create the different versions of the video?

Thanks!

You’re using an old version of Panda3D. In earlier versions, it has to be Vec4(2.0, 0.5, 0.0, 0.0).