GL matrix story (stupid but true)
GL matrix story (stupid but true)
I am writing code to force portrait display mode by rotating the frustum/ortho/viewport.
Results in a 90 turn just by inserting ...
glRotatef (90, 0, 0, 1); // Add me!
glFrustum (-xmax, +xmax, -ymax, -ymax, glnear, glfar);
Stupidly, OpenGL fails to do this! Possibly due to a division by zero I am guessing where perhaps -xmax and xmax are used somewhere in the matrix calculation in a way they add together to be zero.
Hilarously ... instead I use mh's glmatrix frustum calculation which performs the calculation in a way that avoids division by 0 in common situations --- then do glLoadMatrixf (m) to load that matrix.
Then I live in "Not my problem!" city!
Results in a 90 turn just by inserting ...
glRotatef (90, 0, 0, 1); // Add me!
glFrustum (-xmax, +xmax, -ymax, -ymax, glnear, glfar);
Stupidly, OpenGL fails to do this! Possibly due to a division by zero I am guessing where perhaps -xmax and xmax are used somewhere in the matrix calculation in a way they add together to be zero.
Hilarously ... instead I use mh's glmatrix frustum calculation which performs the calculation in a way that avoids division by 0 in common situations --- then do glLoadMatrixf (m) to load that matrix.
Then I live in "Not my problem!" city!
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: GL matrix story (stupid but true)
well, (-ymax)-(-ymax) == 0, so yeah, what do you expect?
I really hope that was a typo in your post and not your code.
glFrustum internally does a glMultMatrix, so make sure your prior matrix is sane. Also that you've got GL_MATRIX_MODE set properly. too much state sucks. but yeah, glLoadMatrix is the most sane way to do most of this anyway. The matrix generated by the function is well defined and well documented so implementing your own should be fairly easy, and more efficient on account of using glLoadMatrix instead of the implicit glMultMatrix of glFrustum.
I really hope that was a typo in your post and not your code.
glFrustum internally does a glMultMatrix, so make sure your prior matrix is sane. Also that you've got GL_MATRIX_MODE set properly. too much state sucks. but yeah, glLoadMatrix is the most sane way to do most of this anyway. The matrix generated by the function is well defined and well documented so implementing your own should be fairly easy, and more efficient on account of using glLoadMatrix instead of the implicit glMultMatrix of glFrustum.
Re: GL matrix story (stupid but true)
Twas a typo. That'd be a very small vertical frustum otherwiseSpike wrote:well, (-ymax)-(-ymax) == 0, so yeah, what do you expect?
I really hope that was a typo in your post and not your code.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: GL matrix story (stupid but true)
Yeah, the great thing about OpenGL is that you can look at the spec, read how things are implemented, then construct your own variant if you need to.
It should be possible (and easy!) to write a GL_RotatedFrustum that does the same in a single operation, not that it would be a performance improvement (unless for some reason you're calling glFrustum thousands or more times per frame).
None of these calls do anything special or magic or voodoo. They just construct an ordinary 4x4 matrix, do a multiplication and load the result to the GPU. There's nothing mysterious going on in their internals.
It should be possible (and easy!) to write a GL_RotatedFrustum that does the same in a single operation, not that it would be a performance improvement (unless for some reason you're calling glFrustum thousands or more times per frame).
None of these calls do anything special or magic or voodoo. They just construct an ordinary 4x4 matrix, do a multiplication and load the result to the GPU. There's nothing mysterious going on in their internals.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: GL matrix story (stupid but true)
Since we're talking about GL matricies, could please tell me, you, engine gurus, if it's possible to create an ortographic matrix to pass to FTE shadowmap code to make it project dynamic parallel shadows? Because I tried and I tried but so far I only created weird static plane shadows!
Note that I created same matrix also in GLSL and pass it to the shadow map fragment shader part
PS:sorry to have sneaked into your post with a question, Baker, but the opportunity was too greedy!!
Note that I created same matrix also in GLSL and pass it to the shadow map fragment shader part
PS:sorry to have sneaked into your post with a question, Baker, but the opportunity was too greedy!!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Re: GL matrix story (stupid but true)
toneddu2000, you're actually looking for two projection matricies.
the one used to render the shadowmap needs to transform from camera space to clip space.
the one used to read the shadowmap needs to transform again from camera space, but this time to the texture coords (with depth).
clip space in opengl ranges from -1 on the left, bottom, and nearest part of the screen, to 1 on the right, top, and furthest part of the screen.
on the other hand, texture coords range from 0 to 1, as does the 'red' component of the shadowmap texture (aka the depth).
sampling from a 2d shadow sampler can be done with a 3d texcoord - the 3rd coord being a reference value to compare the texture against. This gives slightly smoother results. the alternative is to treat it as a regular texture and do the compare yourself, which may be needed with gles2, but mneh.
so the first matrix is a standard ortho matrix, while the second one can be generated from the first by multiplying it against a bias matrix, but if you care about precision you'd get more precise results by calculating it directly.
and don't forget the divide-by-w thing, though I don't recall it actually being needed with ortho matricies.
the one used to render the shadowmap needs to transform from camera space to clip space.
the one used to read the shadowmap needs to transform again from camera space, but this time to the texture coords (with depth).
clip space in opengl ranges from -1 on the left, bottom, and nearest part of the screen, to 1 on the right, top, and furthest part of the screen.
on the other hand, texture coords range from 0 to 1, as does the 'red' component of the shadowmap texture (aka the depth).
sampling from a 2d shadow sampler can be done with a 3d texcoord - the 3rd coord being a reference value to compare the texture against. This gives slightly smoother results. the alternative is to treat it as a regular texture and do the compare yourself, which may be needed with gles2, but mneh.
so the first matrix is a standard ortho matrix, while the second one can be generated from the first by multiplying it against a bias matrix, but if you care about precision you'd get more precise results by calculating it directly.
and don't forget the divide-by-w thing, though I don't recall it actually being needed with ortho matricies.
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: GL matrix story (stupid but true)
thanks a lot Spike, I'll reply in the original thread, to avoid spoling Baker's thread
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Re: GL matrix story (stupid but true)
Doesn't bother me in the slightest, just fyi. Was just sharing a short experience.
Your post about shadowmapping was interesting. Carry on ... should you wish ...
Your post about shadowmapping was interesting. Carry on ... should you wish ...
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: GL matrix story (stupid but true)
Lol, thanks Baker. Anyway, I couldn't get it work. Spike advices were very clear but probably my opengl skills are too low to create a working orthographic projection in FTE for project parallel shadows.
I adapted this GLSL shader that mimic parallel light and I used this site as reference for bias matrix and for learning how shadows are applied in fragment shader
This is the modification in Sh_GenShadowMap() in gl_shadow.c. I simply delete all the code regarding omni/spot and replaced with this. Just temp code.
In CSQC_UpdateView I created a simple light
This is the GLSL shader created by Hugh Kennedy (MIT license)
And this is the material with the BEMODE for rtlights. Note that diffusemap it's useless, since GLSL colors meshes by itself,it's there only to avoid FTE complaining about missing pass
This will make a nice diffuse parallel light with a counter ambient light, which it's cool.Look how round light is.
And this is the shader with the #SHDW flag... practically nothing useful!
As you can see, shadow is just a square sitting in the middle of scene. It's like it was placed at specific coordinates
Weird thing is that, even with FTE release without my modification, rendering is the same as above
I adapted this GLSL shader that mimic parallel light and I used this site as reference for bias matrix and for learning how shadows are applied in fragment shader
This is the modification in Sh_GenShadowMap() in gl_shadow.c. I simply delete all the code regarding omni/spot and replaced with this. Just temp code.
Code: Select all
float left = -1;
float bottom = -1;
float znear = -1;
float right = 1;
float top = 1;
float zfar = 1;
Matrix4x4_CM_Orthographic(r_refdef.m_projection_std,left,right,bottom,top,znear,zfar);
memcpy(r_refdef.m_projection_view, r_refdef.m_projection_std, sizeof(r_refdef.m_projection_view));
Code: Select all
ltest = dynamiclight_add(cam.origin,cvar("render_light_radius"),[cvar("render_light_intensity"),cvar("render_light_intensity"),cvar("render_light_intensity")],0,"",0);
Code: Select all
!!permu FOG
!!samps diffuse
!!cvarf render_sun_ground
!!cvarf render_sun_x
!!cvarf render_sun_y
!!cvarf render_sun_z
!!cvarf render_sun_back_x
!!cvarf render_sun_back_y
!!cvarf render_sun_back_z
!!cvarf render_sun_intensity
#include "sys/defs.h"
#include "sys/pcf.h"
#include "sys/fog.h"
#define shdwIntensity 0.1
varying vec2 tc;
varying vec3 eyevector,normalvector,lightvector;
varying vec4 modelvector,viewvector,vtexprojcoord,shadowCoord ;
uniform float cvar_render_sun_x,cvar_render_sun_y,cvar_render_sun_z,cvar_render_sun_ground;
uniform float cvar_render_sun_back_x,cvar_render_sun_back_y,cvar_render_sun_back_z,cvar_render_sun_intensity;
//Copyright (c) 2014 Hugh Kennedy - MIT License - https://github.com/hughsk/glsl-directional-light
//adapted to FTE engine by Antonio "toneddu2000" Latronico - antoniolatronico.com
#ifdef VERTEX_SHADER
void main (void)
{
vec3 eyeminusvertex = e_eyepos - v_position.xyz;
normalvector = -v_normal.xyz;
eyevector.x = dot(eyeminusvertex, v_svector.xyz);
eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
eyevector.z = dot(eyeminusvertex, v_normal.xyz);
lightvector = l_lightposition - v_position.xyz;
const float right = 1.0;
const float bottom = -1.0;
const float left = -1.0;
const float top = 1.0;
const float far = 1.0;
const float near = -1.0;
mat4 shdwmat = mat4(
vec4(2.0 / (right - left), 0, 0, -(right + left) / (right - left)),
vec4(0, 2.0 / (top - bottom), 0, -(top + bottom) / (top - bottom)),
vec4(0, 0, -2.0 / (far - near), -(far + near) / (far - near)),
vec4(0, 0, 0, 1)
);
mat4 biasmat = mat4(
vec4(0.5, 0.0, 0.0, 0.0),
vec4( 0.0, 0.5, 0.0, 0.0),
vec4( 0.0, 0.0, 0.5, 0.0),
vec4(0.5, 0.5, 0.5, 1.0)
);
mat4 depthMVP = m_projection * m_view * m_model;
mat4 depthBiasMVP = biasmat*depthMVP;
vtexprojcoord = (shdwmat*biasmat*vec4(1.0,1.0,1.0, 1.0));
shadowCoord = depthBiasMVP * vec4(v_position.xyz, 1.0);
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
vec3 directional_light(vec3 normal,vec3 light,vec3 surface,vec3 lightDirection,mat4 modelMatrix,mat4 viewMatrix,vec3 viewPosition,float shininess,float specularity)
{
vec3 direction = normalize((vec4(lightDirection, 1.0)).xyz);
vec3 halfDirection = normalize(direction + viewPosition);
vec3 tNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
float diffuse = max(dot(tNormal, direction), 0.0);
float halfDot = max(dot(tNormal, halfDirection), 0.0);
float specular = max(pow(halfDot, shininess), 0.0);
return max(light * (diffuse * surface + diffuse * specular * specularity), vec3(0.0));
}
vec3 directional_light(vec3 normal,vec3 light,vec3 surface,vec3 lightDirection,mat4 modelMatrix,mat4 viewMatrix,vec3 viewPosition)
{
vec3 direction = normalize((modelMatrix * vec4(lightDirection, 1.0)).xyz);
float diffuse = max(dot(normal, direction),shdwIntensity);
return max(light * diffuse * surface,vec3(0.0));
}
void main (void)
{
vec3 sky = vec3(0.510,0.247,0.000);
vec3 gnd = vec3(0.002,0.486,0.912);
vec3 direction1 = normalize(vec3(cvar_render_sun_x,cvar_render_sun_y, cvar_render_sun_z));
vec3 direction2 = normalize(vec3(cvar_render_sun_back_x, cvar_render_sun_back_y, cvar_render_sun_back_z));
vec3 surface = vec3(1.0,1.0,1.0);
vec3 color = vec3(0.3,0.3,0.3);
//realtime shadows
float visibility = 1.0;
if ( ShadowmapFilter(s_shadowmap, shadowCoord) < shadowCoord.z){
visibility = 0.2;
}
#ifdef GREENBRIGHT
color = vec3(0.059,0.750,0.000);
#endif
#ifdef GREENDARK
color = vec3(0.000,0.510,0.003);
#endif
#ifdef GREENYELLOW
color = vec3(0.484,0.840,0.032);
#endif
#ifdef BROWNBRIGHT
color = vec3(0.795,0.391,0.027);
#endif
#ifdef BROWNDARK
color = vec3(0.545,0.267,0.001);
#endif
#ifdef GREYBRIGHT
color = vec3(0.645,0.655,0.622);
#endif
#ifdef GREYDARK
color = vec3(0.507,0.515,0.489);
#endif
#ifdef GREYVERYDARK
color = vec3(0.369,0.375,0.356);
#endif
#ifdef RED
color = vec3(0.990,0.188,0.000);
#endif
#ifdef YELLOW
color = vec3(0.990,0.700,0.016);
#endif
vec3 composite = mix(surface,color,max(dot(normalvector, direction1),shdwIntensity));
color *= vec3(cvar_render_sun_intensity);
#ifdef SHDW
color = color + (visibility * l_lightcolour );
#endif
vec3 lightsun = vec3(1.000,0.878,0.000);//light sun (usually bright sun)
vec3 lightambient = vec3(0.081,0.593,0.685);//light gi (usually dark blue)
mat4 matrixModel = m_projection;
mat4 matrixView = m_invviewprojection;
vec3 lighting =
directional_light(normalvector, lightsun, color, direction1, matrixModel, matrixView, eyevector)
+ directional_light(normalvector, lightambient, color, direction2, matrixModel, matrixView, eyevector);
gl_FragColor = fog4(vec4(lighting,1.0));
gl_FragDepth = gl_FragCoord.z;
}
#endif
Code: Select all
parallelshdw
{
//first set textures
diffusemap textures/env/green.tga
//second bemode for realtime lights
bemode rtlight
{
program ton_lightparallel#SHDW
}
}
And this is the shader with the #SHDW flag... practically nothing useful!
As you can see, shadow is just a square sitting in the middle of scene. It's like it was placed at specific coordinates
Weird thing is that, even with FTE release without my modification, rendering is the same as above
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Re: GL matrix story (stupid but true)
for a start, you're not even using the ortho matrix in your glsl, at least not in any way that would prevent it from being optimised out.
your light is in one place and its projecting onto some meshes. the vertex coords get multiplied by the model matrix which gives you the vertexes world coord. at this point things diverge - you have both a camera (with its view + perspective-projection matrix), and a light (which has its own orientation/view matrix, and its own ortho-projection matrix).
gl_Position needs the screen/camera position in clip space.
however, your shadowCoord needs the shadow coord in texture space upon your projected texture. this has absolutely nothing to do with the camera's view or projection matrix - the only normal matrix that matters for this varying is the model matrix.
what I'd recommend you try is to first just get your texture projection working.
ditch the shadow map for now, and just project a regular coloured 2d image onto a black wall for now.
that way you'll know when your s+t texture coords are correct, that there's no weird affine issues, etc, in a way that is completely separate from the shadowmap generation.
divide and conquer. you won't know when the p coord is correct until you reinstate the actual shadowmap, but at least you'll know that you're actually reading the right part of the shadowmap. the actual depth values themselves are probably the last thing you should tackle (ignoring stuff like pcf/smoothing/etc).
your light is in one place and its projecting onto some meshes. the vertex coords get multiplied by the model matrix which gives you the vertexes world coord. at this point things diverge - you have both a camera (with its view + perspective-projection matrix), and a light (which has its own orientation/view matrix, and its own ortho-projection matrix).
gl_Position needs the screen/camera position in clip space.
however, your shadowCoord needs the shadow coord in texture space upon your projected texture. this has absolutely nothing to do with the camera's view or projection matrix - the only normal matrix that matters for this varying is the model matrix.
what I'd recommend you try is to first just get your texture projection working.
ditch the shadow map for now, and just project a regular coloured 2d image onto a black wall for now.
that way you'll know when your s+t texture coords are correct, that there's no weird affine issues, etc, in a way that is completely separate from the shadowmap generation.
divide and conquer. you won't know when the p coord is correct until you reinstate the actual shadowmap, but at least you'll know that you're actually reading the right part of the shadowmap. the actual depth values themselves are probably the last thing you should tackle (ignoring stuff like pcf/smoothing/etc).
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: GL matrix story (stupid but true)
Something like that?Spike wrote:what I'd recommend you try is to first just get your texture projection working.
ditch the shadow map for now, and just project a regular coloured 2d image onto a black wall for now.
I projected this texture
on this scene.
I used same matrix trasformations for both gl_Position and projected texture coords.
It's important to mention that, in FTE, if you want to assign to gl_Position, something that is not ftetranform(), you have to use z margin to "extrude" it a little, otherwise zfighting will ruin the rendering
Here's the code
Code: Select all
#include "sys/defs.h"
varying vec4 projectedCoords;
#ifdef VERTEX_SHADER
void main (void)
{
projectedCoords = m_projection * m_view * m_model* vec4(v_position.xyz, 1.0);
//projection in clip space
gl_Position = m_projection * m_view * m_model* vec4(v_position.xyz, 1.0);
//z-fighting fix copied from here: https://stackoverflow.com/questions/24142068/z-fighting-solutions-in-depth-test-in-opengl-how-do-they-work
float Z = 1.0;
float far = 2000.0;
gl_Position.z = 2.0*log(gl_Position.w*Z + 1.0)/log(far*Z + 1.0) - 1.0;
gl_Position.z *= gl_Position.w;
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
void main (void)
{
vec4 projectimg = texture2DProj(s_t0,normalize(projectedCoords));
gl_FragColor = projectimg;
}
#endif
Was that what you meant? Now what?
Should I use, instead of camera inclination, an arbitrary matrix for rotation?
This is fun
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Re: GL matrix story (stupid but true)
no, you want to project the texture, not sample it from screen space. If you'd wanted that then there are easier ways to do it. Ones that do not require you creating a z-fighting minefield. Try re-reading the second block of text in my previous post.
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: GL matrix story (stupid but true)
ok, this is what I did so far. I premise that I use this page as reference(for those interested, go to "9.3 Projective Texturing" chapter).
I don't sample anymore from screen space but I use model matrix multiplied by the light projection matrix (engine-builtin l_cubematrix matrix)
vertex shader(same for both "versions").
fragment shader
And I ended up with this.
As you can see, texture is projected but scale is very low. I put in the top-right corner a zoomed view of texture.
This one was the texture2DProj version. Now the other one.
The next one uses .st swizzle of texCoordProjNorm and texture2D instead using the full vec4 coord and texture2DProj,
so probably it's not what I should do, but, weirdly, final image is exactly what I wanted to achieve!
Now texture orientation is not tied anymore to camera inclination and it seems that texture "covers" entire scene with same texture coordinates. But I used texture2D, and not texture2DProj
adding to vertex shader a bias matrix and multiplying it to model matrix and l_cubematrix, makes image less "warped"
So, did I do things correctly? Is it right to use texture2D, instead of texture2DProj? Or was the texture2DProj approach the correct one(but I missed some steps)? Or none of them?
Then, I used another approach from this page, which it uses projection matrix multiplied by model matrix
And the image is this
Personally, this seems a weird projection and texture is stretched above spheres. It seems more like that every object preserves its own texture coords. But this approach uses texture2DProj
I don't sample anymore from screen space but I use model matrix multiplied by the light projection matrix (engine-builtin l_cubematrix matrix)
vertex shader(same for both "versions").
Code: Select all
void main (void)
{
texCoordProj = m_model* l_cubematrix * vec4(v_position.xyz, 1.0);
gl_Position = ftetransform();
}
Code: Select all
uniform sampler2D s_t0;
void main (void)
{
vec2 uv = normalize(gl_FragCoord.xy/gl_FragCoord.w)/2.0;
vec4 tex = texture2D(s_t0,uv);
vec4 projectimg,texCoordProjNorm;
texCoordProjNorm = normalize(texCoordProj);
projectimg = texture2DProj(s_t0,texCoordProjNorm);
gl_FragColor = projectimg;
}
As you can see, texture is projected but scale is very low. I put in the top-right corner a zoomed view of texture.
This one was the texture2DProj version. Now the other one.
The next one uses .st swizzle of texCoordProjNorm and texture2D instead using the full vec4 coord and texture2DProj,
Code: Select all
uniform sampler2D s_t0;
void main (void)
{
vec2 uv = normalize(gl_FragCoord.xy/gl_FragCoord.w)/2.0;
vec4 tex = texture2D(s_t0,uv);
vec4 projectimg,texCoordProjNorm;
texCoordProjNorm = normalize(texCoordProj);
projectimg = texture2D(s_t0,texCoordProjNorm.st);
gl_FragColor = projectimg;
}
Now texture orientation is not tied anymore to camera inclination and it seems that texture "covers" entire scene with same texture coordinates. But I used texture2D, and not texture2DProj
adding to vertex shader a bias matrix and multiplying it to model matrix and l_cubematrix, makes image less "warped"
Code: Select all
mat4 biasmat = mat4(
vec4(0.5, 0.0, 0.0, 0.0),
vec4( 0.0, 0.5, 0.0, 0.0),
vec4( 0.0, 0.0, 0.5, 0.0),
vec4(0.5, 0.5, 0.5, 1.0)
);
texCoordProj = m_model* l_cubematrix * biasmat* vec4(v_position.xyz, 1.0);
So, did I do things correctly? Is it right to use texture2D, instead of texture2DProj? Or was the texture2DProj approach the correct one(but I missed some steps)? Or none of them?
Then, I used another approach from this page, which it uses projection matrix multiplied by model matrix
Code: Select all
!!ver 130
#include "sys/defs.h"
varying vec4 texCoordProj;
#ifdef VERTEX_SHADER
void main (void)
{
mat4 biasmat = mat4(
vec4(0.5, 0.0, 0.0, 0.0),
vec4( 0.0, 0.5, 0.0, 0.0),
vec4( 0.0, 0.0, 0.5, 0.0),
vec4(0.5, 0.5, 0.5, 1.0)
);
texCoordProj = m_projection* m_model* biasmat* vec4(v_position.xyz, 1.0);
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
void main (void)
{
vec2 uv = normalize(gl_FragCoord.xy/gl_FragCoord.w)/2.0;
vec4 tex = texture2D(s_t0,uv);
vec4 projectimg,texCoordProjNorm;
texCoordProjNorm = normalize(texCoordProj);
projectimg = texture2DProj(s_t0,texCoordProj);
gl_FragColor = projectimg;
}
#endif
Personally, this seems a weird projection and texture is stretched above spheres. It seems more like that every object preserves its own texture coords. But this approach uses texture2DProj
Meadow Fun!! - my first commercial game, made with FTEQW game engine
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: GL matrix story (stupid but true)
Today I tried a different approach. Instead of using engine builtin matricies, I asked myself: how would it be if I use arbitrary rotation matrix for texture plane projection?
So I learned here how openGL uses matricies for transformation and I created a rotation on X axys matrix
which I used as inclination for plane projection.
This is the glsl file
This is the rendering
you can use cvar_glsl_project_angle to change angle of orientation of the projected plane. As you can see, both spheres have same inclination of projection, cubes seems that have their own. Plus, rotating objects like the cube in the screenshot, rotate the projection with them, so it's again in object coordinates, not world coords. But, really, I cannot understand how to convert it.
So I learned here how openGL uses matricies for transformation and I created a rotation on X axys matrix
Code: Select all
mat4 rot_mat_x_axis = mat4(
vec4(1.0, 0, 0, 0),
vec4(0,cos(cvar_glsl_project_angle),-sin(cvar_glsl_project_angle),0),
vec4(0, sin(cvar_glsl_project_angle),cos(cvar_glsl_project_angle),0),
vec4(0, 0, 0, 1)
);
This is the glsl file
Code: Select all
!!ver 430
!!cvarf glsl_project_angle
#include "sys/defs.h"
varying vec4 ProjTexCoord;
varying vec2 uv;
uniform float cvar_glsl_project_angle;
#ifdef VERTEX_SHADER
void main (void)
{
mat4 rot_mat_x_axis = mat4(
vec4(1.0, 0, 0, 0),
vec4(0,cos(cvar_glsl_project_angle),-sin(cvar_glsl_project_angle),0),
vec4(0, sin(cvar_glsl_project_angle),cos(cvar_glsl_project_angle),0),
vec4(0, 0, 0, 1)
);
vec4 pos4 = vec4(v_position.xyz, 1.0);
ProjTexCoord = (m_projection*rot_mat_x_axis*pos4);
uv.xy = v_texcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0,s_t1;
void main (void)
{
vec4 texProj = vec4(0.0);
vec4 texDiff = texture2D(s_t0,uv.xy);
vec4 finalColor;
if( ProjTexCoord.z < cvar_glsl_project_angle ){
texProj = textureProj( s_t1, ProjTexCoord );
finalColor = texProj;
}
else{
finalColor = texDiff;
}
gl_FragColor = finalColor;
}
#endif
you can use cvar_glsl_project_angle to change angle of orientation of the projected plane. As you can see, both spheres have same inclination of projection, cubes seems that have their own. Plus, rotating objects like the cube in the screenshot, rotate the projection with them, so it's again in object coordinates, not world coords. But, really, I cannot understand how to convert it.
Meadow Fun!! - my first commercial game, made with FTEQW game engine