2012-07-02 91 views
7

我很努力獲得下一個簡單的算法,在三星Galaxy工作SIII噪聲算法在三星Galaxy SIII(GLES)失敗

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)); 
.... 

的代碼完全生成三星Galaxy S1和谷歌Nexus S的期望噪聲但在使用ARM Mali-400/MP4的新款智能手機中完全失敗。

任何人都可以發現這個算法有什麼問題嗎?或者也許理解爲什麼它會失敗?

+2

失敗如何?你是否在檢查錯誤/警告的信息? – Tim

+0

完全沒有錯誤,根本不顯示任何噪點像素。整體形象是好的,但沒有任何噪音。 – PerracoLabs

+2

嗯,那麼不確定。我只是建議一次剝下一層,直到你能理解爲什麼。例如。 fract()是否工作? (sin())工作嗎?sin(點((()))工作嗎?等 – Tim

回答

9

你的問題可能來自於一個大數字的sin。這個結果取決於sin的確切實現,這是不可用的。顯然,Mali芯片使用的sin函數比其他函數有更多可預測的結果。

在我看來,你應該使用an actual noise function,而不是這個東西。至少它會在硬件上產生可預測的結果。

+1

我試過這個選項,因爲我雖然會是最好的,我有很奇怪的結果。而不是噪音,我使用了庫中的下一個:https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl – PerracoLabs

3

在ARM論壇上對這個問題進行了一些討論:http://forums.arm.com/index.php?/topic/16364-random-number-with-mali-400-mp/

問題是因爲Mali GPU上片段着色器中的FP16精度。基本上,在調用fract的時候沒有剩餘的小數位(因爲乘法器非常大),所以根本沒有任何「噪聲」。如果你使常量更小,你會開始得到非零值,但它們不會很吵。 (我不完全確定價值是如何挑選的,以及它的not clear where this algorithm came from)。

從技術上講,這種噪聲算法依賴於更高的(中?高?)精度浮點運算,這在片段着色器中是可選的。根據this other post,您可以通過檢查glGetString(GL_EXTENSIONS)中的「OES_fragment_precision_high」擴展名來檢查平臺支持的片段着色器精度。

尼科爾答案中的webgl-noise項目似乎不易受浮點截斷問題的影響(它似乎使事物處於更緊密的邊界)。但是,它的週期大約爲300,並且它會產生比您目前獲得的「白色」(或「粉紅色」)噪音更多的「結構化」噪音。它是一個非常出色的庫,所以即使它不是替代品,它的價值仍然體現在代碼中。

+0

我最終使用了webgl-noise庫,儘管我仍在試圖尋找替代方案,因爲算法過於龐大,除了有時(超過我想要的)產生的噪音看起來完全不像噪音,特別是在與深色混合時,至今爲止,除了webgl-noise項目之外,我還沒有找到任何替代方案。 – PerracoLabs