TypeScript
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
CSS
html, body {
margin: 0;
overflow: hidden;
width: 100%;
height: 100%;
position: relative;
}
.canvasWebGL {
position: absolute;
top: 0%;
width: 100%;
height: 100%;
}
.canvas2D {
position: absolute;
top: 50%;
width: 100%;
height: 100%;
}
JavaScript
var camera, scene, renderer, vp, stats, sphere, normalsMat;
// WebGL boilerplate
function init() {
// WebGL Renderer
vp = new THREE.Vector2(window.innerWidth, window.innerHeight);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(vp.x, vp.y);
renderer.domElement.classList.add("canvasWebGL");
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xe1e1e1);
// camera
camera = new THREE.PerspectiveCamera(30, vp.x / vp.y, 0.05, 150);
camera.position.z = 10;
// stats
stats = new Stats();
// Normals material
normalsMat = new THREE.MeshNormalMaterial();
// Modify color so only Z-normal is visible
normalsMat.onBeforeCompile = function( shader ) {
var newFrag = shader.fragmentShader.replace(
'gl_FragColor = vec4( packNormalToRGB( normal ), opacity );', // Replace this line...
'gl_FragColor = vec4(0.0, 0.0, normal.z, opacity );' // ... with this line
//'gl_FragColor = vec4(normal.x, 0.0, 0.0, opacity );' // ... or this one for X-value
);
shader.fragmentShader = newFrag;
}
// sphere
sphere = new THREE.Mesh(
new THREE.SphereBufferGeometry( 1, 64, 64 ),
normalsMat
);
scene.add(sphere);
const helper = new THREE.AxesHelper(3);
sphere.add(helper)
// append all to DOM
document.body.appendChild(renderer.domElement);
document.body.appendChild(stats.domElement);
window.addEventListener("resize", () => {
vp.set(window.innerWidth, window.innerHeight);
renderer.setSize(vp.x, vp.y);
camera.aspect = vp.x / vp.y;
camera.updateProjectionMatrix();
});
}
function animate(s) {
sphere.position.set(
Math.cos(s / 2000) * 2,
Math.sin(s / 1000) * 2.5,
0
);
// Render scene to canvas
renderer.render(scene, camera);
stats.update();
requestAnimationFrame(animate);
}
init();
animate(0);