2020年2月17日 星期一

DepthMap 的編碼

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

沒有留言:

張貼留言