Extrude shadow volumes to infinity - opengl

I want to use the depth-fail algorithm to make shadow volumes and all works great, but i can't figure out how to extrude the shadow volume quads to infinity.
The aim is to create the shadow volume for a triangle that is lit up from a point light. I have red that i first have to change the perspective matrix that it has no far clip pane and set the w coordinate to 0. But what are the x,y,z coordinates then?
An example would be very helpful, but i also want to understand how its done.

This link shows an example of a projection matrix. It has the form:
a 0 b 0
A = 0 d e 0
0 0 -(f+n)/(f-n) -2fn/(f-n)
0 0 -1 0
f is the far plane and you want f -> infinity.
limit f -> infinity of (f+n)/(f-n) = limit f -> infinity of (1+n/f)/(1-n/f)
and
limit f -> infinity of 2fn/(f-n) = limit f -> infinity of 2n/(1-n/f)
since
f -> infinity => n/f -> 0
your matrix with f -> infinity becomes
a 0 b 0
B = 0 d e 0
0 0 -1 -2n
0 0 -1 0
if you transform your (x,y,z,w=0) with B you'll get
x' = ax + bz
y' = dy + ez
z' = -z
w' = -z
and the perspective division gives
x' = -ax/z - b
y' = -dy/z - e
z' = 1
While x' and y' are the same as transforming (x,y,z,w=0) with A, z' is now a constant that is always equal to the far plane in normalized device coordinates.
This article shows an efficient implementation of shadow volumes with capping at infinity.

Related

Creating a view matrix manually OpenGL

I´m trying to create a view matrix for my program to be able to move and rotate the camera in OpenGL.
I have a camera struct that has the position and rotation vectors in it. From what I understood, to create the view matrix, you need to multiply the transform matrix with the rotation matrix to get the expected result.
So far I tried creating matrices for rotation and for transformation and multiply them like this:
> Transformation Matrix T =
1 0 0 -x
0 1 0 -y
0 0 1 -z
0 0 0 1
> Rotation Matrix Rx =
1 0 0 0
0 cos(-x) -sin(-x) 0
0 sin(-x) cos(-x) 0
0 0 0 1
> Rotation Matrix Ry =
cos(-y) 0 sin(-y) 0
0 1 0 0
-sin(-y) 0 cos(-y) 0
0 0 0 1
> Rotation Matrix Rz =
cos(-z) -sin(-z) 0 0
sin(-z) cos(-z) 0 0
0 0 1 0
0 0 0 1
View matrix = Rz * Ry * Rx * T
Notice that the values are negated, because if we want to move the camera to one side, the entire world is moving to the opposite side.
This solution seems to almost be working. The problem that I have is that when the camera is not at 0, 0, 0, if I rotate the camera, the position is changed. What I think is that if the camera is positioned at, let´s say, 0, 0, -20 and I rotate the camera, the position should remain at 0, 0, -20 right?
I feel like I´m missing something but I can´t seem to know what. Any help?
Edit 1:
It´s an assignment for university, so I can´t use any built-in functions!
Edit 2:
I tried changing the order of the operations and putting the translation in the left side, so T * Rz * Ry * Rx, but then the models rotate around themselves, and not around the camera.

Changing/Convert from UE4 coordinates to OpenGL coorinates

I am trying to convert from UE4 coordinates (Z up) to opengl coorinates (Y up) but I cant seem to get around it.
I do this Matrix transforming from X+ right, Y+ up, Z- deep to Y+ right, Z+ up, X+ deep
[mat = M]
0 1 0 0
0 0 1 0
-1 0 0 0
0 0 0 1
But I end up getting the wrong result and also the rotation....
I get ActorTranfrom from (T) = this->GetTransform()
then
FTransform R = T * M
Then I do the R - ToMatrixWithScale() - then get send it to OpenGL backend.
But the orientation is wrong... What am I doing wrong ?

I try to understand the View Matrix in OpenGL

