简体   繁体   English

Perlin噪音在某些设备(Android,GLSL)上有问题

[英]Perlin noise bugged at some devices (Android, glsl)

I am developing OpenGLES app for Android and using Perlin noise from Stefan Gustavson. 我正在为Android开发OpenGLES应用程序,并使用Stefan Gustavson的Perlin噪声。 It's animated 2D noise so I use 3D Perlin with time variable as third dimension. 它是2D动画动画,因此我将3D Perlin与时间变量作为第三维。 And it was all looking good on my Samsung Galaxy Young (API 10), but when I tested it with ASUS MEMO tablet (API 17) I got this glitchy thing with even elipses and square-like areas:- 在我的Samsung Galaxy Young(API 10)上一切看起来都不错,但是当我用ASUS MEMO平板电脑(API 17)测试它时,我得到了即使在椭圆形或类似正方形区域的故障信号:-

这个

What could cause such differences between various devices? 是什么导致各种设备之间的这种差异?

Fragment shader code: 片段着色器代码:

precision mediump float;
varying vec2 screenPosition;
uniform vec4 colorFilter;
uniform float time;

vec4 permute(vec4 x)
{
  return mod(((x*34.0)+1.0)*x, 289.0);
}

vec4 taylorInvSqrt(vec4 r)
{
  return 1.79284291400159 - 0.85373472095314 * r;
}

vec3 fade(vec3 t) {
  return t*t*t*(t*(t*6.0-15.0)+10.0);
}

float noise(vec3 P)
{
  vec3 Pi0 = floor(P); // Integer part for indexing
  vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
  Pi0 = mod(Pi0, 289.0);
  Pi1 = mod(Pi1, 289.0);
  vec3 Pf0 = fract(P); // Fractional part for interpolation
  vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
  vec4 iy = vec4(Pi0.yy, Pi1.yy);
  vec4 iz0 = Pi0.zzzz;
  vec4 iz1 = Pi1.zzzz;

  vec4 ixy = permute(permute(ix) + iy);
  vec4 ixy0 = permute(ixy + iz0);
  vec4 ixy1 = permute(ixy + iz1);

  vec4 gx0 = ixy0 / 7.0;
  vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;
  gx0 = fract(gx0);
  vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
  vec4 sz0 = step(gz0, vec4(0.0));
  gx0 -= sz0 * (step(0.0, gx0) - 0.5);
  gy0 -= sz0 * (step(0.0, gy0) - 0.5);

  vec4 gx1 = ixy1 / 7.0;
  vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;
  gx1 = fract(gx1);
  vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
  vec4 sz1 = step(gz1, vec4(0.0));
  gx1 -= sz1 * (step(0.0, gx1) - 0.5);
  gy1 -= sz1 * (step(0.0, gy1) - 0.5);

  vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
  vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
  vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
  vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
  vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
  vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
  vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
  vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);

  vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
  g000 *= norm0.x;
  g010 *= norm0.y;
  g100 *= norm0.z;
  g110 *= norm0.w;
  vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
  g001 *= norm1.x;
  g011 *= norm1.y;
  g101 *= norm1.z;
  g111 *= norm1.w;

  float n000 = dot(g000, Pf0);
  float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
  float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
  float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
  float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
  float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
  float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
  float n111 = dot(g111, Pf1);

  vec3 fade_xyz = fade(Pf0);
  vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
  vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
  float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
  return 2.2 * n_xyz;
}

void main() {
    float valuer = (noise(vec3(screenPosition.x*4.0, screenPosition.y*3.0, time)));
    float val1 = 0.25*(sign(valuer+0.2)-sign(valuer-0.2));
    float val2 = 0.125*(sign(valuer+0.4)-sign(valuer-0.4));
    outputColor = colorFilter*(val1+val2+0.25);
}

Most likely the Samsung Galaxy Young is executing the math at highp, and the ASUS MEMO tablet is executing at mediump. 三星Galaxy Young最有可能以较高的速度执行数学运算,而ASUS MEMO平板电脑则以中等的速度执行运算。

OpenGLES devices are not required to support highp in fragment shaders, but the above code looks very much like it will be required. 不需要OpenGLES设备在片段着色器中支持highp,但是上面的代码看起来非常需要它。

Is that even a full fragment shader? 那是一个完整的片段着色器吗? I thought GLES fragment shaders required you to specify a default precision or required you to specify precision on a per-variable basis. 我认为GLES片段着色器要求您指定默认精度或要求您为每个变量指定精度。 I see neither, so perhaps there is some information omitted. 我看不到,所以也许有些信息被省略了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM