From 25410647cc0f9f0dea8d417219054bac00a86c23 Mon Sep 17 00:00:00 2001 From: wan-may Date: Mon, 10 Mar 2025 22:24:36 -0300 Subject: [PATCH] finite projection matrix, rotation matrix --- main.lua | 141 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 39 deletions(-) diff --git a/main.lua b/main.lua index 4b834fd..39bfd20 100644 --- a/main.lua +++ b/main.lua @@ -6,7 +6,7 @@ local testMesh = love.graphics.newMesh( }, {--vertices { 0, 0, 0, 1, - 0, 0, 0 }, + 1, 1, 1 }, { 1, 0, 0, 1, 1, 0, 0 }, { 0, 1, 0, 1, @@ -39,36 +39,105 @@ local testQuad = love.graphics.newMesh( ) local testShader = [[ + varying float d; #ifdef VERTEX uniform mat4 mdl; uniform mat4 view; uniform mat4 proj; vec4 position( mat4 _, vec4 pos ){ - return proj*view*mdl*pos; + vec4 cam = view*mdl*pos; + d = cam.z; + return proj * cam; } #endif #ifdef PIXEL vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { - return color * vec4( 1., 1., 1., 0.5 ); + return color * vec4( 1.0, 1.0, 1.0, 1.0 ) ; } #endif ]] testShader = love.graphics.newShader( testShader, testShader ) +--TODO: column major +local function prod( A, B ) + local C = {} + for j = 1,4 do C[j] = {0, 0, 0, 0} end + for j = 1, 4 do + for i = 1, 4 do + C[j][i] = + A[1][i] * B[j][1] + + A[2][i] * B[j][2] + + A[3][i] * B[j][3] + + A[4][i] * B[j][4] + end + end + return C +end + + +local function roll( t ) + local c, s = math.cos(t), math.sin(t) + return { + {c, 0, s, 0}, + {0, 1, 0, 0}, + {-s, 0, c, 0}, + {0, 0, 0, 1}, + } +end + + +local function trans( x, y, z ) + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {x, y, z, 1}, + } +end + +local function scale( x, y, z ) + return { + {x, 0, 0, 0}, + {0, y, 0, 0}, + {0, 0, z, 0}, + {0, 0, 0, 1}, + } +end + +local function id() + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, + } +end + +--tait-bryan yaw pitch roll +local function rotate( a, b, g ) + local c, s = math.cos, math.sin + local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) + return { + { ca*cb, sa*cb, -sb, 0}, + {ca*sb*sg - sa*cg, sa*sb*sg + ca*cg, cb*sg, 0}, + {ca*sb*cg + sa*sg, sa*sb*cg - ca*sg, cb*cg, 0}, + { 0, 0, 0, 1}, + } +end + --fov in degrees, aspect w/h, near far -local function getProjectionMatrix(n, f) +local function getProjectionMatrix(n, f, fov) local r = love.graphics.getWidth() / 2 local t = love.graphics.getHeight() / 2 - return --[[{ - {n/r, 0, 0, 0}, - {0, n/t, 0, 0}, - {0, 0, -(f+n)/(f-n), -2 * f * n / (f-n) }, - {0, 0, -1, 0}, - }]] - { {1, 0, 0, 0}, - {0,-1, 0, 0}, - {0, 0, -1, -2*n}, - {0, 0, -1, 0}, + local aspect = r/t + local tan = math.tan( fov / 2 ) + return + --infinite z + --TODO: get finite + { {1.0 / tan, 0, 0, 0}, + {0, -1.0 / tan, 0, 0}, + {0, 0, ( f + n ) / (n-f), -1 }, + {0, 0, -2 * f * n / (f - n), 0}, } end @@ -80,23 +149,10 @@ local function getViewMatrix() {0, 0, 0, 1}, } end - -local testID = { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}, - } - -local testModelMatrix = { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, -2}, - {0, 0, 0, 1}, - } +local testModelMatrix local testViewMatrix = getViewMatrix() -local testProjection = getProjectionMatrix( 0.2, 10 ) +local testProjection = getProjectionMatrix( 0.1, 10, math.rad( 30 ) ) local time = 0 local testDSCanvas = love.graphics.newCanvas( @@ -118,29 +174,36 @@ function love.draw() love.graphics.clear() love.graphics.setDepthMode( "less", true ) love.graphics.setShader( testShader ) - testShader:send( "mdl", "row", testModelMatrix ) - testShader:send( "proj", "row", testProjection ) - testShader:send( "view", "row", testViewMatrix ) + testShader:send( "mdl", "column", testModelMatrix ) + testShader:send( "proj", "column", testProjection ) + testShader:send( "view", "column", testViewMatrix ) love.graphics.draw( testMesh ) - testShader:send( "mdl", "column", testID ) - love.graphics.draw( testQuad ) + testShader:send( "mdl", "column", id() ) + --love.graphics.draw( testQuad ) love.graphics.setShader() - love.graphics.draw( testQuad ) love.graphics.setColor(1,1,1, 0.5 ) - -- love.graphics.rectangle( "fill", 0, 0, love.graphics.getDimensions() ) + --love.graphics.rectangle( "fill", 0, 0, love.graphics.getDimensions() ) love.graphics.setCanvas() love.graphics.setDepthMode( "always", true ) love.graphics.pop() love.graphics.draw( testCanvas ) - love.graphics.print( string.format( "%05.2f\t:TIME\n%05.2f\t:ANGLE", time, (180 / math.pi) * time / 15 ) ) + love.graphics.print( string.format( "%05.2f\t:TIME\n%05.2f\t:ANGLE", time, time )) --[[love.graphics.setShader() love.graphics.setColor( 1,1,1,1 ) love.graphics.circle( "fill", time, time/2, 5 )]] end function love.update( dt ) - time = time + 10 * dt - testModelMatrix[3][4] = -2.0 - math.sin( time / 5 ) + time = time + dt + testModelMatrix = prod( + trans( 0, 0, -4 + math.sin( time )), + roll( time ) + ) + testModelMatrix = prod( + testModelMatrix, + rotate( time, time, time ) + + ) end \ No newline at end of file