You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
6.8 KiB
124 lines
6.8 KiB
2 years ago
|
<!DOCTYPE html><html lang="en"><head>
|
||
|
<meta charset="utf-8">
|
||
|
<title>Debugging - GLSL</title>
|
||
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
||
|
<meta name="twitter:card" content="summary_large_image">
|
||
|
<meta name="twitter:site" content="@threejs">
|
||
|
<meta name="twitter:title" content="Three.js – Debugging - GLSL">
|
||
|
<meta property="og:image" content="https://threejs.org/files/share.png">
|
||
|
<link rel="shortcut icon" href="/files/favicon_white.ico" media="(prefers-color-scheme: dark)">
|
||
|
<link rel="shortcut icon" href="/files/favicon.ico" media="(prefers-color-scheme: light)">
|
||
|
|
||
|
<link rel="stylesheet" href="/manual/resources/lesson.css">
|
||
|
<link rel="stylesheet" href="/manual/resources/lang.css">
|
||
|
<!-- Import maps polyfill -->
|
||
|
<!-- Remove this when import maps will be widely supported -->
|
||
|
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
|
||
|
|
||
|
<script type="importmap">
|
||
|
{
|
||
|
"imports": {
|
||
|
"three": "../../build/three.module.js"
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="container">
|
||
|
<div class="lesson-title">
|
||
|
<h1>Debugging - GLSL</h1>
|
||
|
</div>
|
||
|
<div class="lesson">
|
||
|
<div class="lesson-main">
|
||
|
<p>This site so far does not teach GLSL just like it does not teach JavaScript.
|
||
|
Those are really large topics. If you want to learn GLSL consider checking out
|
||
|
<a href="https://webglfundamentals.org">these articles</a> as a starting place.</p>
|
||
|
<p>If you already know GLSL then here are a few tips for debugging.</p>
|
||
|
<p>When I'm making a new GLSL shader and nothing appears generally
|
||
|
the first thing I do is change the fragment shader to return a solid
|
||
|
color. For example at the very bottom of the shader I might put</p>
|
||
|
<pre class="prettyprint showlinemods notranslate lang-glsl" translate="no">void main() {
|
||
|
|
||
|
...
|
||
|
|
||
|
gl_FragColor = vec4(1, 0, 0, 1); // red
|
||
|
}
|
||
|
</pre>
|
||
|
<p>If I see the object I was trying to draw then I know the issue is
|
||
|
related to my fragment shader. It could be anything like bad textures,
|
||
|
uninitialized uniforms, uniforms with the wrong values but at least
|
||
|
I have a direction to look.</p>
|
||
|
<p>To test some of those I might start trying to draw some of the inputs.
|
||
|
For example if I'm using normals in the fragment shader then I might
|
||
|
add</p>
|
||
|
<pre class="prettyprint showlinemods notranslate lang-glsl" translate="no">gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1);
|
||
|
</pre>
|
||
|
<p>Normals go from -1 to +1 so by multiplying by 0.5 and adding 0.5 we get
|
||
|
values that go from 0.0 to 1.0 which makes them useful for colors.</p>
|
||
|
<p>Try this with some things you know work and you'll start getting an idea
|
||
|
of what normals <em>normally</em> look like. If your normals don't look normal
|
||
|
then you have some clue where to look. If you're manipulating normals
|
||
|
in the fragments shader you can use the same technique to draw the
|
||
|
result of that manipulation.</p>
|
||
|
<div class="threejs_center"><img src="../resources/images/standard-primitive-normals.jpg" style="width: 650px;"></div>
|
||
|
|
||
|
<p>Similarly if we're using textures there will be texture coordinates and we
|
||
|
can draw them with something like</p>
|
||
|
<pre class="prettyprint showlinemods notranslate lang-glsl" translate="no">gl_FragColor = vec4(fract(vUv), 0, 1);
|
||
|
</pre>
|
||
|
<p>The <code class="notranslate" translate="no">fract</code> is there in case we're using texture coordinates that go outside
|
||
|
the 0 to 1 range. This is common if <code class="notranslate" translate="no">texture.repeat</code> is set to something greater
|
||
|
than 1.</p>
|
||
|
<div class="threejs_center"><img src="../resources/images/standard-primitive-uvs.jpg" style="width: 650px;"></div>
|
||
|
|
||
|
<p>You can do similar things for all values in your fragment shader. Figure out
|
||
|
what their range is likely to be, add some code to set <code class="notranslate" translate="no">gl_FragColor</code> with
|
||
|
that range scaled to 0.0 to 1.0</p>
|
||
|
<p>To check textures try a <a href="/docs/#api/en/textures/CanvasTexture"><code class="notranslate" translate="no">CanvasTexture</code></a> or a <a href="/docs/#api/en/textures/DataTexture"><code class="notranslate" translate="no">DataTexture</code></a> that you
|
||
|
know works.</p>
|
||
|
<p>Conversely, if after setting <code class="notranslate" translate="no">gl_FragColor</code> to red I still see nothing
|
||
|
then I have a hint my issue might be in the direction of the things
|
||
|
related to the vertex shader. Some matrices might be wrong or my
|
||
|
attributes might have bad data or be setup incorrectly.</p>
|
||
|
<p>I'd first look at the matrices. I might put a breakpoint right after
|
||
|
my call to <code class="notranslate" translate="no">renderer.render(scene, camera)</code> and then start expanding
|
||
|
things in the inspector. Is the camera's world matrix and projection
|
||
|
matrix at least not full of <code class="notranslate" translate="no">NaN</code>s? Expanding the scene and looking
|
||
|
at its <code class="notranslate" translate="no">children</code> I'd check that the world matrices look reasonable (no <code class="notranslate" translate="no">NaN</code>s)
|
||
|
and last 4 values of each matrix look reasonable for my scene. If I
|
||
|
expect my scene to be 50x50x50 units and some matrix shows 552352623.123
|
||
|
clearly something is wrong there.</p>
|
||
|
<div class="threejs_center"><img src="../resources/images/inspect-matrices.gif"></div>
|
||
|
|
||
|
<p>Just like we did for the fragment shader we can also draw values from the
|
||
|
vertex shader by passing them to the fragment shader. Declare a varying
|
||
|
in both and pass the value you're not sure is correct. In fact if my
|
||
|
shader use using normals I'll change the fragment shader to display them
|
||
|
like is mentioned above and then just set <code class="notranslate" translate="no">vNormal</code> to the value I want
|
||
|
to display but scaled so the values go from 0.0 to 1.0. I then look at the
|
||
|
results and see if they fit my expectations.</p>
|
||
|
<p>Another good thing to do is use a simpler shader. Can you draw your data
|
||
|
with <a href="/docs/#api/en/materials/MeshBasicMaterial"><code class="notranslate" translate="no">MeshBasicMaterial</code></a>? If you can then try it and make sure it shows
|
||
|
up as expected.</p>
|
||
|
<p>If not what's the simplest vertex shader that will let you visualize your
|
||
|
geometry? Usually it's as simple as</p>
|
||
|
<pre class="prettyprint showlinemods notranslate lang-glsl" translate="no">gl_Position = projection * modelView * vec4(position.xyz, 1);
|
||
|
</pre>
|
||
|
<p>If that works start adding in your changes a little at a time.</p>
|
||
|
<p>Yet another thing you can do is use the
|
||
|
<a href="https://chrome.google.com/webstore/detail/shader-editor/ggeaidddejpbakgafapihjbgdlbbbpob?hl=en">Shader Editor extension for Chrome</a>
|
||
|
or similar for other browsers. It's a great way to look at how other shaders
|
||
|
are working. It's also good as you can make some of the changes suggested above
|
||
|
live while the code is running.</p>
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<script src="/manual/resources/prettify.js"></script>
|
||
|
<script src="/manual/resources/lesson.js"></script>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
</body></html>
|