ThreeJS Setting the Right Aspect Ratio for the Camera

One quick note for myself and anyone who will ever use this…

If you are working with an abnormal size canvas, you need to do some math to set the size of the renderer to be correct with the aspect ratio:

[pastacode lang=”javascript” manual=”let%20rect%20%3D%20this.renderer.domElement.getBoundingClientRect()%3B%0A%09%09camera.aspect%20%3D%20rect.width%20%2F%20rect.height%3B%0A%09%09camera.updateProjectionMatrix()%3B%0A%09%09renderer.setSize(%20rect.width%2C%20rect.height%20)%3B” message=”” highlight=”” provider=”manual”/]

Basically, you are working out the bounding box in which the scene will exist. To do that, we need to give the camera an aspect ratio and a size for the renderer. Setting the size on the renderer is easy; just send the width and height. The aspect ratio is also pretty easy; just divide the width by the height and you are good to go.

Both the width and height can be found by using “getBoundingClientRect()”.

NOTE: This site is all about helpful hints tricks and tips. The posts lately have been short on purpose. For one, I’m busy AF and don’t have the time to post anything of great detail. Additionally, I believe in simplicity. You can visit, find something helpful and move on with your life.

As always I appreciate your feedback, please leave a comment if you feel I’m leading people down a less than idea path or just comment because you like talking IDC.

Simple Shader with ThreeJS

Ok folks, it doesn’t get easier than this. If you want to start writing shaders in the browser but can’t figure out how to create your shader program, ThreeJS has you covered.

To write a shader in GLSL (oenGL Shading Language) you first need to let the browser know where you’re going to put your program. Some the shader stuff might look like a combination of javascript and C to you, however, it’s actually GLSL. That’s the language you write shaders in for the web. In order to start writing shaders, you first need to have something to shade. Which means you need to have atleast a simple 3 dimensional object upon which the shader can begin “shading”. The most simple is a plane (two triangles put together into a square) which you will use below to start experimenting with shaders.

Just like drawing with canvas and javascript you need a context. WebGL (the technology threeJS uses) uses the same canvas element that you might be used to drawing with in 2D. Basically instead of get a context of “2D” we are going to get the canvas context of “webgl” instead.

[pastacode lang=”javascript” manual=”const%20gl%20%3D%20canvas.getContext(‘webgl’%2C%20%7B%0A%20%20antialias%3A%20false%2C%0A%20%20depth%3A%20false%0A%7D)%3B” message=”” highlight=”” provider=”manual”/]

Follow the instructions below to begin creating your own shaders. If you are having trouble getting started and don’t want to create your own contexts, you can easily use shadertoy to do the heavy lifting for you. It allows you to start writing GLSL immediately.

In your JS

[pastacode lang=”javascript” manual=”var%20camera%20%3D%20new%20THREE.Camera()%3B%0A%09camera.position.z%20%3D%201%3B%0A%0A%09var%20scene%20%3D%20new%20THREE.Scene()%3B%0A%0A%09var%20uniforms%20%3D%20%7B%0A%09%09time%3A%20%7B%20type%3A%20%22f%22%2C%20value%3A%201.0%20%7D%2C%0A%09%09resolution%3A%20%7B%20type%3A%20%22v2%22%2C%20value%3A%20new%20THREE.Vector2()%20%7D%0A%09%7D%3B%0A%0A%09var%20material%20%3D%20new%20THREE.ShaderMaterial(%20%7B%0A%09%09uniforms%3A%20uniforms%2C%0A%09%09vertexShader%3A%20document.getElementById(%20’vertexShader’%20).innerText%2C%0A%09%09fragmentShader%3A%20document.getElementById(%20’fragmentShader’%20).innerText%0A%09%7D)%3B%0A%0A%09var%20mesh%20%3D%20new%20THREE.Mesh(%20new%20THREE.PlaneGeometry(%202%2C%202%20)%2C%20material%20)%3B%0A%0A%09scene.add(%20mesh%20)%3B%0A%0A%09var%20canvas%20%3D%20document.querySelector(%22.lense-flare%22)%3B%0A%09var%20parent%20%3D%20canvas.parentElement%3B%0A%09var%20renderer%20%3D%20new%20THREE.WebGLRenderer(%7B%20canvas%3A%20canvas%20%7D)%3B%0A%09renderer.setSize(%20parent.clientWidth%2C%20parent.clientHeight%20)%3B%0A%0A%09uniforms.resolution.value.x%20%3D%20parent.clientWidth%3B%0A%09uniforms.resolution.value.y%20%3D%20parent.clientHeight%3B%0A%09var%20startTime%20%3D%20Date.now()%3B%0A%0A%09animate()%3B%0A%0A%09function%20animate()%20%7B%0A%09%09requestAnimationFrame(%20animate%20)%3B%0A%09%09render()%3B%0A%09%7D%0A%0A%09function%20render()%20%7B%0A%09%09var%20elapsedMilliseconds%20%3D%20Date.now()%20-%20startTime%3B%0A%09%09var%20elapsedSeconds%20%3D%20elapsedMilliseconds%20%2F%201000.%3B%0A%09%09uniforms.time.value%20%3D%2060.%20*%20elapsedSeconds%3B%0A%09%09renderer.render(%20scene%2C%20camera%20)%3B%0A%09%7D” message=”” highlight=”” provider=”manual”/]

 

In your head:

[pastacode lang=”markup” manual=”%3Cscript%20id%3D%22vertexShader%22%20type%3D%22x-shader%2Fx-vertex%22%3E%0A%09%09%09uniform%20float%20time%3B%0A%09%09%09uniform%20vec2%20resolution%3B%0A%09%09%09void%20main()%09%7B%0A%09%09%09%09gl_Position%20%3D%20vec4(%20position%2C%201.0%20)%3B%0A%09%09%09%7D%0A%09%09%3C%2Fscript%3E%0A%09%09%3Cscript%20id%3D%22fragmentShader%22%20type%3D%22x-shader%2Fx-fragment%22%3E%0A%09%09%09uniform%20float%20time%3B%0A%09%09%09uniform%20vec2%20resolution%3B%0A%09%09%09void%20main()%09%7B%0A%09%09%09%09float%20x%20%3D%20mod(time%20%2B%20gl_FragCoord.x%2C%2020.)%20%3C%2010.%20%3F%201.%20%3A%200.%3B%0A%09%09%09%09float%20y%20%3D%20mod(time%20%2B%20gl_FragCoord.y%2C%2020.)%20%3C%2010.%20%3F%201.%20%3A%200.%3B%0A%09%09%09%09gl_FragColor%20%3D%20vec4(vec3(min(x%2C%20y))%2C%201.)%3B%0A%09%09%09%7D%0A%09%09%3C%2Fscript%3E” message=”” highlight=”” provider=”manual”/]