DepthMap 的編碼
前言
最近要實現 DepthMap ,但在手機平台實現發生了問題,在 GLES2 可能會不支援 Depth texture ,如果不支援就直接放棄嗎?有個方法可以解決,就是將深度值"編碼"後解到 RGBA8 的 Texture ,這個方法的實作又些麻煩,在此做個紀錄。內容
在 DepthMap 的實現裡需要把深度值寫到 Texture 或 DepthBuffer 裡,但不幸的是 GLES2 並不保證支援 Depth texture ,更別說是 R32 格式的 Texture,有替代方案嗎?可以參考 WebGL Tutorial: Directional Shadow Mapping without extensions 裡的作法,將深度值"編碼"寫到 RGBA8 的 Texture ,在取值的時候要"解碼"後取得深度值。該如何從 Float 的深度值"編碼"到 RGBA8 的數值,請看以下
vec4 encodeFloat (float depth) { const vec4 bitShift = vec4( 256 * 256 * 256, 256 * 256, 256, 1.0 ); const vec4 bitMask = vec4( 0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 ); vec4 comp = fract(depth * bitShift); comp -= comp.xxyz * bitMask; return comp; }
這是將深度值編碼成4個 Float 的 Function ,編碼後透過 Fragment shader 直接輸出到 RGBA8 的 Texture 上,接著在取得 DepthMap 的數值時要經過解碼,請看以下
float decodeFloat (vec4 color) { const vec4 bitShift = vec4( 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1 ); return dot(color, bitShift); }
解碼後就可以取得原先的深度值。
沒有留言:
張貼留言