PDA

View Full Version : Wide-angle view


Brett Lindberg
06-01-2009, 09:22 PM
Is there a smooth way in Vizard to generate a wide view FOV (say, greater than 180 degrees?)

I'm trying to "unwrap" a spherical panoramic view into a quad, but I can't get it right: if I set FOV greater than 90, it messes everything up. I've tried to get around this by compositing four 90-degree views, but there is significant distortion at the boundaries.

What I'd like is a wide, short view (say 4:1, across the top of the window), rendering the a 360 panorama of same scene as the normal main view.

Jeff
06-11-2009, 12:30 PM
Have you gotten any further with this? I'll check with our dev team to see if they have some suggestions.

Brett Lindberg
07-15-2009, 01:13 PM
Haven't gotten it to work yet: trying to make a bunch of very narrow views stuck close together, but this isn't that great a solution, because I want to be able to get coordinates.

farshizzo
07-15-2009, 05:31 PM
You need to render multiple views to a texture and then render the textures to the screen using either an undistortion mesh or shader. There should be examples on the forum for rendering views to a texture.

Brett Lindberg
08-20-2009, 09:05 PM
I hacked my way around and came up with this: draws 40 windows across the top of the window. I could render to texture, and make one window, but would that be a lot better?

import viz
import math

class PanoWindowGroup:
def __init__(self, SubWins=40, windowHeight=0.3, vertFOV=90):


self.numSubWins = SubWins

self.winHeight = windowHeight

self.winFOV = 360.0/self.numSubWins

self.vFOV=vertFOV
self.sizeRat = 1.0/self.numSubWins

self.size = (self.sizeRat, self.winHeight)

self.subWinArr = []

#experimentally derived sub-window FOV ratio:
# self.subWinFOVrat = 4.3015/(pow(self.numSubWins,1.113))

for i in range(self.numSubWins):
scrPos = ((i*self.sizeRat),1.0)
direction = i*self.winFOV-60.0
print "Direction= ", direction
subWin = PanoSubWindow(scrPos, self.size, direction, self.winFOV, self.vFOV, self.subWinFOVrat )
self.subWinArr.append(subWin)


class PanoSubWindow:


def __init__(self, scrPos, sizer, direction, winFOV, vFOV, sWFR, viewPos=[0,0,0]):
print "Inputs: ", "scrPos= ", scrPos, " sizer= ", sizer, "direction= ",direction, "winFOV= ", winFOV, "vFOV= ", vFOV
self.vFOV = vFOV
self.size = sizer
self.subwindow = viz.addWindow(pos=scrPos, size=sizer)
self.subwindow.visible(0, viz.SCREEN)
self.subWinFOVrat = sWFR

self.subview = viz.addView()
self.subview.setPosition(viewPos)

self.subview.setEuler([direction,0,0])
self.subwindow.setView(self.subview)

# self.subwindow.fov(self.vFOV, self.subWinFOVrat)
self.subwindow.fov(self.vFOV, 0.075)

Brett Lindberg
08-29-2009, 01:14 PM
Take 3: how do I render multiple views to one texture?
There's only one example on the forums: http://forum.worldviz.com/showthread.php?t=2003, but that's only for one view.

farshizzo
09-03-2009, 06:05 PM
For each view, you would create a separate render node and render texture. You would then apply all the render textures from each view to a separate texture unit of a quad. Finally, you would apply a fragment shader on the quad that performs the undistortion using the different textures. I can provide some sample code that sets this up if you like, but you would still need to come up with your own shader code that performs the undistortion.

Brett Lindberg
09-03-2009, 07:25 PM
A sample to get started would be great: the shader stuff should be doable.

farshizzo
09-04-2009, 04:57 PM
Here is a sample script. The shader simply averages the image from each pass, you will need to replace that with your own shader code.import viz
viz.go()

FRAG = """
uniform sampler2D Pass1;
uniform sampler2D Pass2;
uniform sampler2D Pass3;
uniform sampler2D Pass4;

void main()
{
vec4 p1 = texture2D(Pass1, gl_TexCoord[0].xy);
vec4 p2 = texture2D(Pass2, gl_TexCoord[0].xy);
vec4 p3 = texture2D(Pass3, gl_TexCoord[0].xy);
vec4 p4 = texture2D(Pass4, gl_TexCoord[0].xy);

//TODO: Combine texture from each pass
gl_FragColor = (p1+p2+p3+p4) * 0.25;
}
"""

def CreateRenderPasses():

renderPass = []
uniforms = []

#Create post render pass that combines all passes
postRenderPass = viz.addRenderNode()
postRenderPass.setHUD(-1,1,-1,1,renderQuad=True)
postRenderPass.setOrder(viz.POST_RENDER,-1)

#Create each pass
for x in range(4):

#Create render texture
renderTexture = viz.addRenderTexture()

#Apply to post render pass
postRenderPass.texture(renderTexture,unit=x)

#Create uniform for texture unit
uniforms.append(viz.addUniformInt('Pass'+str(x+1), x))

#Create render node to render texture
renderNode = viz.addRenderNode()
renderNode.attachTexture(renderTexture)
renderPass.append(renderNode)

#Apply shader
shader = viz.addShader(frag=FRAG,uniforms=uniforms)
postRenderPass.apply(shader)

#Set rotation offset of each render pass
renderPass[0].setEuler(-30,0,0)
renderPass[1].setEuler(-10,0,0)
renderPass[2].setEuler(10,0,0)
renderPass[3].setEuler(30,0,0)

viz.add('gallery.ive')

CreateRenderPasses()