Rendering only parts of the scene

This snippet requires my RenderTarget from https://github.com/tobspr/RenderTarget, just put it into the same folder.

It shows how to only display parts of the scene, using an arbitrary object as mask (In this case a quad).
Looks like this: http://prntscr.com/9xafvh (Quad is animated)

main.py:


from panda3d.core import *
from RenderTarget import RenderTarget

load_prc_file_data("", """
textures-power-2 none
win-size 1600 900
win-fixed-size #t
""")
import direct.directbase.DirectStart


# Just load the scene, nothing special
scene = loader.loadModel("environment")
scene.reparent_to(base.render)
base.disableMouse()
base.camera.set_pos(30, 30, 30)
base.camera.look_at(0, 0, 20)
base.camLens.set_fov(110)

# Render the scene to a FBO
scene_target = RenderTarget("RenderScene")
scene_target.add_color_texture()
scene_target.prepare_scene_render()

# Create a quad which is our background
cm = CardMaker("cm")
cm.set_frame_fullscreen_quad()
cm.set_color(0.2, 0.6, 1.0, 1.0)
cm_n = cm.generate()
cm_np = render2d.attach_new_node(cm_n)

# Create an arbitrary object (in this case a quad) which shows the scene
quad = CardMaker("cm")
quad.set_frame(-2.0, 2.0, 2.0, -2.0)
quad_n = quad.generate()
quad_np = aspect2d.attach_new_node(quad_n)

# Rotate the panda
quad_np.hprScaleInterval(2.0, Vec3(0, 0, 360), Vec3(0.0)).loop()

# Create a super simple vertex shader, which does not really do anything
vshader = """
#version 400
in vec4 p3d_Vertex;
uniform mat4 p3d_ModelViewProjectionMatrix;
void main() {
    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
}
"""

# Create a fragment shader which just displays the texture
fshader = """
#version 400
uniform sampler2D SceneTex;
out vec4 color;
void main() {color = texelFetch(SceneTex, ivec2(gl_FragCoord.xy), 0); }
"""
quad_np.set_shader(Shader.make(Shader.SL_GLSL, vshader, fshader))
quad_np.set_shader_input("SceneTex", scene_target["color"])

base.run()

Cool! The fun thing is that I recently saw a video from the Budget Cuts game (https://www.youtube.com/watch?v=gbp7xX9QPOc) and tough that the ‘‘portal’’ effect looked quite nice.

Out of curiosity, could this effect be achieved with a derivative of this snippet or is there any other way to achieve this effect in panda3D?

Only asking, no (current) intention on working on something like that :stuck_out_tongue:

Good work!

Everything is possible in panda, its just a matter of how much effort it takes :slight_smile:

From what I can see in the video, they are mixing up two different scenes. Basically you would have your main render scene, and you would have a second scene which you render to a FBO. You would then texture your 2D object (in their case, a blue circle) with your second scene to achieve this kind of blending effect.

The snippet currently cannot do that, one would have to extend it with a secondary rendered scene.

You can implement portals using stencils, without render-to-texture. Draw the main scene including the portal disc (which you write to the stencil buffer), and then have a second DisplayRegion layered on top that that renders the other scene, drawing using the stencil test enabled.

Haha ok cool! I am not near good enough with panda3d to try this yet, but that sound like an interesting thing to try eventually!