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);
}
解碼後就可以取得原先的深度值。
參考資料
WebGL Tutorial: Directional Shadow Mapping without extensions