Skip to content

Commit

Permalink
add fake 3d
Browse files Browse the repository at this point in the history
  • Loading branch information
shi-yan committed Aug 2, 2024
1 parent b21725f commit 63f08c5
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 14 deletions.
21 changes: 11 additions & 10 deletions 2D_Techniques/implementing_fake_3d.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@

<div id="article-container">
<article>
<h2 >2.6 Implementing Fake 3D</h2><p>in this example, we will look at a fake 3d effect. for a real 3d scene, if we move our camera position in the screen plane, we will notice the 3d effect called parallax, because objects further away move slower than objects nearby.</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="parallax.gif" alt="Train Window Presents a Real Life Parallax Effect" sources='["https://www.artstation.com/artwork/Z5vndm"]' /><div class="img-title">Train Window Presents a Real Life Parallax Effect<a class="img-source" target="_blank" href="https://www.artstation.com/artwork/Z5vndm">[SOURCE]</a></div></div></p><p>given a 2d picture, if we have a pairing depth map, we can fake this parallex effect to produce a 3D effect. the idea is simple, given a movement offset, we offset the texture coordinates. The amount of the offset is determined by the movement as well as the depth map, such that if a pixel is far away, we do not offset the texture coordinate as much as that of a nearby pixel.</p><p>To generate a depth map for your image, we can use the <a class="link" href="pytorch.org/hub/intelisl_midas_v2" target="_blank">MiDaS model</a>. please refer to the link for the details about how to create a depth map. In this example, we have a sample image with a paired depth image.</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="placeholder.jpg" alt="Show the Depth Map" sources='[]' /><div class="img-title">Show the Depth Map</div></div></p><p>to make our demo more interesting, we want to use mouse to control the movement vector. The vector is calculated by subtract the current mouse position and the canvas center:</p><pre><code class="language-javascript code-block"> canvas.addEventListener('mousemove', function (event) {
let mousePos = getMousePos(canvas, event);
mousePos = { x: mousePos.x * 2.0 / canvas.width - 1.0, y: mousePos.y * 2.0 / canvas.height - 1.0 };
//console.log('mousemove', mousePos);
requestAnimationFrame(() =&gt; {
render([mousePos.x * 0.01, mousePos.y* 0.01]);
});
});</code></pre><p>the magic happens in the fragment shader:</p><pre><code>
@group(0) @binding(0)
<h2 >2.6 Implementing Fake 3D</h2><p>in this example<a class="footnote-ref" href="#footnote_1">[1]</a>, we will look at a fake 3d effect. for a real 3d scene, if we move our camera position in the screen plane, we will notice the 3d effect called parallax, because objects further away move slower than objects nearby.</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="parallax.gif" alt="Train Window Presents a Real Life Parallax Effect" sources='["https://www.artstation.com/artwork/Z5vndm"]' /><div class="img-title">Train Window Presents a Real Life Parallax Effect<a class="img-source" target="_blank" href="https://www.artstation.com/artwork/Z5vndm">[SOURCE]</a></div></div></p><p>given a 2d picture, if we have a pairing depth map, we can fake this parallax effect to produce a 3D effect. the idea is simple, given a movement offset, we offset the texture coordinates. The amount of the offset is determined by the movement as well as the depth map, such that if a pixel is far away, we do not offset the texture coordinate as much as that of a nearby pixel.</p><p>To generate a depth map for your image, we can use the <a class="link" href="pytorch.org/hub/intelisl_midas_v2" target="_blank">MiDaS model</a>. please refer to the link for the details about how to create a depth map. In this example, we have a sample image with a paired depth image.</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="thumb_portraitanddepth.png" original_src="portraitanddepth.png" alt="The Picture Used in This Sample and Its Generated Depth" sources='[]' /><div class="img-title">The Picture Used in This Sample and Its Generated Depth</div></div></p><p>to make our demo more interesting, we want to use mouse to control the movement vector. The vector is calculated by subtract the current mouse position and the canvas center, such that the further our mouse is alway from the center of the image, we will offset the image more in the opposite direction.</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=242>canvas.addEventListener('mousemove', function (event) {
let mousePos = getMousePos(canvas, event);
mousePos = { x: mousePos.x * 2.0 / canvas.width - 1.0, y: mousePos.y * 2.0 / canvas.height - 1.0 };
//console.log('mousemove', mousePos);
requestAnimationFrame(() =&gt; {
render([mousePos.x * 0.01, mousePos.y* 0.01]);
});
});
</pre></code><div class="code-fragments-caption"><a target="_blank" href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html?highlight=241:248#2_06_fake_3d">2_06_fake_3d/index.html:242-249 Getting the Offset Vector From Mouse</a></div></div><p>the magic happens in the fragment shader:</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=31>@group(0) @binding(0)
var t_diffuse: texture_2d&lt;f32&gt;;
@group(0) @binding(1)
var t_depth: texture_2d&lt;f32&gt;;
Expand All @@ -168,7 +168,8 @@ <h2 >2.6 Implementing Fake 3D</h2><p>in this example, we will look at a fake 3d

