与 webgl 相比,android 上的着色器精度不准确
Inaccurate shader precision on android compared to webgl
我正在尝试根据以下示例在 android 上制作单纯形噪声:
https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl
转换代码并在设备上编译后,我意识到该模式与运行dom相去甚远。我已将代码分解为最基本的部分,我仍然看到桌面(我在 http://glslsandbox.com/e 上测试这些)和移动设备之间存在很大差异,我明白了。
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
float u_time = time;
vec2 u_resolution = resolution;
vec3 mod289(vec3 x) {
vec3 t = x * 0.00346020761;
t = floor(t);
t = t * 289.0;
return x - t;
//return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec3 permute(vec3 x) {
vec3 t = x * 34.0;
t = t + 1.0;
t = t * x;
return mod289(t);
//return mod289(((x*34.0)+1.0)*x);
}
void main( void ) {
vec2 p = vec2( (gl_FragCoord.xy / u_resolution.xx - 0.5) * 2.0);
vec3 value = permute( p.xyx * 10000.0 + u_time * 0.1);
gl_FragColor = vec4(value, 1.0);
//gl_FragColor = vec4(p + 1.0, 0.0, 1.0);
}
分行的目的是我之前也遇到过这种错误。
GLSL ES fragment shader produces very different results on different devices
在设备上,此代码(#ifdef 和#extension 已删除,统一变量设置正确)产生了白屏。 (在多个设备上测试,使用#version 300 es 并使用较旧的着色器版本,结果始终相同。)
这个错误是不是floor()不准确造成的?
或者有没有办法在没有这些 mod289 函数的情况下产生单纯形噪声?
(二维噪点运行就好了)
很有可能您的桌面 GPU 使用 fp32 精度进行计算(即使您在着色器中指定 mediump
,它只需要 fp16)。
如果你设置precision highp float
,效果会更好吗?这将强制进行 fp32 浮点计算。
但是,请注意并非所有移动设备都支持 highp
- 它仅在 OpenGL ES 3.x 之后才成为强制性要求,因此某些 OpenGL ES 2.x GPU 仅支持 fp16 计算。
(您 运行 使用的是什么设备?)
我正在尝试根据以下示例在 android 上制作单纯形噪声:
https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl
转换代码并在设备上编译后,我意识到该模式与运行dom相去甚远。我已将代码分解为最基本的部分,我仍然看到桌面(我在 http://glslsandbox.com/e 上测试这些)和移动设备之间存在很大差异,我明白了。
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
float u_time = time;
vec2 u_resolution = resolution;
vec3 mod289(vec3 x) {
vec3 t = x * 0.00346020761;
t = floor(t);
t = t * 289.0;
return x - t;
//return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec3 permute(vec3 x) {
vec3 t = x * 34.0;
t = t + 1.0;
t = t * x;
return mod289(t);
//return mod289(((x*34.0)+1.0)*x);
}
void main( void ) {
vec2 p = vec2( (gl_FragCoord.xy / u_resolution.xx - 0.5) * 2.0);
vec3 value = permute( p.xyx * 10000.0 + u_time * 0.1);
gl_FragColor = vec4(value, 1.0);
//gl_FragColor = vec4(p + 1.0, 0.0, 1.0);
}
分行的目的是我之前也遇到过这种错误。 GLSL ES fragment shader produces very different results on different devices
在设备上,此代码(#ifdef 和#extension 已删除,统一变量设置正确)产生了白屏。 (在多个设备上测试,使用#version 300 es 并使用较旧的着色器版本,结果始终相同。)
这个错误是不是floor()不准确造成的?
或者有没有办法在没有这些 mod289 函数的情况下产生单纯形噪声? (二维噪点运行就好了)
很有可能您的桌面 GPU 使用 fp32 精度进行计算(即使您在着色器中指定 mediump
,它只需要 fp16)。
如果你设置precision highp float
,效果会更好吗?这将强制进行 fp32 浮点计算。
但是,请注意并非所有移动设备都支持 highp
- 它仅在 OpenGL ES 3.x 之后才成为强制性要求,因此某些 OpenGL ES 2.x GPU 仅支持 fp16 计算。
(您 运行 使用的是什么设备?)