fade from one camera to another?

Hello everyone, I’m wondering what is the fastest way to fade from one camera view to another. It’s not simply fading from the last frame of the first camera to another camera, both cameras should continue rendering during the transition.

If you really want to do a cross-fade, you’ll probably have to render at least one of the cameras offscreen to a card, and apply the card to the main window, and gradually fade the transparency on the card.

You could also try fading the whole scene out, but this is likely to cause problems with transparency within the scene.

David

I’m not sure what’s the cheapest way. Should I get a texture from a camera each frame and assign it to a plane? Do I need to createa display region? How do I say the display region shouldn’t render on-screen? How do I make the plane render on top of the 3d scene, but behind the GUI? How to handle the aspect ratio?
I’m really not sure how this is done.

I’m currently experimenting with buffers & cameras setup in my deferred shading system.

Here is a quick setup for your camera fading in & out.

Here is what it does:

  • deactivate main camera rendering,
  • create 2 offscreens buffers with their respective camera and mask,
  • create a fullscreen quad and apply a compositing shader to it,
  • make the transition in the shader.

The variables could get better names, like frontCameraBuffer & sideCameraBuffer instead of cube_buffer & sphere_buffer, depending on your application.

The fading is made in the shader here, with lerp function. With this you can easily do blend fading, or fade to black, or fade to white transitions.

Could make a snippet out of it with transitions a la Starwars for example :smiley:

main.py

#######################################
### Cameras transitions quick setup ###
### 24/12/11                        ###
#######################################

from panda3d.core import *
loadPrcFileData('', 'show-buffers 1')
from math import pi,sin,cos
import random
import direct.directbase.DirectStart

class World():

    def __init__(self):
        
        # reinitialize display
        render.setState(RenderState.makeEmpty())
        base.cam.node().setActive(0)
        
        # master nodes
        NP_spheres = render.attachNewNode("spheres")
        NP_cubes = render.attachNewNode("cubes")
        
        # models
        cube = loader.loadModel('cube')
        sphere = loader.loadModel('sphere4')
        cube.reparentTo(NP_cubes)
        sphere.reparentTo(NP_spheres)
        
        # buffers creation
        sphere_buffer = self.make_FBO("sphere buffer",1)
        cube_buffer = self.make_FBO("cube buffer",2)
        
        # set buffers clear colors
        sphere_buffer.setClearColorActive(1)
        sphere_buffer.setClearDepthActive(1)
        sphere_buffer.setClearColor(Vec4(0,0,0,1))
        cube_buffer.setClearColorActive(1)
        cube_buffer.setClearDepthActive(1)
        cube_buffer.setClearColor(Vec4(0,0,0,1))

        # render textures creation
        sphere_map = Texture()
        cube_map = Texture()
        sphere_buffer.addRenderTexture(sphere_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
        cube_buffer.addRenderTexture(cube_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
       
        # cameras creation
        sphere_cam = base.makeCamera(sphere_buffer)
        cube_cam = base.makeCamera(cube_buffer)

        # cameras masks
        sphere_mask = BitMask32(1)
        cube_mask = BitMask32(2)     
        cube_cam.node().setCameraMask(cube_mask)
        sphere_cam.node().setCameraMask(sphere_mask)
        NP_spheres.hide(cube_mask)
        NP_cubes.hide(sphere_mask)
        
        # 2D fullscreen quad creation
        card = CardMaker('compositing quad')
        card.setFrameFullscreenQuad()
        quad = render2d.attachNewNode(card.generate())
        # fade pass
        quad.setShader(loader.loadShader("fade.cg"))
        quad.setShaderInput("color1", sphere_map)
        quad.setShaderInput("color2", cube_map)
        
        self.quad = quad
        
        taskMgr.add(self.update,"update")
    
    def update(self, task):
        
        # transition parameters
        time = task.time
        fade_power = cos(task.time)
        other_param = 1
        
        # send parameters to shader each frame
        self.quad.setShaderInput("params", Vec3(time, fade_power, other_param))
        
        return task.cont
        
    def make_FBO(self, name, auxrgba):
        winprops = WindowProperties.size(base.win.getXSize(),base.win.getYSize())
        props = FrameBufferProperties()
        props.setRgbColor(1)
        props.setAlphaBits(1)
        props.setDepthBits(1)
        props.setAuxRgba(auxrgba)
        return base.graphicsEngine.makeOutput(
             base.pipe, name, -2,
             props, winprops,
             GraphicsPipe.BFSizeTrackHost | GraphicsPipe.BFCanBindEvery | 
             GraphicsPipe.BFRttCumulative | GraphicsPipe.BFRefuseWindow,
             base.win.getGsg(), base.win)
    
app = World()
run()

fade.cg

//Cg

void vshader(float4 vtx_position : POSITION,
             out float4 l_position : POSITION,
             out float2 l_texcoord : TEXCOORD0,
             uniform float4 texpad_color1,
             uniform float4x4 mat_modelproj)
{
    l_position = mul(mat_modelproj, vtx_position);
    l_texcoord = (vtx_position.xz * texpad_color1.xy) + texpad_color1.xy;
}

void fshader(float2 l_texcoord : TEXCOORD0,
             uniform sampler2D k_color1 : TEXUNIT0,
             uniform sampler2D k_color2 : TEXUNIT1,
             uniform float3 k_params,
             out float4 o_color : COLOR)
{


    float4 color1 = tex2D(k_color1, l_texcoord);
    float4 color2 = tex2D(k_color2, l_texcoord);
    
    float power = k_params.y;

    o_color = lerp(color1, color2, power);
}

Hey nice sample, however I’d prefer a non shader solution, also your snippet seems to ignore aspect ratio and I need to fade from one camera to another which both render the same scene.

Hi, I made my solution to this problem today and posted it in the code snippits section of the forums

find it here: [url]Fade from one camera to another]

There are no shader’s used, and it completely cleans up after itself (so it’s safe to use hundreds of times without any problems or performance leaks)

It’s relatively simple too, and could be modified to fit specific needs (showing a different scene for instance and fading into that instead of just into a new camera perspective)

Anywho, I hope it’s of use to you, I mostly wrote it for you because I thought it was a curios idea :laughing:
~powerpup118