math - Projection theory? (Implimented in GLSL) -



math - Projection theory? (Implimented in GLSL) -

opengl 3.x, because dont want to far behind in tech.

first of all, yes know it's lot. vec3 transform(vec3) function fine, if nil else know does'nt contain problem i'm coming here for.

the bit of code i'm having problems (or should be) in vec3 project(vec3) function. if i'm looking straight at, say, box, looks fine. if turn photographic camera bit box closer side of screen (periferal vision), happy box start's becoming rectangle. while live game i'm putting into, it's annoying.

the basic theory behind projection is: have point (x, y, z), find angles between , origin (where photographic camera is) , project plane nearz distance out. finding angles matter of anglex = atan(x/z) , angley = atan(y/z). , using 2 angles, project them onto near plane doing point = tan(angle) * nearz. find outer ridge of screen edgey = tan(fovy) * nearz , edgex = tan(fovy * aspect) * nearz. finding screen point using screen = point/edge

as basic optimization had, removed in effort prepare take screen = angle/fov

anything wrong theory of projection function? here's implimentation:

#version 330 uniform vec3 model_location = vec3(0.0, 0.0, 0.0); uniform vec3 model_rotation = vec3(0.0, 0.0, 0.0); uniform vec3 model_scale = vec3(1.0, 1.0, 1.0); uniform vec3 camera_location = vec3(0.0, 0.0, 0.0); uniform vec3 camera_rotation = vec3(0.0, 0.0, 0.0); uniform vec3 camera_scale = vec3(1.0, 1.0, 1.0); uniform float fovy = 60.0; uniform float nearz = 0.01; uniform float farz = 1000.0; uniform float aspect = 1.0; vec3 transform(vec3 point) { vec3 translate = model_location - camera_location; vec3 rotate = radians(model_rotation); vec3 scale = model_scale / camera_scale; vec3 s = vec3(sin(rotate.x), sin(rotate.y), sin(rotate.z)); vec3 c = vec3(cos(rotate.x), cos(rotate.y), cos(rotate.z)); float sy_cz = s.y * c.z; float sy_sz = s.y * s.z; float cx_sz = c.x * s.z; vec3 result; result.x = ( point.x * ( ( c.y * c.z ) * scale.x ) ) + ( point.y * ( ( ( -cx_sz ) + ( s.x * sy_cz ) ) * scale.y ) ) + ( point.z * ( ( ( -s.x * s.z ) + ( c.x * sy_cz ) ) * scale.z ) ) + translate.x; result.y = ( point.x * ( ( c.y * s.z ) * scale.y ) ) + ( point.y * ( ( ( c.x * c.z ) + ( s.x * sy_sz ) ) * scale.y ) ) + ( point.z * ( ( ( -s.x * c.z ) + ( c.x * sy_sz ) ) * scale.z ) ) + translate.y; result.z = ( point.x * ( ( -s.y ) * scale.x ) ) + ( point.y * ( ( s.x * c.y ) * scale.y ) ) + ( point.z * ( ( c.x * c.y ) * scale.z ) ) + translate.z; homecoming result; } vec4 project(vec3 point) { vec4 result = vec4(0.0); vec3 rotation = radians(camera_rotation); result.x = ( atan(point.x/point.z) - rotation.y ); result.y = ( atan(point.y/point.z) - rotation.x ); result.z = point.z/(farz - nearz); result.w = 1.0; result.x = tan(result.x) * nearz; result.y = tan(result.y) * nearz; vec2 bounds = vec2( tan(fovy * aspect) * nearz, tan(fovy) * nearz ); result.x = result.x / bounds.x; result.y = result.y / bounds.y; if (camera_rotation.z == 0) homecoming result; float dist = sqrt( (result.x*result.x) + (result.y*result.y) ); float theta = atan(result.y/result.x) + rotation.z; result.x = sin(theta) * dist; result.y = cos(theta) * dist; homecoming result; } layout(location = 0) in vec3 vertex_position; layout(location = 1) in vec2 texcoord; out vec2 uvcoord; void main() { uvcoord = texcoord; vec4 pos = project( transform(vertex_position) ); if (pos.z < 0.0) return; gl_position = pos; }

to reply few anticipated questions:

q: why not utilize glm/some-other-mathimatics-lib?

a:

-i tryed while ago. "hello world!" triangle stuck in center of screen. using transformation matrics did'nt move forward, scale it, or anything.

-because learning how figure thing's out you're self important. doing mean's larn how tackle thing's this, while still having fall on if get's out-of-hand. (there's fool's justification.)

q: why not utilize matrics?

a:

-those hate me too.

-i'm doing in new way, if used matrics doing how every tutorial say's it, instead of figuring out my-self.

tryed sources:

http://ogldev.atspace.co.uk/index.html

http://www.swiftless.com/opengltuts/opengl4tuts.html

copyed letter letter glsl shader's (vert & frag) out of "opengl shading language 3rd edition", "emulating opengl fixed functionality" on pg. 288-293

tryed each multiple times, , tinkered each point of insanity. trying programme war game, got wire-frame box project peace symbol one.

edit:

the problem turned out utilize of polar coord's pointed out datenwolf. improve equasion sake of projection using less advanced math was: c = znear * (p.x/p.y) taken thought of 2 triangles, projected points triangle , given points triangle, beingness preportional; , result using same angle.

assuming x , y given point projected, , preportional triangles sidese labeled , c respectivly. can take equasion's atan(y/x) = angle , atan(c/a) = angle , atan(y/x) = atan(c/a) becomes y/x = c/a , finishing c = * (y/x) distance near plane. , c screen coord in y direction.

-those hate me too.

matrices friends. larn utilize them.

-i'm doing in new way, if used matrics doing how every tutorial say's it, instead of figuring out my-self.

your way bad. transformations don't commute , you're locking stiff framework. this:

result.x = ( point.x * ( ( c.y * c.z ) * scale.x ) ) + ( point.y * ( ( ( -cx_sz ) + ( s.x * sy_cz ) ) * scale.y ) ) + ( point.z * ( ( ( -s.x * s.z ) + ( c.x * sy_cz ) ) * scale.z ) ) + translate.x; result.y = ( point.x * ( ( c.y * s.z ) * scale.y ) ) + ( point.y * ( ( ( c.x * c.z ) + ( s.x * sy_sz ) ) * scale.y ) ) + ( point.z * ( ( ( -s.x * c.z ) + ( c.x * sy_sz ) ) * scale.z ) ) + translate.y; result.z = ( point.x * ( ( -s.y ) * scale.x ) ) + ( point.y * ( ( s.x * c.y ) * scale.y ) ) + ( point.z * ( ( c.x * c.y ) * scale.z ) ) + translate.z;

effectively rotation matrix multiplication followed translation matrix, written in overly complicated error prone way. you're wasting precious gpu resources.

your projection function seems implement kind of spherical projection model. problematic, because spherical coordinates curvilinear. long primitives small, compared curvature things work out. primitive gets larger hell breaks loose, because primitive edges drawn straight lines on screen, while have curves, if transform curvilinear coordinate system. you'd need @ to the lowest degree few tesselation shaders , iterative vertex adjustment create work.

math opengl glsl projection

Comments

Popular posts from this blog

web services - java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer -

Accessing MATLAB's unicode strings from C -

javascript - mongodb won't find my schema method in nested container -