简体   繁体   English

具有顶点着色器的定点算术

[英]Fixed-point arithmetic with vertex shaders

If I use fixed-point (or integers with 1 describing the smallest game unit) to describe my vertex vectors, how can I setup OpenGL/eigen transformations to work with it? 如果我使用定点(或描述最小游戏单元的1的整数)来描述我的顶点向量,我如何设置OpenGL /本征变换来使用它? If I'm doing this in my vertex shader: 如果我在顶点着色器中执行此操作:

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

If I pass in_Position in as a vec3 of GL_INT, while I pass in the matrices as GL_FLOAT mat4, will the proper casting be done? 如果我将in_Position作为GL_INT的vec3传入,而我将矩阵作为GL_FLOAT传递给mat4,是否会进行正确的转换? Is there a performance cost? 是否有性能成本?

Is it possible to prepare my transformation matrices to be in fixed-point as well? 是否有可能将我的转换矩阵准备好定点?

This is being done with a 2D game, which I think makes it more feasible than with 3D. 这是通过2D游戏完成的,我认为这比使用3D更可行。 I would really prefer the accuracy, since it seems there is degradation of position on large maps when things get far away from the origin. 我真的更喜欢准确性,因为当事物离原点很远时,大地图上的位置似乎会降低。 I realize I could probably get away with only object position being an integer while the vertices are still described as floats. 我意识到我可能只能将对象位置变为整数,而顶点仍被描述为浮点数。 However, I think my collision scheme will work better with fixed-point vertices. 但是,我认为我的碰撞方案可以更好地使用定点顶点。 What is generally the performance difference? 一般性能差异是什么?

This will imply a int to float conversion that will penalize your performances. 这将意味着一个int to float转换将惩罚你的表现。 You should cast in_Position to vec3 at CPU to GPU copy time. 您应该在CPU到GPU复制时将in_Position转换为vec3。 If you use a Matrix object to store them on CPU, you can cast them with: 如果使用Matrix对象将它们存储在CPU上,则可以使用以下方法强制转换它们:

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

Then call glBufferData with data_as_float. 然后使用data_as_float调用glBufferData。

Ok, after some experimentation, I've settled on a solution. 好的,经过一些实验,我已经找到了解决方案。

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

camera is a uniform uvec3 , and in_Position is the uvec3 position input. camera是一个uniform uvec3in_Positionuvec3位置输入。 Translation is performed as a separate operation, while the view scaling, rotation, and projection is done with a mat4 of floats ( projviewMatrix ) as usual. 而视图缩放,旋转和投影用做翻译作为单独的操作来执行, mat4浮标( projviewMatrix )如常。

Care must be taken to ensure the proper types and input commands ( glVertexAttribIPointer ) are used. 必须注意确保使用正确的类型和输入命令( glVertexAttribIPointer )。 OpenGL seems very eager to cast to float yet leave the data in an integer type, so any small error will result in mangled input. OpenGL似乎非常渴望转换为float而将数据保留为整数类型,因此任何小错误都将导致输入错误。

It simply is not feasible to perform the projviewMatrix multiply in fixed-point, since you do not have access to an intermediary 64-bit storage for the multiplications. 由于您无法访问用于乘法的中间64位存储,因此在定点中执行projviewMatrix是不可行的。 Only if the bits used by in_Position and projviewMatrix sum to 32 would it approach usability, but considering that coords for rendering will be so close to the origin and no extra ops are gained (still need to shift after multiply, GPU will take as long for floats as ints), there is no reason to perform fixed-point arithmetic after the position has been centered by camera. 只有当in_PositionprojviewMatrix总和为32时才会接近可用性,但考虑到渲染的坐标将如此接近原点并且没有获得额外的操作(仍然需要在乘法后移位,GPU将花费很长时间浮动为整数),没有理由在位置被摄像机居中后执行定点运算。

Of course, this is ignoring the royal pain it is to actually manipulate the integer position data. 当然,这忽略了实际操纵整数位置数据的皇家痛苦。 I really wouldn't recommend it. 我真的不推荐它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM