c++ - OpenGL Asymmetric Frustum for Desktop VR -
i making opengl c++ application tracks users location in relation screen , updates rendered scene perspective of user. know "desktop vr" or can think of screen diorama or fish tank. rather new opengl , have defined simple scene far, cube, , rendered correctly.
the problem when start moving , want rerender cube scene, projection plane seems translated , don't see think should. want plane fixed. if writing ray tracer, window fixed, eye allowed wander. can please explain me how can achieve effect desire (pinning viewing window) while having camera/eye wander @ non-origin coordinate?
all of examples find demand camera/eye @ origin, not conceptually convenient me. also, because "fish tank", setting d_near xy-plane, z = 0.
in screen/world space, assign center of screen (0,0,0) , 4 corners to: tl(-44.25, 25, 0) tr( 44.25, 25, 0) br( 44.25,-25, 0) bl(-44.25,-25, 0) these values in cm 16x9 display.
i calculate user's eye (actually web cam on face) using posit somewhere in range of (+/-40, +/-40, 40-250). posit method accurate.
i defining own matrices perspective , viewing transforms , using shaders.
i initialize follows:
float right = 44.25; float left = -44.25; float top = 25.00; float bottom = -25.00; vec3 eye = vec3(0.0, 0.0, 100.0); vec3 view_dir = vec3(0.0, 0.0, -1.0); vec3 = vec3(0.0, 1.0, 0.0); vec3 n = normalize(-view_dir); vec3 u = normalize(cross(up, n)); vec3 v = normalize(cross(n, u)); float d_x = -(dot(eye, u)); float d_y = -(dot(eye, v)); float d_z = -(dot(eye, n)); float d_near = eye.z; float d_far = d_near + 50; // perspective transform matrix mat4 p = mat4((2.0*d_near)/(right-left ), 0, (right+left)/(right-left), 0, 0, (2.0*d_near)/(top-bottom), (top+bottom)/(top-bottom), 0, 0, 0, -(d_far+d_near)/(d_far-d_near), -(2.0*d_far*d_near)/(d_far-d_near), 0, 0, -1.0, 0); // viewing transform matrix mat4 v = mat4(u.x, u.y, u.z, d_x, v.x, v.y, v.z, d_y, n.x, n.y, n.z, d_z, 0.0, 0.0, 0.0, 1.0); mat4 mv = c * v; //mv = v;
from gather looking on web, view_dir , remain fixed. means need update d_near , d_far d_x, d_y, , d_y? in glutidlefunc( idle );
void idle (void) { hbuffer->getframe(hframe); if (hframe->goodh && hframe->timestamp != timestamp) { timestamp = hframe->timestamp; std::cout << "(" << hframe->eye.x << ", " << hframe->eye.y << ", " << hframe->eye.z << ") \n"; eye = vec3(hframe->eye.x, hframe->eye.y, hframe->eye.z); d_near = eye.z; d_far = eye.z + 50; p = mat4((2.0*d_near)/(right-left), 0, (right+left)/(right-left), 0, 0, (2.0*d_near)/(top-bottom), (top+bottom)/(top-bottom), 0, 0, 0, -(d_far+d_near)/(d_far-d_near), -(2.0*d_far*d_near)/(d_far-d_near), 0, 0, -1.0, 0); d_x = -(dot(eye, u)); d_y = -(dot(eye, v)); d_z = -(dot(eye, n)); c = mat4(1.0, 0.0, 0.0, eye.x, 0.0, 1.0, 0.0, eye.y, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); v = mat4(u.x, u.y, u.z, d_x, v.x, v.y, v.z, d_y, n.x, n.y, n.z, d_z, 0.0, 0.0, 0.0, 1.0); mv = c * v; //mv = v; glutpostredisplay(); } }
here shader code:
#version 150 uniform mat4 mv; uniform mat4 p; in vec4 vposition; in vec4 vcolor; out vec4 color; void main() { gl_position = p * mv * vposition; color = vcolor; }
ok, made changes code, without success. when use v in place of mv in vertex shader, looks want to, perspective correct , objects right size, however, scene translated displacement of camera.
when using c , v obtain mv, scene rendered perspective of observer straight on , rendered scene fills window should, perspective of eye/camera lost.
really, want translate 2d pixels, projection plane, appropriate x , y values of eye/camera, keep center of object (whose xy center (0,0)) in center of rendered image. guided examples in textbook "interactive computer graphics: top-down approach shader-based opengl (6th edition)". using files paired book freely available on web, continuing row major approach.
the following images taken when not using matrix c create mv. when use c create mv, scenes first image below. desire no translation in z , leave 0.
because projection plane , camera plane parallel, conversion 1 other coordinate system translation , inv(t) ~ -t.
here image eye @ (0,0,50):
here image eye @ (56,-16,50):
the solution update d_x, d_y, , d_z, accounting new eye position, never change u, v, or n. in addition, 1 must update matrix p new values left, right, top , bottom, relate new position of camera/eye.
i initialize this:
float screen_right = 44.25; float screen_left = -44.25; float screen_top = 25.00; float screen_bottom = -25.00; float screen_front = 0.0; float screen_back = -150;
and idle function looks this, note calculations top, bottom, right, , left:
void idle (void) { hbuffer->getframe(&hframe); if (hframe.goodh && hframe.timestamp != timestamp) { timestamp = hframe.timestamp; //std::cout << "(" << hframe.eye.x << ", " << // hframe.eye.y << ", " << // hframe.eye.z << ") \n"; eye = vec3(hframe.eye.x, hframe.eye.y, hframe.eye.z); d_near = eye.z; d_far = eye.z + abs(screen_back) + 1; float top = screen_top - eye.y; float bottom = top - 2*screen_top; float right = screen_right - eye.x; float left = right - 2*screen_right; p = mat4((2.0 * d_near)/(right - left ), 0.0, (right + left)/(right - left), 0.0, 0.0, (2.0 * d_near)/(top - bottom), (top + bottom)/(top - bottom), 0.0, 0.0, 0.0, -(d_far + d_near)/(d_far - d_near), -(2.0 * d_far * d_near)/(d_far - d_near), 0.0, 0.0, -1.0, 0.0); d_x = -(dot(eye, u)); d_y = -(dot(eye, v)); d_z = -(dot(eye, n)); v = mat4(u.x, u.y, u.z, d_x, v.x, v.y, v.z, d_y, n.x, n.y, n.z, d_z, 0.0, 0.0, 0.0, 1.0); glutpostredisplay(); }
}
this redefinition of perspective matrix keeps rendered image translating. still have camera capture , screen grabbing synchronization issues, able create images following updated in real-time position of user:
Comments
Post a Comment