使用GLSL中的mod进行精度损失 [英] Precision loss with mod in GLSL

查看:165
本文介绍了使用GLSL中的mod进行精度损失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在顶点着色器中重复纹理(用于存储,而不是在现场重复).这是正确的方法吗?我似乎有些失落了.

I'm repeating a texture in the vertex shader (for storage, not for repeating at the spot). Is this the right way? I seem to lose precision somehwere.

varying vec2 texcoordC;

texcoordC = gl_MultiTexCoord0.xy;
texcoordC *= 10.0;
texcoordC.x = mod(texcoordC.x, 1.0);
texcoordC.y = mod(texcoordC.y, 1.0);

添加:然后,我将texcoord保存(存储)为颜色,将其打印到纹理上,然后再次使用该纹理.当我从纹理中检索颜色时,我会找到texcoords并使用它们在后期处理中应用纹理.我有这样的一个理由,我不会去讨论.我知道texcoords将受到颜色精度的限制,没关系,因为我的纹理的宽度和高度均为256.

ADDED: I then save (storage) the texcoord in the color, print it to the texture and later use that texture again. When I retrieve the color from the texture, I find the texcoords and use them to apply a texture in postprocess. There's a reason I want it this way, that I won't go into. I get it that the texcoords will be limited by the color's precision, that is alright as my texture is 256 in width and height.

我知道通常我会将glTexcoord2f的texcoords设置为大于1.0以重复(并使用GL_REPEAT),但是我使用的是一个懒惰地编辑的模型加载器,因为我认为这是不必要的/也不是最简单的方式.

I know normally I would set the texcoords with glTexcoord2f to higher than 1.0 to repeat (and using GL_REPEAT), but I am using a modelloader which I am to lazy to edit, as I think it is not necessary/not the easiest way.

推荐答案

(至少)有两种方法可能会出错:

There are (at least) two ways in which this could go wrong:

首先是的,您将失去精度.放大后,实际上是在使用浮点数的小数部分.这本质上将一些数字丢掉了.

Firstly yes, you will lose precision. You are essentially taking the fractional part of a floating point number, after scaling it up. This essentially throws some of the number away.

第二,无论如何,这可能都不起作用,不适用于大多数典型用途.您试图按顶点平铺纹理,但是纹理是在多边形上插值的.因此,该技术可能会在同一多边形的不同顶点上不同地平铺纹理,从而造成混乱.

Secondly, this probably won't work anyway, not for most typical uses. You are trying to tile a texture per-vertex, but the texture is interpolated across a polygon. So this technique could tile the texture differently on different vertices of the same polygon, resulting in a bit of a mess.

如果顶点1的U值为1.5(按比例缩放),而顶点2的U值为2.2,则您希望插值在这些点之间给出递增的值,而中间点的U值为1.85.

If vertex1 has a U of 1.5 (after scaling), and vertex2 has a U of 2.2, then you expect the interpolation to give increasing values between those points, with the half-way point having a U of 1.85.

如果在每个顶点取模,则U分别为0.5,U为0.2,从而导致减少 U,以及中点为U的中点0.35 ...

If you take the modulo at each vertex, you will have a U of 0.5, and a U of 0.2 respectively, resulting in a decreasing U, and a half-way point with a U of 0.35...

仅在纹理/采样器上启用平铺并使用0-> 1范围以外的坐标就可以平铺纹理.如果确实要提高采样精度并进行大量平铺,则需要将UV坐标均匀地包装在整个多边形上,而不是在每个顶点上包装.即在您的数据中执行此操作,而不是在顶点着色器中执行该操作.

Textures can be tiled just be enabling tiling on the texture/sampler, and using coordinates outside the range 0->1. If you really want to increase sampling accuracy and have a large amount of tiling, you need to wrap the UV coordinates uniformly across whole polygons, rather than per-vertex. i.e. do it in your data, not in the vertex shader.

对于您的情况,当您尝试将UV坐标输出到缓冲区中以备后用时,您可以将UV钳位/包装在 pixel 着色器中.因此,在顶点着色器中乘以UV,将其正确插值到多边形上,然后仅在写入缓冲区时才应用模.

For your case, where you're trying to output the UV coordinates into a buffer for some later purpose, you could clamp/wrap the UVs in the pixel shader. So multiply up the UV in the vertex shader, interpolate it across the polygon correctly, and then apply the modulo only when writing to the buffer.

但是我仍然认为您会遇到精度问题,因为您将丢失所有子像素信息.我不知道这对您使用的技术是否有问题.

However I still think you'll have precision issues as you're losing all the sub-pixel information. Whether or not that's a problem for the technique you're using, I don't know.

这篇关于使用GLSL中的mod进行精度损失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