実現したいこと
A-FrameでParallax Occulusion Mappingのシェーダーを実装しています。
しかし、作成したコードの出力は期待する結果とは異なっているように見えます。
コードのどの部分が良くないのかわかりません。
どの部分に問題があり、描画がうまくいかないのでしょうか?
動作するコードはこちらに共有しました。
https://glitch.com/edit/#!/a-frame-parallax-occulusion-mapping
実現したいこと
- Parallax Occulusion Mappingが適切に描画されるようにする
前提
以下のWebサイトを参考にParallax Occulusion Mappingのシェーダーを実装しました。
https://learnopengl.com/Advanced-Lighting/Parallax-Mapping
該当のソースコード
html
1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="UTF-8" /> 5 <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> 6 <script src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js"></script> 7 <script src="./main.js"></script> 8 <script> 9 AFRAME.registerShader("parallax-occulusion-mapping", { 10 schema: { 11 uTexture: { type: "map", is: "uniform" }, // テクスチャ 12 uDepth: { type: "map", is: "uniform" }, // 深度マップ 13 reverse: { type: "bool", is: "uniform", default: true }, // 高さマップを反転するか 14 numLayers: { 15 type: "float", 16 is: "uniform", 17 default: 8.0, 18 min: 4.0, 19 max: 256.0, 20 }, // number of depth layers 21 }, 22 vertexShader: ` 23 varying vec2 vUv; 24 varying vec3 vViewPosition; // ビュー座標系での頂点座標 25 void main() { 26 // fragment shaderのための変数を計算 27 vUv = uv; 28 vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0); 29 vViewPosition = modelViewPosition.xyz; 30 // vertex shaderの出力を計算 31 gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 32 } 33 `, 34 fragmentShader: ` 35 precision highp float; 36 varying vec2 vUv; 37 varying vec3 vViewPosition; 38 uniform sampler2D uTexture; 39 uniform sampler2D uDepth; 40 uniform float numLayers; 41 uniform bool reverse; 42 float getDepth(vec2 xy) { 43 float v = texture2D(uDepth, xy).r; 44 if(reverse) return 1.0-v; 45 else return v; 46 } 47 void main() { 48 // 初期化 -------------------------------- 49 vec3 viewDir = normalize(vViewPosition); // 頂点からカメラへのベクトル 50 float STEP_DEPTH = 1.0 / numLayers; // 各レイヤのサイズ 51 vec2 STEP_POS = (viewDir.xy / viewDir.z) * STEP_DEPTH; // レイヤごとのテクスチャ軸方向の、ベクトルPからの移動量 52 53 // deltaを探索 ---------------------------------- 54 // 探索の初期値 55 float currentLayerDepth = 0.0; // レイヤ深さ 56 vec2 currentPos = vUv.xy; // 衝突後のテクスチャ座標のための変数 57 float currentMapDepth = getDepth(currentPos); // マップ深さ 58 float i=0.0; 59 for (i = 0.0; i < numLayers; i++) 60 { 61 currentPos -= STEP_POS; // P方向にテクスチャ座標を移動 62 currentMapDepth = getDepth(currentPos); // 更新した座標で深度値を取得 63 currentLayerDepth += STEP_DEPTH; // 次のレイヤの深度を取得する 64 if(currentLayerDepth > currentMapDepth) break; 65 } 66 // 線形補完 -------------------------------- 67 vec2 prevPos = currentPos + STEP_POS; // 衝突前のテクスチャ座標 68 float prevLayerDepth = currentLayerDepth - STEP_DEPTH; 69 float prevMapDepth = getDepth(prevPos); 70 float currentDepthDiff = currentLayerDepth - currentMapDepth; 71 float prevDepthDiff = prevMapDepth - prevLayerDepth; 72 73 // テクスチャ軸の線形補完 74 float weight = prevDepthDiff / (prevDepthDiff + currentDepthDiff); 75 vec2 finalPos = currentPos + (1.0 - weight) * STEP_POS; 76 77 // 視差マッピングの計算 ------------------------ 78 // テクスチャを取得 79 vec4 color = texture2D(uTexture, finalPos); 80 gl_FragColor = color; 81 } 82 `, 83 }); 84 </script> 85 </head> 86 <body> 87 <a-scene stats loading-screen="dotsColor: gray; backgroundColor: lightgray"> 88 <a-assets timeout="30000"> 89 <img 90 id="img1" 91 src="https://cdn.glitch.global/07ec46d7-6f8d-4aba-88c7-9f2074e79760/ganges_river_pebbles_diff_480p.jpg?v=1714894399240" 92 /> 93 <img 94 id="img1_D" 95 src="https://cdn.glitch.global/07ec46d7-6f8d-4aba-88c7-9f2074e79760/ganges_river_pebbles_disp_480p.png?v=1714894398359" 96 /> 97 </a-assets> 98 <a-camera id="my_camera"> 99 <a-cursor></a-cursor> 100 </a-camera> 101 <a-entity environment="preset: default;"></a-entity> 102 <a-image 103 id="aimg1" 104 position="0 1.2 -1" 105 scale="1 1 1" 106 material="shader:parallax-occulusion-mapping; uTexture:#img1; uDepth:#img1_D;" 107 ></a-image> 108 </a-scene> 109 </body> 110</html>
補足情報(FW/ツールのバージョンなど)
- html5
- A-Frame 1.2.0
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。