Skip to content

Commit

Permalink
add openable code block
Browse files Browse the repository at this point in the history
  • Loading branch information
shi-yan committed Jul 27, 2024
1 parent a500726 commit fcaf022
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 61 deletions.
22 changes: 11 additions & 11 deletions Advanced/mega_texture.html

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Advanced/skeleton_animation.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Advanced/toon_shading.html
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ <h2 >5.2 Toon Shading</h2><p>achieving realistisity is not the only goal of rend
fn fs_main(in: VertexOutput) -&gt; @location(0) vec4&lt;f32&gt; {
return vec4&lt;f32&gt;( 0.0,0.0,0.0,1.0);
}
</pre></code><div class="code-fragments-caption">5_02_toon_shading/index.html:37-68 Outline Shader</div></div><p>The above shader does the inflation in the clip space. The two parameters passed into the vertex shader are the vertex position in 3D and the vertex's normal in 3D. We convert the position to the clip space position as always. For the normal vector, we apply the normal matrix and then projection. notice that the w component is set to 0.0 because it is a vector.</p><p>after that, we need to inflate the clip space position. again, since the silhouette is in 2D, we don't want to touch the zw components, we leave them as they are. for the xy axis, we offset them by normalize(clip_normal.xy)*6.4/screenDim * out.clip_position.w. here, dividing the clip space normal by the screen dimension is to compensate for the screen size and aspect ratio. We want the silhouette width to be uniform regardless of the screen size and aspect ratio. timing it by out.clip_position is because the graphics pipeline will later divide the clip space position by the w component when converting it to the normalized device coordinates. to avoid further change to the silhouette thickness during this conversion, we premultiply it by the w.</p><p>the fragment shader is simple. we simply output pure black pixels. not let's examine the javascript code:</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=253>let { positionBuffer, normalBuffer, indexBuffer, indexSize } = await loadObj(device, '../data/teapot.obj');
</pre></code><div class="code-fragments-caption"><a target="_blank" href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html#5_02_toon_shading">5_02_toon_shading/index.html:37-68 Outline Shader</a></div></div><p>The above shader does the inflation in the clip space. The two parameters passed into the vertex shader are the vertex position in 3D and the vertex's normal in 3D. We convert the position to the clip space position as always. For the normal vector, we apply the normal matrix and then projection. notice that the w component is set to 0.0 because it is a vector.</p><p>after that, we need to inflate the clip space position. again, since the silhouette is in 2D, we don't want to touch the zw components, we leave them as they are. for the xy axis, we offset them by normalize(clip_normal.xy)*6.4/screenDim * out.clip_position.w. here, dividing the clip space normal by the screen dimension is to compensate for the screen size and aspect ratio. We want the silhouette width to be uniform regardless of the screen size and aspect ratio. timing it by out.clip_position is because the graphics pipeline will later divide the clip space position by the w component when converting it to the normalized device coordinates. to avoid further change to the silhouette thickness during this conversion, we premultiply it by the w.</p><p>the fragment shader is simple. we simply output pure black pixels. not let's examine the javascript code:</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=253>let { positionBuffer, normalBuffer, indexBuffer, indexSize } = await loadObj(device, '../data/teapot.obj');
this.positionBuffer = positionBuffer;
// The normal buffer contains vertex normals calculated as averages of adjacent surface normals.
this.normalBuffer = normalBuffer;
Expand Down Expand Up @@ -216,15 +216,15 @@ <h2 >5.2 Toon Shading</h2><p>achieving realistisity is not the only goal of rend
format: 'depth32float'
}
}
</pre></code><div class="code-fragments-caption">5_02_toon_shading/index.html:253-656 Outline Pipeline Setup</div></div><p>when we load the obj file, we have already established the normal buffer containing the vertex normals calculated as an average of adjacent surface normals. When setting up the pipeline for rendering the outline, we set the cullMode to front to peal the front side of the inflated object. Also, notice that we enable the depth testing here.</p><p>in the second part of this tutorial, we will look at how to achieve the painterly shading effect. painterly styles don't usually have smooth color transition as we see on a physically accurate picture. the color transition is often discretized. also the color use is also false colors that can't be described by lighting equations attempt to achieve physical accuracy.</p><p>but it is not difficult to achieve this discretized false color effect. all we need to do is introducing another layer of indirection by using a look up table. We will still using the same phong shading algorithm to calculate lighting as before. The difference is, before, we directly calculate the final color. this time, we only calculate a light intensity as a single value. then, we use a prebuild lookup table to transfer the intensity into colors. our lookup table is in 1D, and is able to convert a value in the range [0,1] into an arbitrary RGB color. in our setup, our 1D texture contains a few bands of false colors, our final image will be rendered using these false colors.</p><p>let's look at the shader first. Again, this shader is modified from the shadow map shader.</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=86>// Instead of setting colors as RGB, we use scalars here as we only want to calculate intensity.
</pre></code><div class="code-fragments-caption"><a target="_blank" href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html?highlight=253:259#5_02_toon_shading">5_02_toon_shading/index.html:253-656 Outline Pipeline Setup</a></div></div><p>when we load the obj file, we have already established the normal buffer containing the vertex normals calculated as an average of adjacent surface normals. When setting up the pipeline for rendering the outline, we set the cullMode to front to peal the front side of the inflated object. Also, notice that we enable the depth testing here.</p><p>in the second part of this tutorial, we will look at how to achieve the painterly shading effect. painterly styles don't usually have smooth color transition as we see on a physically accurate picture. the color transition is often discretized. also the color use is also false colors that can't be described by lighting equations attempt to achieve physical accuracy.</p><p>but it is not difficult to achieve this discretized false color effect. all we need to do is introducing another layer of indirection by using a look up table. We will still using the same phong shading algorithm to calculate lighting as before. The difference is, before, we directly calculate the final color. this time, we only calculate a light intensity as a single value. then, we use a prebuild lookup table to transfer the intensity into colors. our lookup table is in 1D, and is able to convert a value in the range [0,1] into an arbitrary RGB color. in our setup, our 1D texture contains a few bands of false colors, our final image will be rendered using these false colors.</p><p>let's look at the shader first. Again, this shader is modified from the shadow map shader.</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=86>// Instead of setting colors as RGB, we use scalars here as we only want to calculate intensity.
const diffuseConstant:f32 = 1.0;
const specularConstant:f32 = 0.0;
const ambientConstant:f32 = 0.0;
</pre></code><div class="code-fragments-separator">• • •</div><pre><code class="language-javascript code-block" startNumber=168>// We apply the same Phong shading, but instead of deriving the final color, we obtain an intensity.
var intensity:f32 = max(dot(-lightDir, n), 0.0)* diffuseConstant + specular(-lightDir, viewDir, n, shininess) * specularConstant;
// With the light intensity, we look up the final color.
var diffuse:vec3&lt;f32&gt; = textureSample(t_shade, s_shade, intensity * visibility).xyz;
</pre></code><div class="code-fragments-caption">5_02_toon_shading/index.html:86-171 Painterly Shader</div></div><p>And finally, let's see, on the javascript side, how this 1D lookup texture is set up.</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=260>// 1D texture, width is hardcoded to 128.
</pre></code><div class="code-fragments-caption"><a target="_blank" href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html?highlight=86:90#5_02_toon_shading">5_02_toon_shading/index.html:86-171 Painterly Shader</a></div></div><p>And finally, let's see, on the javascript side, how this 1D lookup texture is set up.</p><div class="code-fragments"><pre><code class="language-javascript code-block" startNumber=260>// 1D texture, width is hardcoded to 128.
const shadeTextureDesc = {
size: [128],
dimension: '1d',
Expand Down Expand Up @@ -268,7 +268,7 @@ <h2 >5.2 Toon Shading</h2><p>achieving realistisity is not the only goal of rend
}, { width: 128 });
// Wait for completion.
await device.queue.onSubmittedWorkDone();
</pre></code><div class="code-fragments-caption">5_02_toon_shading/index.html:260-303 Setup 1D Lookup Texture</div></div><p>Together with the outline shader, we now have the toon shading effect:</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="placeholder.jpg" alt="Image to Show the Result" sources='[]' /><div class="img-title">Image to Show the Result</div></div></p>
</pre></code><div class="code-fragments-caption"><a target="_blank" href="https://shi-yan.github.io/WebGPUUnleashed/code/code.html#5_02_toon_shading">5_02_toon_shading/index.html:260-303 Setup 1D Lookup Texture</a></div></div><p>Together with the outline shader, we now have the toon shading effect:</p><p><div class="img-container"><img class="img" onclick="openImage(this)" src="placeholder.jpg" alt="Image to Show the Result" sources='[]' /><div class="img-title">Image to Show the Result</div></div></p>
</article>
<a href="https://github.com/shi-yan/WebGPUUnleashed/discussions" target="_blank" class="comment"><svg
style="margin-right:10px;vertical-align: middle;" xmlns="http://www.w3.org/2000/svg" height="32"
Expand Down
Loading

0 comments on commit fcaf022

Please sign in to comment.