Floating point 如何处理GLSL中增加浮点值的十进制精度?

Floating point 如何处理GLSL中增加浮点值的十进制精度?,floating-point,glsl,shader,precision,floating-accuracy,Floating Point,Glsl,Shader,Precision,Floating Accuracy,我正在写一个着色器,我需要根据增加的x偏移计算y值 问题在于,增加的x值最终将失去其十进制精度,导致y函数的输出返回越来越零碎的值 我试着用这个例子来说明这个问题 您可以增加或减少larGetTimeOffset变量,以查看它对正弦波细节的影响。有解决这个问题的通用方法吗 片段着色器供参考: float calculateY(浮点x,浮点y){ 返回y+sin(x); } 无效主图像(输出vec4 fragColor,输入vec2 fragCoord) { vec3-bgColor=vec3(0

我正在写一个着色器,我需要根据增加的x偏移计算y值

问题在于,增加的x值最终将失去其十进制精度,导致y函数的输出返回越来越零碎的值

我试着用这个例子来说明这个问题

您可以增加或减少
larGetTimeOffset
变量,以查看它对正弦波细节的影响。有解决这个问题的通用方法吗

片段着色器供参考:

float calculateY(浮点x,浮点y){
返回y+sin(x);
}
无效主图像(输出vec4 fragColor,输入vec2 fragCoord)
{
vec3-bgColor=vec3(0.0);
vec3 lineColor=vec3(0.0);
浮动线宽=0.001;
vec2 uv=fragCoord/iResolution.xy;
紫外线=-1.0+2.0*紫外线;
uv.y+=0.1;
float LarGetTimeOffset=1000000.0;
float x=(uv.x+(iTime+larGetTimeOffset));
浮动y=计算y(x,uv.y);
线宽=绝对值(1.0/(300.0*y));
lineColor+=vec3(线宽、线宽、线宽);
fragColor=vec4(bgColor+lineColor,1.0);
}

首先请注意,扩展分别从OpenGL ES 3.2(GLSL ES 3.20)或“桌面”OpenGL 4.0(GLSL 4.00)开始支持数据类型
double


由于是一个周期函数,因此可以通过计算一段时间内的偏移量来解决该问题。周期分别为2*PI
2.0*acos(-1.0)

mod
分别在所有GLSL和GLSL ES版本中提供)

float x=uv.x+mod(iTime+largeTimeOffset,2.0*acos(-1.0));

当然,这是三角函数的一个特殊解决方案
sin
cos
@rabbi76提到fp64扩展在OpenGL ES 3.2上工作,但在文章中说,支持的最低版本是OpenGL 3.2,它不等同于OpenGL ES 3.2。

要在OpenGL ES中实际使用双精度浮点数,必须对其进行仿真。对于三角函数,可以使用这些函数的泰勒级数展开。

为什么是浮点,而不是双精度?GLSL不支持double@stego扩展分别从OpenGL ES 3.2(GLSL ES 3.20)或“桌面”OpenGL 4.0(GLSL 4.00)开始支持double。参见小调:好奇,为什么使用3.141593而不是更精确的pi值?3.141593不能产生
float
中可用的最佳pi近似值。一个好的机器pi是acos(-1)的结果。我想我可以利用你的建议来解决我的问题。然而,在我看来,丢失的十进制精度仍然会影响最终结果。根据您的建议,曲线看起来很平滑,但增加
LarGetTimeOffset
时,小数精度仍然丢失,这不仅仅是因为不再影响曲线的平滑度。@stepo仍然不清楚您试图实现什么。为了获得完美的结果,请在CPU上计算
mod(时间,2*PI)
(具有双精度),并将该值设置为统一值。在您的示例中,
float x=uv.x+iTime+mod(largetimecoffset,2.0*acos(-1.0))
也会给出一个很好的结果,但我认为这不会在“真实”的情况下解决问题。