Displaying/Projecting a texture with a large FOV

Hey!

I’m a bit stuck and in need of some help.
I work on a script that aims to display a 3d scene on a curved screen to cover a larger FOV.
So far I managed to generate a dynamic cube map, to apply the texture on a screen model of my actual screen and to view it with a camera to validate that it looks realistic when you look around.
Now to display the cube map on the actual screen, I thought that I can either somehow project the applied texture back onto a flat screen which I’ll the display on the curved screen, but since all projections seem to use cameras I’m again limited in the FOV.
I also found the nonlinearimager and its lenses, but it’s unclear to me how to customize the lenses to my needs, as I’m not sure if the fisheye or cylindrical lens will help me.

Any ideas?

Thanks:)

#------------------------------------------------------------------------------
#load configuration .prc file
from panda3d.core import loadPrcFile
loadPrcFile("Config/VR_screen_model_config.prc")

# #load config manager and print config vars
from panda3d.core import ConfigVariableManager
ConfigVariableManager.getGlobalPtr().listVariables()

# import gltf support
import simplepbr

#import panda3d.core stuff
from panda3d.core import *

#import ShowBase
from direct.showbase.ShowBase import ShowBase

# import task, a task is a procedure that is called every frame
from direct.task import Task
#------------------------------------------------------------------------------
#make dictionary to map keys press events to true/false
keyMap = {
    "up": False,
    "down": False,
    "left": False,
    "right": False,
    "rcon": False,
    "zero": False,
    "w": False,
    "s": False,
    "a": False,
    "d": False,
    "e": False,
    "q": False,
    "2": False,
    "1": False
    }

#callback update function
def updateKeyMap(key,state):
    keyMap[key] = state
