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
			| 
								 
											3 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>
							 |