floating-point - 您如何处理 GLSL 中增加浮点值的小数精度?
问题描述
我正在编写一个着色器,我需要根据增加的 x 偏移量计算 y 值。
问题是不断增加的 x 值最终将失去其小数精度,导致 y 函数的输出返回越来越碎片化的值。
我试图在这个例子中说明问题。
您可以增加或减少largeTimeOffset
变量以查看它对正弦波细节的影响。有没有解决这个问题的通用方法?
片段着色器供参考:
float calculateY(float x, float y) {
return y + sin(x);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec3 bgColor = vec3(0.0);
vec3 lineColor = vec3(0.0);
float lineWidth = 0.001;
vec2 uv = fragCoord/iResolution.xy;
uv = -1.0 + 2.0 * uv;
uv.y += 0.1;
float largeTimeOffset = 1000000.0;
float x = (uv.x + (iTime + largeTimeOffset));
float y = calculateY(x, uv.y);
lineWidth = abs(1.0 / (300.0 * y));
lineColor += vec3(lineWidth, lineWidth, lineWidth);
fragColor = vec4(bgColor+lineColor,1.0);
}
解决方案
首先请注意,double
从 OpenGL ES 3.2 (GLSL ES 3.20) 或“桌面”OpenGL 4.0 (GLSL 4.00) 开始支持数据类型,分别由扩展ARB_gpu_shader_fp64 支持。
请参阅数据类型 (GLSL)
由于sin
是一个周期函数,这个问题可以通过计算一个周期内的偏移量来解决mod
。周期分别为 2*PI
:(2.0*acos(-1.0)
适用于所有 GLSL 和 GLSL ES 版本)mod
float x = uv.x + mod(iTime + largeTimeOffset, 2.0*acos(-1.0));
当然,这是三角函数的特殊解决方案,sin
并且cos
推荐阅读
- reactjs - 在 Firebase 上部署时,Next.js 链接不起作用
- reactjs - azure Microsoft MSAL 2.0(msal浏览器)时如何识别用户是否登录?
- drools - Drools DMN 在节点上找不到所需的依赖项。消息类型:“REQ_NOT_FOUND”
- c++ - 在 while 循环中获取 bad_alloc
- javascript - Node.js Firestore 错误 - 无法编码值
- r - 将数字分成几组中的任何一组 tidyverse r
- javascript - 复选框状态在反应中没有改变
- python - 检查点周围是否有封闭区域
- c - 无法在 arm64(Apple Silicon)上使用 GTK+3 构建 C11 应用程序
- blockchain - ERC721 - tokenURI 中提及的元数据资产的真实性