#------------------------------------------------------------------------------
class VR(ShowBase):
    def __init__(self, cube_size = 2048):
        super().__init__()
  
        simplepbr.init(use_normal_maps=True) 
        
        #load scene
        self.scene = self.loader.loadModel('world.glb')
        self.scene.setScale(10)
        self.scene.reparentTo(self.render)
        
        #adjust camera
        self.camera.setPos(0,-10,0)
        self.camera.setHpr(0,0,0)
        
        #set speed
        self.camera_speed = 0.5
        self.turning_speed = 1.5
        
        #create new window, camera, avatar and renderer for screen display
        win2 = self.openWindow(makeCamera=True)
        render2 = NodePath('render2')
        self.cam2 = self.camList[1]
        self.cam2.reparentTo(render2)
        self.cam2.node().getLens().setNearFar(1/10,1000)
        self.cam2.node().getLens().setFov(70)
        self.cam2.node().showFrustum()
        avatar = self.loader.loadModel('ZF_fov.glb')
        avatar.setHpr(0,-90,0)
        avatar.setScale(0.02)
        avatar.setPos(0,0,0)
        avatar.setColor(0.7,0.3,0.3)
        avatar.reparentTo(self.cam2)
        
        #create new window with overview camera
        win_ov = self.openWindow(makeCamera=True)
        cam_ov = self.camList[2]
        cam_ov.reparentTo(render2)
        cam_ov.setPos(0,0,50)
        cam_ov.lookAt(avatar)
        
        # activate keyboard control
        self.keyboard_control()
        
        #make cube map from win and attach to win2
        self.cube_cams = self.scene.attachNewNode('cube_cams')
        self.cube_cams.setHpr(180,0,0) #rotate cube cams
        self.cube_cams.setPos(0,0,0)
        cube_map_buffer = win2.makeCubeMap('cube_map', cube_size, self.cube_cams)
        [icam.node().getLens().setNearFar(1/10,1000) for icam in self.cube_cams.getChildren()] #adjust near and far clipping distance
        [icam.node().showFrustum() for icam in self.cube_cams.getChildren()]
        
        #load display screen
        self.screen = self.loader.loadModel("curved_screen_model.glb")
        self.screen.setScale(1)
        self.screen.reparentTo(render2) #attach screen to cam2 to render it with render2
        self.screen.setPos(0,5.5,0) #move screen relative to render2
        self.screen.setHpr(-90,0,90)
        
        # display cube_map_buffer.getTexture() on screen
        ts = TextureStage('ts')
        self.screen.setTexGen(ts, TexGenAttrib.MWorldCubeMap)
        self.screen.setTexture(ts,cube_map_buffer.getTexture())
        #self.cam2.lookAt(self.screen)
        
        # Add the move tasks procedure to the task manager.
        self.taskMgr.add(self.move_cam2, "move_cam2")
        self.taskMgr.add(self.move_cube_cams, "move_cc")
    
    def keyboard_control(self):
        
        #create camera control for cam2
        #use build-in keyboard support: self.accept. see doc for key (event) names
        self.accept("arrow_left",updateKeyMap,["left", True])
        self.accept("arrow_right",updateKeyMap,["right", True])
        self.accept("arrow_up",updateKeyMap,["up", True])
        self.accept("arrow_down",updateKeyMap,["down", True])
        self.accept("rcontrol",updateKeyMap,["rcon", True])
        self.accept("0",updateKeyMap,["zero", True])

        #key release events
        self.accept("arrow_left-up",updateKeyMap,["left", False])
        self.accept("arrow_right-up",updateKeyMap,["right", False])
        self.accept("arrow_up-up",updateKeyMap,["up", False])
        self.accept("arrow_down-up",updateKeyMap,["down", False])
        self.accept("rcontrol-up",updateKeyMap,["rcon", False])
        self.accept("0-up",updateKeyMap,["zero", False])
        
        #create camera control for cube cams
        #use build-in keyboard support: self.accept. see doc for key (event) names
        self.accept("a",updateKeyMap,["a", True])
        self.accept("d",updateKeyMap,["d", True])
        self.accept("w",updateKeyMap,["w", True])
        self.accept("s",updateKeyMap,["s", True])
        self.accept("e",updateKeyMap,["e", True])
        self.accept("q",updateKeyMap,["q", True])
        self.accept("2",updateKeyMap,["2", True])
        self.accept("1",updateKeyMap,["1", True])

        #key release events
        self.accept("a-up",updateKeyMap,["a", False])
        self.accept("d-up",updateKeyMap,["d", False])
        self.accept("w-up",updateKeyMap,["w", False])
        self.accept("s-up",updateKeyMap,["s", False])
        self.accept("e-up",updateKeyMap,["e", False])
        self.accept("q-up",updateKeyMap,["q", False])
        self.accept("2-up",updateKeyMap,["2", False])
        self.accept("1-up",updateKeyMap,["1", False])
        
    def move_cam2(self, task):
        
        #get camera position and Hpr
        cam2_pos = self.cam2.getPos()
        cam2_hpr = self.cam2.getHpr()
        
        #update camera based on key pressing
        if keyMap["left"]:
            cam2_pos.x -= self.camera_speed
            
        if keyMap["right"]:
            cam2_pos.x += self.camera_speed
            
        if keyMap["up"]:
            cam2_pos.y += self.camera_speed
            
        if keyMap["down"]:
            cam2_pos.y -= self.camera_speed  
        
        if keyMap["rcon"]:
            cam2_hpr.x += self.turning_speed
            print(cam2_hpr)
            
        if keyMap["zero"]:
            cam2_hpr.x -= self.turning_speed 
            print(cam2_hpr)
            
        #update camera position and Hpr
        self.cam2.setPos(cam2_pos)
        self.cam2.setHpr(cam2_hpr)
        return Task.cont
    
    def move_cube_cams(self,task):
        #get cube cams position and Hpr
        cc_pos = self.cube_cams.getPos()
        cc_hpr = self.cube_cams.getHpr()
        
        #update camera based on key pressing
        if keyMap["a"]:
            cc_pos.x -= self.camera_speed
            
        if keyMap["d"]:
            cc_pos.x += self.camera_speed
            
        if keyMap["w"]:
            cc_pos.y += self.camera_speed
            
        if keyMap["s"]:
            cc_pos.y -= self.camera_speed
            
        if keyMap["2"]:
            cc_pos.z += self.camera_speed  
            
        if keyMap["1"]:
            cc_pos.z -= self.camera_speed 
            
        #-----------------------------------
        
        if keyMap["e"]:
            cc_hpr.x += self.turning_speed
           
            
        if keyMap["q"]:
            cc_hpr.x -= self.turning_speed
            
        #-----------------------------------
        
        #update subjct position and Hpr
        self.cube_cams.setPos(cc_pos)
        self.cube_cams.setHpr(cc_hpr)
        
        return Task.cont
       
#------------------------------------------------------------------------------       
VR_instance = VR() #read out variables with test_instance.variable
VR_instance.run()   
        

Do you know what kind of projection is used for the image?

well so far I’m not using any projections, but simply applying the dynamic cube map texture to the screen model.