Jump to content

  • Log In with Google      Sign In   
  • Create Account


mdwh

Member Since 27 Feb 2006
Offline Last Active Yesterday, 07:20 AM
-----

Topics I've Started

Clip planes on NVIDIA with Shaders?

24 November 2007 - 06:54 AM

My NVIDIA 8600GT supports user clip planes, but only when using the fixed pipeline. Is there any way to enable them when using shaders? I've occasionally come across places suggesting this is possible (e.g., a comment here suggests it works if you "write a clip distance to result.clip[0] in your vertex program"), but I don't know enough to know how to implement that? I'm using Cg and OpenGL if that makes any difference. Note, I've tried Oblique Depth Projection, but it doesn't work for me - please see this thread for details on that. Thanks in advance.

Oblique Depth Projection troubles...

14 November 2007 - 02:25 PM

I am trying to use the Oblique Depth Projection code at http://www.terathon.com/code/oblique.php , but am having problems (using OpenGL). I am trying to render reflections in a Y=0 plane. I get the same problem whether I use Render to Texture, or just draw directly; I get the same issue with or without shaders. The clipping doesn't behave as expected - it clips objects partly in a -ve Y direction (i.e., objects towards the bottom of the screen are clipped away, which is opposite to what I want). Also it isn't fixed in world space, but moves with the camera (I am specifying the plane in camera space), and the plane appears to be tilted forward, so that objects nearer the camera are clipped first. This problem occurs both on NVIDIA 8600GT and Intel GMA 950. Everything works fine if I use the OpenGL user clip planes. Also, the z-ordering appears to be reversed - objects further away are drawn in front of those nearer. This seems to be due to my use of glScale3f(0,-1,0) for the reflection - if I don't reflect the objects, this issue is fixed, but the clipping still doesn't work properly (the reflection scale works fine with user clip planes). The code is:
        // Calculate the clip-space corner point opposite the clipping plane
        // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
        // transform it into camera space by multiplying it
        // by the inverse of the projection matrix
        float q_x = (sgn(pl[0]) + matrix[8]) / matrix[0];
        float q_y = (sgn(pl[1]) + matrix[9]) / matrix[5];
        float q_z = -1.0F;
        float q_w = (1.0F + matrix[10]) / matrix[14];

        // Calculate the scaled plane vector
        //Vector4D c = clipPlane * (2.0F / Dot(clipPlane, q));
        float dot = q_x * pl[0] + q_y * pl[1] + q_z * pl[2] + q_w * pl[3];
        float scale = 2.0 / dot;

        // Replace the third row of the projection matrix
        matrix[2] = pl[0] * scale;
        matrix[6] = pl[1] * scale;
        matrix[10] = pl[2] * scale + 1.0F;
        matrix[14] = pl[3] * scale;
