← Playgrounds一覧に戻る
EXT_texture_norm16
WebGL 2に16bitの正規化形式のテクスチャを足す拡張です。符号なしの16bitの整数を、シェーダーでは0.0〜1.0の小数として線形補間付きで読めます。
Playground
同じ16bitの高さデータを3つの形式で比べる
起伏の小さい16bitの高さデータを、R8・R16F・R16_EXTのテクスチャにそれぞれ入れ、くぼみの底を黒、丘のてっぺんを白にして描きます。R8とR16Fでは値が丸められて段差が現れ、R16_EXTだけが滑らかなまま残ります。
くぼみの底(32664)を黒、丘のてっぺん(32918)を白にして描いています
R88bitの正規化形式R16F16bitの浮動小数点数R16_EXT16bitの正規化形式テクスチャへの入れ方(JavaScriptの擬似コード)
// 256×256画素の高さを、1画素16bitの整数(0〜65535)で並べた配列
// 中身は高さ32768の平地に小さな丘とくぼみがある地形で、
// くぼみの底が32664、丘のてっぺんが32918
const heights = new Uint16Array(256 * 256);
// R8: 0〜255に丸めて、Uint8Arrayで渡す
const r8 = Uint8Array.from(heights, (h) => Math.round((h / 65535) * 255));
gl.texImage2D(..., gl.R8, ..., gl.UNSIGNED_BYTE, r8);
// R16F: 0.0〜1.0の小数にして、Float32Arrayで渡す
const r16f = Float32Array.from(heights, (h) => h / 65535);
gl.texImage2D(..., gl.R16F, ..., gl.FLOAT, r16f);
// R16_EXT: Uint16Arrayのまま渡す
const ext = gl.getExtension('EXT_texture_norm16');
gl.texImage2D(..., ext.R16_EXT, ..., gl.UNSIGNED_SHORT, heights);3つに共通のシェーダー(GLSLの抜粋)
// テクスチャから高さを0.0〜1.0の小数で読む
float height = texture(u_heights, v_uv).r;
// くぼみの底(low)を黒の0.0、丘のてっぺん(high)を白の1.0にする
// low・highも、くぼみの底と丘のてっぺんを65535で割った0.0〜1.0の値
float shade = (height - low) / (high - low);