Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (522)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (590)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Shaders => vertex world position  (Read 1661 times)
0 Members and 1 Guest are viewing this topic.
Offline Tim Spekler

« JGO Spiffy Duke »


Medals: 58
Projects: 2
Exp: 4 years



« Posted 2012-04-22 11:39:55 »

Hi !

My project includes OpenGL API and most recently shader programming.
The thing is: I need to know world coordinates of vertexes in my Vertex shader. So I do this:
1  
vec4 pos= gl_ModelViewMatrix * gl_Vertex;

Then I can do whatever I want to "pos" which is the world coordinates of my Vertex. And at the end, I do this:
1  
gl_Position = gl_ProjectionMatrix * pos;

But whenever I decide to move the camera, it changes world coordinates !

This is my rendering process:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
public void draw(){
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   //Clear The Screen And The Depth Buffer
        shaders.use();
        set3D();
        camera();
        Map.draw();
        shaders.release();
        set2D();
        //... 2D GUI
   }
   
   public void camera(){
         glRotated(-avatar.getYangle(),1,0,0);
         glRotated(-avatar.getViewangle(),0,1,0);
         glTranslated(-avatar.getX(), -avatar.getY(), -avatar.getZ());
   }


To solve the problem, I created an uniform variable in my shader which corresponds to camera position, and I set this variable in my camera() function so I can substract camera position to "pos". But I 'm not sure this is the best thing to do as I should do the same thing for rotation and it can be time consuming... So is it the best way to deal with this problem or is there a better way ?

Thanks in advance for your help  Smiley
Offline pitbuller
« Reply #1 - Posted 2012-04-22 12:02:13 »

ModelView is camera space.
Go from model to world and then from there to projection.
OpenGL matrix stack is something that just cause headache. Gles2.0 is awesome becouse it does not have that stack.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 835
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #2 - Posted 2012-04-22 12:08:35 »

ModelView is camera space.
Actually, 'ModelView' is: 'inverse of view multiplied by model', which is indeed why it confuses so many people.


What you actually 'should' do is not:
1  
2  
3  
         glRotated(-avatar.getYangle(),1,0,0);
         glRotated(-avatar.getViewangle(),0,1,0);
         glTranslated(-avatar.getX(), -avatar.getY(), -avatar.getZ());


but:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
         Matrix4 camera = new Matrix4();
         camera.translate(avatar.getX(), avatar.getY(), avatar.getZ());
         camera.rotateAxisAngle(avatar.getViewangle(),0,1,0);
         camera.rotateAxisAngle(avatar.getYangle(),1,0,0);
         camera.invert();
         glMultMatrix(camera.toFloatBuffer());

         // position model
         glTranslatef(x, y, z);
         // ... etc


To me, that is a lot easier to grasp.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Spasi
« Reply #3 - Posted 2012-04-22 12:25:11 »

To get the vertex world-position you need to transform it with the model matrix only. Normally this requires an extra matrix uniform, but you can have it for "free" using pseudo-instancing, with the additional benefit of faster rendering. The idea is to update the modelview matrix once, at the start of the frame, with the inverse camera transform only, like Riven explained. Then, per render call, you pass the model transformation as static vertex attributes. Example shader code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
void main(void) {
   // This is the world-space vertex position
   vec3 position = vec3
   (
      // gl_MultiTexcoord5-7 contain a 3x4 transformation matrix (assumes affine transformation, otherwise use 4x4)
      dot(gl_MultiTexCoord5, gl_Vertex), // gl_Vertex is the model-space vertex position
      dot(gl_MultiTexCoord6, gl_Vertex),
      dot(gl_MultiTexCoord7, gl_Vertex)
   );

   // gl_ModelViewProjectionMatrix contains the camera inverse transform and projection.
   gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
   // gl_Position is the clip-space vertex position
   ...
}
Offline Tim Spekler

« JGO Spiffy Duke »


Medals: 58
Projects: 2
Exp: 4 years



« Reply #4 - Posted 2012-04-22 15:23:24 »

Thank you all for your answers , it 's really helpful Cheesy
I changed my camera process as you (Riven and Spasi) told me, which seems better as I get a unique matrix which is the exact representation of my camera position.
I 'm passing my camera matrix to the vertex shader and I compute a dot product. I'm still working on it.  Wink
Offline theagentd

« JGO Bitwise Duke »


Medals: 361
Projects: 2
Exp: 8 years



« Reply #5 - Posted 2012-04-22 16:54:17 »

To get the vertex world-position you need to transform it with the model matrix only. Normally this requires an extra matrix uniform, but you can have it for "free" using pseudo-instancing, with the additional benefit of faster rendering. The idea is to update the modelview matrix once, at the start of the frame, with the inverse camera transform only, like Riven explained. Then, per render call, you pass the model transformation as static vertex attributes. Example shader code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
void main(void) {
   // This is the world-space vertex position
   vec3 position = vec3
   (
      // gl_MultiTexcoord5-7 contain a 3x4 transformation matrix (assumes affine transformation, otherwise use 4x4)
      dot(gl_MultiTexCoord5, gl_Vertex), // gl_Vertex is the model-space vertex position
      dot(gl_MultiTexCoord6, gl_Vertex),
      dot(gl_MultiTexCoord7, gl_Vertex)
   );

   // gl_ModelViewProjectionMatrix contains the camera inverse transform and projection.
   gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
   // gl_Position is the clip-space vertex position
   ...
}


