2016-12-14 2 views
0

Я пытаюсь сделать симплекс шум на андроид, основываясь на этом примере:Неточное шейдер точность на андроид по сравнению с WebGL

https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl

После преобразования кода и компиляции на устройстве, я понял, что шаблон далеко не случайный. Я разбил код на самую основную часть, где я все еще вижу большую разницу между рабочим столом (я тестирую их на 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? (2d шум побежал просто отлично)

ответ

2

Очень вероятно, что ваш настольный графический процессор использует точность fp32 для вычисления (даже если в шейдере указать mediump, что требует только fp16).

Если вы установили precision highp float, это сработает лучше? Это заставит вычисление с плавающей запятой fp32. Обратите внимание, что не все мобильные устройства поддерживают highp - это стало обязательным только в OpenGL ES 3.x, поэтому некоторые графические процессоры OpenGL ES 2.x поддерживают только вычисления fp16.

(Какое устройство вы работаете на?)

+0

Я только проверил highp на нижнем устройстве, это ARM Mali-400 MP2 (двухъядерный). Лучше с Adreno 305, который поддерживает es 3.0, также поддерживает highp, что решило мою проблему. Примечание для кого-либо еще, имеющего эту проблему, вы можете проверить поддержку точности: http://stackoverflow.com/questions/4414041/what-is-the-precision-of-highp-floats-in-glsl-es -2-0-for-iphone-ipod-touch-ipad glGetShaderPrecisionFormat возвращает нули, если highp не поддерживается. – andras

+0

Серия Mali-400 - это только OpenGL ES 2.x и не поддерживает fp32, поэтому в этом случае вы просто получите fp16 – solidpixel

Смежные вопросы