I try to construct my own View Matrix in OpenGL.
I'm following this link
https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
From the OpenGL doc, I have following.
eye position = eye(xe, ye, ze)
center position = cen(0, 0, 0)
up = up(xu, yu, zu). (e.g. up = (0, 1, 0))
forward vector
f' = cen - eye = (0, 0, 0) - (xe, ye, ze) = (-xe, -ye, -ze)
side vector
s' = f' x up
I don't understand why f' x up, why not up x f'
u' = s' x f'
I do't understand why u' = s' x f', why not u' = f' x s'
we normalize s', u', f'
s = norm(s'), u = norm(u'), f=norm(f')
We construct the rotation matrix with row-major(what we learn in algebra class)
R =
s_x u_x f_x 0
s_y u_y f_y 0
s_z u_z f_z 0
0 0 0 1
translation matrix:
T =
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
we know
M = T*R
View Matrix V = invert(M)
V = invert(T*R) = invert(R)invert(T)
V = transpose(R)invert(T)
transpose(R) =
s_x s_y s_z 0
u_x u_y u_z 0
f_x f_y f_z 0
0 0 0 1
invert(T) =
1 0 0 -x
0 1 0 -y
0 0 1 -z
0 0 0 1
so
View Matrix V = transpose(R)invert(T)
But from the OpenGL doc., f change to -f
The rotation changes to following
R =
s_x u_x -f_x 0
s_y u_y -f_y 0
s_z u_z -f_z 0
0 0 0 1
I Don't understand why we need to change the forward vector to negative.
The cross product order just follows from its definition. It is just like it is. You are setting up a right-handed coordinate system. So if you align the thumb of your right hand with the first factor and the index finger with the second factor, then the middle finger will point in the direction of the cross product (perpendicular to both). There is really not much more to tell about this.
And since you are setting up a right-handed coordinate system, the forward direction of the camera must be mapped to the negative z-direction. That's why the third column of the rotation matrix is inverted. If you don't do this, you end up with a left-handed coordinate system, where the camera looks in the direction of the positive z-axis.

calculate pixel coordinates for 8 equidistant points on a circle

I have a circle centred at 0 with radius 80. How using python do I calculate the coordinates for 8 equidistant points around the circumference of the circle?
r = 80
numPoints = 8.0
points = []
for index in range(numPoints):
points.append([r*math.cos((index*2*math.pi)/numPoints),r*math.sin((index*2*math.pi)/numPoints)])
return points
you can simplify this some if you know you are always going to have only 8 points with something like:
r = 80
numPoints = 8
points = []
x = (r*math.sqrt(2))/2
points = [[0,r],[x,x],[r,0],[-x,x],[-r,0],[-x,-x],[0,-r],[x,-x]]
print points
with x being the x/y of the point 45 degrees and 80 units away from the origin
click this pic for more clarity
in the above picture.
coordinates 1,2,3,4,5,6,7,8 are equidistant points on a circumference of circle Radius R and its centre is at X (0,0)
take the triangle XLZ , its aright angled at L ,
Let LZ = H ,
LY = A
XL + LY = R => XL + A = R => XL = R-A
since XLZ is right angled , XZ square = XL square + LZ square
R square = (R-A) square + h square ————1
since these 8 points makes an octagon theta = 360 deg / 8 = 45 deg
tan 45 deg = h / XL = h / R-A => 1 = h/ R-A => h = R-A —————2
Z coordinates are (R-A, h) = > (h,h)
from the equations 1 and 2
R square = h square + h square => 2 h square = R square => h = R/ sqrt 2
so the coordinates at point 2 (Z) = (R/sqrt2, R/sqrt2)
remaining can be derived easily as they are just oppside
So all coordinates are
1 (0,R)
2 (R/sqrt2,R/sqrt2)
3 (R,0)
4 (-R/sqrt2, R/sqrt2)
5 (-R,0)
6 (-R/sqrt2,-R/sqrt2)
7 (0,-R)
8 (R/sqrt2, -R/sqrt2)

Inverse perspective transformation of a warped image

# Iwillnotexist Idonotexist presented his code for image perspective transformation (rotations around 3 axes): link
I'm looking for a function (or math) to make an inverse perspective transformation.
Let's make an assumption, that my "input image" is a result of his warpImage() function, and all angles (theta, phi and gamma), scale and fovy are also known.
I'm looking for a function (or math) to compute inverse transformation (black border doesn't matter) to get an primary image.
How can I do this?
The basic idea is you need to find the inverse transformation. In the linked question they have F = P T R1 R2 where P is the projective transformation, T is a translation, and R1, R2 are two rotations.
Denote F* as the inverse transformation. We can the inverse as F* = R2* R1* T* P*. Note the order changes. Three of these are easy R1* is just another rotation but with the angle negated. So the first inverse rotation would be
cos th sin th 0 0
R1* = -sin th cos th 0 0
0 0 1 0
0 0 1
Note the signs on the two sin terms are reversed.
The inverse of a translation is just a translation in the opposite direction.
1 0 0 0
T*= 0 1 0 0
0 0 1 h
0 0 0 1
You can check these calculating T* T which should be the identity matrix.
The trickiest bit is the projective component we have
cot(fv/2) 0 0 0
P = 0 cot(fv/2) 0 0
0 0 -(f+n)/(f-n) -2 f n / (f-n)
0 0 -1 0
The inverse of this is
tan(fv/2) 0 0 0
P*= 0 tan(fv/2) 0 0
0 0 0 -2
0 0 (n-f)/(f n) (f+n)/(f n)
Wolfram alpha inverse with v=fv
You then need to multiply these together in the reverse order to get the final matrix.
I also had issues to back-transform my image.
You need to store the points
ptsInPt2f and ptsOutPt2f
which are computed in the the 'warpMatrix' method.
To back-transform, simply use the same method
M = getPerspectiveTransform(ptsOutPt2f, ptsInPt2f);
but with reversed param order (output as first argument, input as second).
Afterwards a simple crop will get rid of all the black.