Last active
May 24, 2017 16:59
-
-
Save caesarsol/2a2ef7fc361b2010b256ccb060c8aabd to your computer and use it in GitHub Desktop.
regl-camera example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const regl = require('regl')() | |
const mat4 = require('gl-mat4') | |
const generateTorus = require('primitive-torus') | |
const generateCube = require('primitive-cube') | |
const generatePlane = require('primitive-plane') | |
const makeCamera = require('regl-camera') | |
const camera = makeCamera(regl, { | |
center: [0, 10, 0], | |
distance: 1, | |
minDistance: 100, | |
maxDistance: 8000, | |
far: 10000, | |
near: 1, | |
damping: 0.2, | |
theta: 0, | |
phi: 0, | |
}) | |
document.querySelector('canvas').addEventListener('mousewheel', (event) => { event.preventDefault() }) | |
function createModel (position = [0,0,0], scale = 1, rotation = [0,0,0]) { | |
var m = mat4.identity([]) | |
mat4.translate(m, m, position) | |
mat4.scale(m, m, [scale, scale, scale]) | |
mat4.rotate(m, m, rotation[0], [1,0,0]) | |
mat4.rotate(m, m, rotation[1], [0,1,0]) | |
mat4.rotate(m, m, rotation[2], [0,0,1]) | |
return m | |
} | |
function logMatrix (matrix) { | |
const strMatrix = Array.from(matrix) | |
.map((n, i) => n.toFixed(2)) | |
const maxW = Math.max(...strMatrix.map((n) => n.length)) | |
const spaces = (n) => Array(maxW - n.length + 1).fill(' ').join('') | |
const showMatrix = strMatrix | |
.map((n, i) => (1 + i) % 4 === 0 ? `${n}\n` : `${n}${spaces(n)}`) | |
.join('') | |
console.log(showMatrix) | |
} | |
const scene = regl({ | |
cull: { | |
enable: true, | |
}, | |
depth: { | |
enable: true, | |
mask: true, | |
func: 'less', | |
range: [0, 1] | |
}, | |
uniforms: { | |
lightDir: [0.3, 1, 0.6], | |
ambientLightAmount: 0.3, | |
diffuseLightAmount: 0.7, | |
}, | |
vert: ` | |
precision mediump float; | |
attribute vec3 position; | |
attribute vec3 normal; | |
varying vec3 vPosition; | |
varying vec3 vNormal; | |
uniform mat4 projection, view, model; | |
void main() { | |
vPosition = position; | |
vNormal = normal; | |
gl_Position = projection * view * model * vec4(position, 1); | |
} | |
`, | |
frag: ` | |
precision mediump float; | |
varying vec3 vNormal; | |
uniform vec3 lightDir; | |
uniform float ambientLightAmount; | |
uniform float diffuseLightAmount; | |
uniform vec3 color; | |
void main () { | |
vec3 tex = color; | |
float cosTheta = clamp(dot(vNormal, lightDir), 0.0, 1.0); | |
float cosAlpha = clamp(dot(vNormal, reflect(-lightDir, vNormal)) - 0.25, 0.0, 1.0); | |
vec3 ambient = ambientLightAmount * tex; | |
vec3 diffuse = diffuseLightAmount * tex * cosTheta; | |
vec3 reflect = diffuseLightAmount * (tex + vec3(0.3,0.3,0.3)) * pow(cosAlpha, 5.0); | |
gl_FragColor = vec4(ambient + diffuse + reflect, 1.0); | |
} | |
`, | |
}) | |
const plane = generatePlane() | |
const drawPlane = regl({ | |
elements: plane.cells, | |
attributes: { | |
position: plane.positions, | |
normal: plane.normals, | |
}, | |
uniforms: { | |
color: [0.2, 0.5, 0.7], | |
model: (_, props) => createModel(props.position, props.scale, [-Math.PI / 2, 0, 0]), | |
}, | |
cull: { | |
enable: false, | |
}, | |
}) | |
const box = generateCube() | |
const drawBox = regl({ | |
elements: box.cells, | |
attributes: { | |
position: box.positions, | |
normal: box.normals, | |
}, | |
uniforms: { | |
color: [0.9, 0.2, 0.0], | |
model: (_, props) => createModel(props.position, props.scale), | |
}, | |
// primitive: 'line loop', | |
}) | |
const torus = generateTorus({ | |
// majorSegments: 16, | |
// minorSegments: 16, | |
}) | |
const drawTorus = regl({ | |
elements: torus.cells, | |
attributes: { | |
position: torus.positions, | |
normal: torus.normals, | |
}, | |
uniforms: { | |
color: [0.9, 0.2, 0.0], | |
model: (_, props) => createModel(props.position, props.scale), | |
}, | |
}) | |
function frameCatch (func) { | |
const loop = regl.frame(() => { | |
try { | |
func() | |
} catch (err) { | |
console.error(err) | |
loop.cancel() | |
} | |
}) | |
} | |
frameCatch(() => { | |
regl.clear({ | |
color: [0, 0.1, 0, 0.5], | |
depth: 1 | |
}) | |
camera(() => { | |
scene(() => { | |
drawPlane({scale: 2000, position: [0, 0, 0]}) | |
drawBox({scale: 50, position: [0, 25 + 5, 0]}) | |
drawTorus({scale: 50, position: [150, 25 + 5, 0]}) | |
}) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment