Алгоритм шума в Samsung Galaxy SIII (GLES)

Я пытаюсь получить следующий простой алгоритм, работающий в Samsung Galaxy SIII

float rand(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

....
vec3 color = texture2D(u_texture, v_texcoord);
gl_FragColor.rgb = color + vec3(rand(gl_FragCoord.xy + time / 1000.0));
....

Код генерирует совершенно ожидаемый шум в Samsung Galaxy S1 и Google Nexus S. Но он полностью не работает на новом смартфоне, который использует ARM Mali-400/MP4.

Кто-нибудь может заметить что-то не так с этим алгоритмом? Или, может быть, понять, почему это может не получиться?

Ответ 1

Вероятно, ваша проблема связана с принятием sin большого числа. Результат этого зависит от точной реализации sin, которая недоступна. Очевидно, что функция sin, используемая чипом Mali, имеет более предсказуемые результаты с большими числами, чем другие.

Мне кажется, что вы должны использовать фактическую функцию шума, а не эту вещь. По крайней мере, он будет иметь предсказуемые результаты по всему оборудованию.

Ответ 2

Немного обсуждать эту проблему на форумах ARM: http://forums.arm.com/index.php?/topic/16364-random-number-with-mali-400-mp/.

Проблема заключается из-за точности FP16 в флеш-шейдерах на Мали-графическом процессоре. В принципе, до тех пор, пока время fract не вызывается (поскольку множители настолько велики), до сих пор не осталось ни одного дробного бита, так что вы вообще не получите никакого "шума". Если вы уменьшите константы, вы начнете получать ненулевые значения, но они не будут шумными. (Я не совсем уверен, как были выбраны значения, а не понял, откуда этот алгоритм пришел).

Технически этот алгоритм шума опирается на операции с плавающей запятой с более высокой (средней? высокой?) точностью, которые являются необязательными в фрагментарных шейдерах. В соответствии с это другое сообщение вы можете проверить точность поддерживаемой платформы в шейдерах фрагментов, проверив расширение "OES_fragment_precision_high" в glGetString(GL_EXTENSIONS).

Проект webgl-noise в ответ Nicol не кажется восприимчивым к вопросам усечения с плавающей запятой (похоже, что он более жесткая привязка). Тем не менее, он имеет период около 300, и он генерирует более "структурированный" шум, чем "белый" (или "розовый" ) шум, который вы в настоящее время получаете. Его отличная библиотека, тем не менее, поэтому стоит работать в вашем коде, даже если это не замена.