Aw, crap. I always thought GLSL supported custom matrix attribute since OpenGL 2.1 or so. Shadow mapping and deferred shading is all a lie! Battlefield 3 is rendered by gnomes in your computer!

E.g. use a custom matrix uniform. One glUniformMatrix call to update the matrix and clearer GLSL code.

Myomyomyo.
Online Spasi
« Reply #6 - Posted 2012-04-22 17:39:35 »

Aw, no. Did you jump straight to the code and missed the part about pseudo-instancing? Updating vertex attribute values is much faster than updating a uniform.

Anyway, there's nothing special about gl_MultiTexcoord5-7 in the above code, it was just an example that matched the linked paper. You can use any vertex attribs you like. The same thing can be written with more elegance like so:

1  
2  
3  
4  
5  
vec3 position = gl_Vertex * mat3x4(
      gl_MultiTexCoord5,
      gl_MultiTexCoord6,
      gl_MultiTexCoord7
);

or with a mat3x4 vertex attribute:

1  
2  
3  
4  
5  
6  
in mat3x4 modelMatrix;

void main(void) {
      vec3 position = gl_Vertex * modelMatrix;
      ...
}
Offline davedes
« Reply #7 - Posted 2012-04-22 17:44:02 »

To get the vertex world-position you need to transform it with the model matrix only. Normally this requires an extra matrix uniform, but you can have it for "free" using pseudo-instancing, with the additional benefit of faster rendering. The idea is to update the modelview matrix once, at the start of the frame, with the inverse camera transform only, like Riven explained. Then, per render call, you pass the model transformation as static vertex attributes. Example shader code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
void main(void) {
   // This is the world-space vertex position
   vec3 position = vec3
   (
      // gl_MultiTexcoord5-7 contain a 3x4 transformation matrix (assumes affine transformation, otherwise use 4x4)
      dot(gl_MultiTexCoord5, gl_Vertex), // gl_Vertex is the model-space vertex position
      dot(gl_MultiTexCoord6, gl_Vertex),
      dot(gl_MultiTexCoord7, gl_Vertex)
   );

   // gl_ModelViewProjectionMatrix contains the camera inverse transform and projection.
   gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
   // gl_Position is the clip-space vertex position
   ...
}

This article suggests the performance is poor on ATI cards... Any insight into that?

I'd like instancing of some sort in my app but unfortunately GL_ARB_draw_instanced isn't available on my system. Sad

Offline Danny02
« Reply #8 - Posted 2012-04-22 18:31:11 »

I wouldn't care that much about instancing, look at it if you struggle with performance. Especially in OpenGL(compared to DX) instancing shouldn't give you that great performance boost compared to the greater difficulty to use it.

@Spasi, I wouldn't use pseudo instancing it'S not the fastes way and also not the easiest one.
Online Spasi
« Reply #9 - Posted 2012-04-22 19:06:07 »

This article suggests the performance is poor on ATI cards... Any insight into that?

That's true indeed. I updated a loads-of-cubes benchmark I had used before and I'm seeing a 5-10% slowdown with pseudo-instancing vs using a uniform matrix. Running on an AMD 5870. The massive slowdown in that article must have been a problem with older drivers.

I wouldn't care that much about instancing, look at it if you struggle with performance. Especially in OpenGL(compared to DX) instancing shouldn't give you that great performance boost compared to the greater difficulty to use it.

@Spasi, I wouldn't use pseudo instancing it'S not the fastes way and also not the easiest one.

I don't see the difficulty, the code is very similar. Lets say you have 2 code paths, on AMD:

1  
2  
3  
4  
5  
// Init
modelMatrix = glGetUniformLocation(sp, "modelMatrix");

// Before render call
glUniformMatrix3x4(modelMatrix, false, matrixBuffer);

On NV:

1  
2  
3  
4  
5  
6  
7  
// Init
modelMatrix = glGetAttribLocation(sp, "modelMatrix");

// Before render call
glVertexAttrib4f(modelMatrix + 0, m00, m01, m02, m03);
glVertexAttrib4f(modelMatrix + 1, m10, m11, m12, m13);
glVertexAttrib4f(modelMatrix + 2, m20, m21, m22, m23);
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

trollwarrior1 (31 views)
2014-11-22 12:13:56

xFryIx (72 views)
2014-11-13 12:34:49

digdugdiggy (51 views)
2014-11-12 21:11:50

digdugdiggy (45 views)
2014-11-12 21:10:15

digdugdiggy (39 views)
2014-11-12 21:09:33

kovacsa (63 views)
2014-11-07 19:57:14

TehJavaDev (68 views)
2014-11-03 22:04:50

BurntPizza (66 views)
2014-11-03 18:54:52

moogie (81 views)
2014-11-03 06:22:04

CopyableCougar4 (81 views)
2014-11-01 23:36:41
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!