Fixed Point Arithmetic with Vertex Shaders

If I use a fixed point (or integers with 1 describing the smallest part of the game) to describe my vertex vectors, how can I customize OpenGL / native transforms to work with it? If I do this in my vertex shader:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0) 

If I pass in_Position as vec3 from GL_INT, and when I pass in matrices as GL_FLOAT mat4, will the correct casting be performed? Is there any cost to fulfill?

Is it possible for my transform matrices to be at a fixed point?

This is done with a 2D game, which, in my opinion, makes it more feasible than with 3D. I would prefer accuracy, as it seems that on large maps the situation is worsening when things go far from the origin. I understand that I could leave with the only position of the object being an integer, while the vertices are still described as a float. However, I think my collision scheme will work better with fixed-point vertices. How is the performance difference usually?

+4
source share
2 answers

Well, after some experimentation, I decided to solve the problem.

 gl_Position = projviewMatrix * vec4(ivec3(in_Position - camera), 1.0); 

camera is uniform uvec3 , and in_Position is the input of uvec3 position. Translation is performed as a separate operation, while scaling, rotation and projection of a view are performed using mat4 floats ( projviewMatrix ), as usual.

Care must be taken to ensure the correct input types and commands ( glVertexAttribIPointer ). OpenGL, it seems, really wants to quit swimming, but leave the data in an integer type, so any small error will lead to distortion of the input.

It is simply not possible to perform projviewMatrix multiplication at a fixed point, since you do not have access to the intermediate 64-bit storage for multiplication. Only if the bits used by in_Position and projviewMatrix up to 32 will be close to usability, but considering that the rendering cords will be so close to the original and no additional options will be received (still need to be changed after multiplication, the GPU will take so much same time as for float as int), there is no reason to perform fixed-point arithmetic after the position has been focused by the camera.

Of course, this ignores royal pain in order to actually manipulate integer position data. I would not recommend it.

0
source

This will mean that int will float with a conversion that will punish your actions. You must use in_Position for vec3 when loading the processor on the GPU. If you use a Matrix object to store them on the CPU, you can use them with:

 MatrixXf data_as_float = data_as_int.cast<float>(); 

Then call glBufferData with data_as_float.

+1
source

All Articles