ShaderMaterial Tangent Space
by Matt
CSS
html,
body,
canvas {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: block;
}
JavaScript
import * as THREE from '//cdn.skypack.dev/[email protected]'
import { OrbitControls } from '//cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js'
// Scene, Camera
const scene = new THREE.Scene()
scene.background = new THREE.Color('black')
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
camera.position.set(0, 2, 3)
// WebGL renderer
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// OrbitControls
const controls = new OrbitControls(camera, renderer.domElement)
controls.autoRotate = true
// Mesh
const geometry = new THREE.SphereGeometry(1, 32, 32)
const material = new THREE.ShaderMaterial({
vertexShader: `
attribute vec4 tangent;
varying vec3 vTangent;
void main() {
vTangent = tangent.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
varying vec3 vTangent;
void main() {
vec3 rgb = normalize(vTangent);
rgb = rgb * 0.5 + 0.5;
gl_FragColor = vec4(rgb, 1.);
}
`
})
geometry.computeTangents()
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
const axes = new THREE.AxesHelper(5)
scene.add(axes)
// Render loop
function animate() {
requestAnimationFrame(animate)
controls.update()
renderer.render(scene, camera)
}
animate()
// Window sizing
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
}