return color;
}
</code></pre><p>in the shader, we do two texture sampling. the first time is against the depth map to obtain the depth. The second time is from the actual image, but we will adjust the texture coordinates. the adjustment is the mouse offset scaled by the depth.</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="placeholder.jpg" alt="Show Parallex" sources='[]' /><div class="img-title">Show Parallex</div></div></p>
</pre></code><div class="code-fragments-caption"><a target="_blank" href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html?highlight=30:45#2_06_fake_3d">2_06_fake_3d/index.html:31-46 Offset the Texture Coordinates Based on Depth and the Offset Vector</a></div></div><p>in the shader, we do two texture sampling. the first time is against the depth map to obtain the depth. The second time is from the actual image, but we will adjust the texture coordinates. the adjustment is the mouse offset scaled by the depth.</p><p>This is a very simple program, but the end result is very interesting. Check it out for your self, try to replace the image with your own.</p><a href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html#2_06_fake_3d" target="_blank" class="comment"><svg style="margin-right:10px;vertical-align: middle;" xmlns="http://www.w3.org/2000/svg" height="32"
width="32" fill="#dadadb" viewBox="0 -960 960 960"><path d="M189-160q-60 0-102.5-43T42-307q0-9 1-18t3-18l84-336q14-54 57-87.5t98-33.5h390q55 0 98 33.5t57 87.5l84 336q2 9 3.5 18.5T919-306q0 61-43.5 103.5T771-160q-42 0-78-22t-54-60l-28-58q-5-10-15-15t-21-5H385q-11 0-21 5t-15 15l-28 58q-18 38-54 60t-78 22Zm3-80q19 0 34.5-10t23.5-27l28-57q15-31 44-48.5t63-17.5h190q34 0 63 18t45 48l28 57q8 17 23.5 27t34.5 10q28 0 48-18.5t21-46.5q0 1-2-19l-84-335q-7-27-28-44t-49-17H285q-28 0-49.5 17T208-659l-84 335q-2 6-2 18 0 28 20.5 47t49.5 19Zm348-280q17 0 28.5-11.5T580-560q0-17-11.5-28.5T540-600q-17 0-28.5 11.5T500-560q0 17 11.5 28.5T540-520Zm80-80q17 0 28.5-11.5T660-640q0-17-11.5-28.5T620-680q-17 0-28.5 11.5T580-640q0 17 11.5 28.5T620-600Zm0 160q17 0 28.5-11.5T660-480q0-17-11.5-28.5T620-520q-17 0-28.5 11.5T580-480q0 17 11.5 28.5T620-440Zm80-80q17 0 28.5-11.5T740-560q0-17-11.5-28.5T700-600q-17 0-28.5 11.5T660-560q0 17 11.5 28.5T700-520Zm-360 60q13 0 21.5-8.5T370-490v-40h40q13 0 21.5-8.5T440-560q0-13-8.5-21.5T410-590h-40v-40q0-13-8.5-21.5T340-660q-13 0-21.5 8.5T310-630v40h-40q-13 0-21.5 8.5T240-560q0 13 8.5 21.5T270-530h40v40q0 13 8.5 21.5T340-460Zm140-20Z"/></svg>Launch Playground - 2_06_fake_3d</a><table class="footnote-def"><tr class="footnote-row" id="footnote_1"><td>[1]: </td><td><p>This tutorial is inspired by this <a class="link" href="https://tympanus.net/codrops/2019/02/20/how-to-create-a-fake-3d-image-effect-with-webgl/" target="_blank">WebGL tutorial</a>.</p></td></tr></table>
</article>

<div class="older_newer_link_section">
Expand Down
Binary file added 2D_Techniques/portraitanddepth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 2D_Techniques/thumb_portraitanddepth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 0 additions & 4 deletions code/2_06_fake_3d/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
}

// Fragment shader

@group(0) @binding(0)
var t_diffuse: texture_2d<f32>;
@group(0) @binding(1)
Expand All @@ -45,7 +44,6 @@

return color;
}

</script>

<script>
Expand Down Expand Up @@ -241,7 +239,6 @@
await device.queue.onSubmittedWorkDone();
offsetUniformBufferUpdate.destroy();
}

canvas.addEventListener('mousemove', function (event) {
let mousePos = getMousePos(canvas, event);
mousePos = { x: mousePos.x * 2.0 / canvas.width - 1.0, y: mousePos.y * 2.0 / canvas.height - 1.0 };
Expand All @@ -250,7 +247,6 @@
render([mousePos.x * 0.01, mousePos.y* 0.01]);
});
});

requestAnimationFrame(() => {
render([0.0, 0.0]);
});
Expand Down

0 comments on commit 63f08c5

Please sign in to comment.