一個(gè)華為手機(jī)專屬Bug
今天又發(fā)現(xiàn)了一個(gè) 華為手機(jī) 專屬bug华畏,如下圖:
原本 LUX 表現(xiàn)正常的水在我的 華為 Meta 30 上表現(xiàn)呈 條帶狀鉴竭。
從表現(xiàn)上看跟 深度計(jì)算 相關(guān),定位了一下原因宜猜,發(fā)現(xiàn)問題代碼如下:
#if defined(SHADER_API_GLES)
float refractedSceneDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV + offset, 0);
#else
float refractedSceneDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * saturate(screenUV + offset) * 0.9999f ).x;
#endif
SHADER_API_GLES 代表的是 gles2.0 設(shè)備,走的是 SAMPLE_TEXUTRE 的分支硝逢。
而我們工程的 Graphics APIs 首選項(xiàng)是 OpenGLES3姨拥,并且我的華為手機(jī)也支持,所以最終代碼走的是 LOAD_TEXTURE 這個(gè)分支渠鸽。
Texture Sample Vs Texture Load
那么 SAMPLE_TEXTURE 和 LOAD_TEXTURE2D 有什么區(qū)別呢叫乌?
以 GLES3.0 代碼為例:
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
關(guān)于 Texture Sample 和 Texture Load 的差別,可以參考這個(gè)帖子:Difference between texture.Sample and texture.Load徽缚,簡(jiǎn)單來說憨奸,兩者差別如下:
Texture Sample是紋理采樣,會(huì)應(yīng)用 紋理尋址 和 紋理過濾凿试。
Texture Load只是加載某一個(gè)特定位置的 texel排宰。
道理上,作者希望 gles3.0 以上的設(shè)備都用 LOAD_TEXTURE 的方式來獲取深度值红省,但是偏偏遇到華為手機(jī)就跪了额各。
原因
華為手機(jī)的 浮點(diǎn)數(shù) 問題我不是第一次遇到了,之前也寫過吧恃,https://baddogzz.github.io/2020/04/27/Mali-Float-Presion/虾啦。
這次這個(gè)問題應(yīng)該還是浮點(diǎn)數(shù)計(jì)算的問題,使用 Texture Load 方式,我們需要根據(jù) UV坐標(biāo) 計(jì)算出 texel坐標(biāo)傲醉,代碼如下:
_CameraDepthTexture_TexelSize.zw * saturate(screenUV + offset) * 0.9999f
如果 texel坐標(biāo) 超出紋理范圍蝇闭,LOAD_TEXTURE2D 會(huì)返回 0。
針對(duì)這種情況硬毕,作者已經(jīng)對(duì) screenUV + offset 做了 saturate 保護(hù)并且還乘了 0.9999f呻引,想必也是為了規(guī)避浮點(diǎn)數(shù)計(jì)算的誤差,但是華為手機(jī)依然還是跪了吐咳。
修正
修正的方式也簡(jiǎn)單逻悠,這里不再區(qū)分 SHADER_API_GLES,統(tǒng)一走 SAMPLE_TEXTURE 即可韭脊,如下:
float refractedSceneDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV + offset, 0);
這樣改之后童谒,我的 Meta 30 終于正常了,如下圖:
此外沪羔,我發(fā)現(xiàn)如果 Graphics APIs 選 Vulkan饥伊,我的華為手機(jī)也正常,好吧蔫饰,我服了琅豆。
個(gè)人主頁
本文的個(gè)人主頁鏈接:https://baddogzz.github.io/2020/10/19/HW-LoadX-Bug/
。
好了篓吁,拜拜茫因!