Here are the details of my data: Plane in world space: (x,y,z,d) = (0, -1, 0, 0) [Is that oriented the right way? I want to clip away everything being drawn above the y=0 plane for the reflections; if I reverse the sign, then I don't get any reflections drawn, it seems to all be clipped away.] Plane in eye space: (0, -1, 0, 0.5) [this looks right? - the camera is looking along the z axis, and is at y=0.5] The perspective matrix before modification is: [ 2.414 0 0 0 ] [ 0 2.414 0 0 ] [ 0 0 -1.0002 -0.2 ] [ 0 0 -1 0 ] The 3rd row is changed to: [ 0 -4.823 1 2.411 ] Now I have some code to extract the frustum planes from the perspective matrix, and the result from this is: RIGHT -0.923880 0.000000 -0.382683 0.000000 LEFT 0.923880 0.000000 -0.382683 0.000000 BOTTOM 0.000000 0.923880 -0.382683 0.000000 TOP 0.000000 -0.923880 -0.382683 0.000000 FAR 0.000000 0.923716 -0.383078 -0.461858 NEAR 0.000000 -1.000000 0.000000 0.500000 So the near plane has been correctly modified(?) Is it the modified far plane that is causing the problem? The orientation would seem to give the result I am observing of objects being clipped as I move close to them. But that doesn't explain why the near plane doesn't seem to be clipping anything, nor does it explain why the z-ordering seems to be reversed? Also, comparing the Far plane to the Bottom plane, it seems to me that the far plane is below the bottom plane, i.e., it shouldn't intersect the view frustum (the intersection point, I believe, is at ( 0 413.252883 997.682347 ))? Any ideas? Thanks in advance.

Vertex Buffer Objects with Dynamic Data

04 March 2006 - 05:08 PM

Are there any good tutorials about using Vertex Buffer Objects properly with dynamic data? I want to render models where the vertices are recalculated each time (because I'm interpolating between frames), though the normals and texture coordinates are precalculated. I could understand that using VBOs for the vertices doesn't give any benefit, but I'm actually finding them slower than ordinary vertex arrays! First some performance figures. "Mixed" means that I'm using VBOs for the normals/texture-coords, but using an ordinary vertex array for the vertices. The figure in brackets is with normals disabled. Scene 1 - 700K triangles: No VBOs: 15FPS (19FPS) All VBOs: 15FPS (16FPS) Mixed: 28FPS (28FPS) Scene 2 - 130K triangles: No VBOs: 85FPS (110FPS) All VBOs: 85FPS (89FPS) Mixed: 178FPS (178FPS) Scene 3 - 772 triangles: No VBOs: 1200FPS (1200FPS) All VBOs: 1125FPS (1125FPS) Mixed: 1200FPS (1200FPS) So there are two things to conclude: - "Mixed" gives a significant advantage, presumably as the color/texture-coord data is cached on the gfx card rather than being sent each frame. But using a VBO for the vertices too loses this performance gain! - If normals are disabled, using a VBO for the vertices makes things slightly slower than not using VBOs at all. The code I'm using is: glGenBuffersARB( 1, &vbo_vertices ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbo_vertices ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, 3*n_vertices*sizeof(float), NULL, GL_STREAM_DRAW_ARB ); for initialisation, and then rendering each frame with: glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbo_vertices ); glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, 0, 3*n_vertices*sizeof(float), va_vertices_temp ); glVertexPointer(3, GL_FLOAT, 0, (char *)NULL); I've tried calling glBufferDataARB each frame to set the data, but that doesn't help. I'm using glDrawRangeElements to draw the arrays. Am I doing something wrong here? Or is this yet another case of VBOs being implemented poorly? I've looked at the many other threads on similar subjects, and can't see what I'm doing wrong. I've got a Radeon 9800, and have the latest OpenGL drivers. Okay, I can just use my "Mixed" method, and get a nice performance increase - but my reading from various forums is that this isn't the method I'm supposed to be using! Any ideas? thanks in advance, mark

Vertex Buffer Objects versus Display Lists

27 February 2006 - 03:36 PM

Further to my earlier post, I'm now having trouble with the performance of VBOs versus display lists. There's been a million threads on vertex arrays versus display lists, and I know that the latter have an advantage of the data being stored on the graphics card, for greater performance. So I can accept display lists being faster in some cases. However, my understanding was that Vertex Buffer Objects are stored on the graphics card also, so one might think that display lists shouldn't be faster? I'm looking at the worst case situations where no vertices are shared (so the advantage of sharing vertices you get with vertex arrays/VBOs is lost). My graphics card is a Radeon 9800 with the latest OpenGL drivers. I've got a test case rendering 8192 quads, using GL_QUADS, with no shared vertices. As far as I can tell, the display list is set up to render the same thing as the VBO. Firstly, I test with vertices only - no normals, colors or textures: Display list: ~1490 FPS VBO: ~1490 FPS Vertex Array (no VBO): ~610 FPS All well and good - the VBO is about the same as the display list, and slower without VBO. But then I specify a normal for each vertex: Display list: ~1490 FPS VBO: ~300 FPS Vertex Array (no VBO): ~200 FPS Whilst display lists are just as fast, I get a dramatic slowdown with VBOs! I then tried using GL_TRIANGLES rather than GL_QUADS, rendering each quad as two triangles (so with vertex arrays/VBOs, this means some vertex sharing). I get (again with normals specified): Display list: ~1670 FPS VBO: ~550 FPS Vertex Array (no VBO): ~150 FPS So VBOs are sped up, but still a huge difference compared to display lists (as an aside, it's interesting to note the effect of using GL_TRIANGLES versus GL_QUADS). Has anyone else experienced this? Is there a known reason why display lists are faster? Or is it a driver issue where VBOs haven't been implemented well? Or is this likely to be an issue with my code? I'm in the process of trying to move my 3D engine from display lists to VBOs, and I'd rather get rid of display lists entirely to avoid unnecessary extra code, but I'm worried at this big performance drop. On the other hand, perhaps I shouldn't worry about this "worse case", and only worry about meshes where vertices are shared as much as possible? Also, my understanding is that display lists aren't supported in DirectX (?) - if so, then I presume this isn't considered that much of a problem. I guess my questions are: * Is this something I'm doing wrong, and can the problem be fixed (or at least reduced)? * Or should I simply accept that VBOs are slower in these cases for whatever reasons, and not worry? The code I'm using to initialise my buffers is: glGenBuffersARB( 1, &vbo_vertices ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbo_vertices ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, 3*n_elements*sizeof(float), va_vertices, GL_STATIC_DRAW_ARB ); glGenBuffersARB( 1, &vbo_normals ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbo_normals ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, 3*n_elements*sizeof(float), va_normals, GL_STATIC_DRAW_ARB ); and I render with: glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbo_vertices ); glVertexPointer(3, GL_FLOAT, 0, (char *)NULL); glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbo_normals ); glNormalPointer(GL_FLOAT, 0, (char *)NULL); glDrawArrays(GL_QUADS, 0, n_renderlength); [or GL_TRIANGLES] thanks in advance, mark

Poor Performance with Vertex Buffer Objects

27 February 2006 - 12:57 PM

I recently discovered a problem with performance on Vertex Buffer Objects - I've found the cause, but I'm curious as to the reasons. The problem occurred when I specified vertex colours with a VBO. To make sure it wasn't something odd with my code, I took a copy of NeHe's Lesson 45. Normally I get 300-400 FPS with VBOs, and about 100 FPS without. But when I implemented using VBOs for colours too, whilst without VBOs it was still around 100 FPS, with VBOs it drops to 10 FPS! The code I am using is: glGenBuffersARB( 1, &m_nVBOColors ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nVBOColors ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_nVertexCount*3*sizeof(unsigned char), m_pColors, GL_STATIC_DRAW_ARB ); to initialise the VBO, and: glBindBufferARB( GL_ARRAY_BUFFER_ARB, g_pMesh->m_nVBOColors ); glColorPointer( 3, GL_UNSIGNED_BYTE, 0, (char *) NULL ); to render. I finally figured out the problem - it was due to specifying colours as a collection of 3 chars. If I used 4 chars (ie, with the alpha channel), or if I used 3 floats instead, then the problem went away. So what's happening here? I've heard that sometimes hardware performs better if things are grouped in 16/32bits rather than 24bits. But does this mean I'm always better off using an alpha channel (whether I want it or not), e.g., for normal vertex arrays too, just in case? I've always been told to send as small amount of data as necessary to the gfx card. Or is there something wrong with my code? Has anyone else experienced this? I have a Radeon 9800, with the latest OpenGL drivers. Is this something particular to Radeon cards, or a driver issue? Are there any other situations where the representation/format of the data makes such big difference? thanks, mark

PARTNERS