首页 > 解决方案 > 您如何处理 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);
}

标签: floating-pointglslshaderprecisionfloating-accuracy

解决方案


首先请注意,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


推荐阅读