Published
Edited
Nov 9, 2021
Insert cell
Insert cell
{
while (1) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
draw(spherePosition);
TWEEN.update();
yield gl.canvas;
}
}
Insert cell
drawProgramInfo = {
const shaders = {
vert: `#version 300 es
precision mediump float;
in vec3 position;
in vec3 normal;
in vec2 uv;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform vec4 shift;
out vec3 fragNormal;
out vec2 fragUV;
void main () {
fragUV = uv;
fragNormal = normal;
float theta = 3.14159*shift.w/180.;
float C = cos(theta);
float S = sin(theta);
vec3 vPosition = vec3(position.x*C-position.y*S, position.x*S+position.y*C,position.z);//(shift.x>4.99)?vec3(position.x*C-position.y*S, position.x*S+position.y*C,position.z):position;
vec3 vShift = vec3(shift.x*C-shift.y*S, shift.x*S+shift.y*C,shift.z);//(shift.x>4.99)?vec3(shift.x*C-shift.y*S, shift.x*S+shift.y*C,shift.z):shift.xyz;
gl_Position = projectionMatrix*viewMatrix*vec4(vPosition+vShift, 1);
}
`,
frag: `#version 300 es
precision mediump float;
in vec2 fragUV;
in vec3 fragNormal;
uniform sampler2D tex;
out vec4 outColor;
void main () {
vec3 textureColor = texture(tex, fragUV).xyz;
outColor = vec4(textureColor, 1);
}
`
};
errorBlock.style.height = "20px";
errorBlock.innerHTML = "Program Shader compilation successful";
return twgl.createProgramInfo(gl, [shaders.vert, shaders.frag], (message) => {
errorBlock.style.height = "400px";
errorBlock.innerHTML = "Scene Program Shader compilation error\n" + message;
});
}
Insert cell
errorBlock = html`<textarea style="height : 20px; width : ${width}px; font-size: 0.8em; display: block"></textarea>`
Insert cell
drawBufferInfo = twgl.createBufferInfoFromArrays(gl, {
position: {
numComponents: 3,
data: sphere.positions.flat()
},
normal: {
numComponents: 3,
data: sphere.normals.flat()
},
uv: {
numComponents: 2,
data: sphere.uvs.flat()
},
indices: {
numComponents: 3,
data: sphere.cells.flat()
}
})
Insert cell
draw = (shift) => {
const uniforms = {
viewMatrix,
projectionMatrix: perspectiveMatrix,
tex: checkerTexture,
shift: Object.values(spherePosition)
};
//mutable debug = uniforms;
gl.useProgram(drawProgramInfo.program);
twgl.setUniforms(drawProgramInfo, uniforms);
twgl.setBuffersAndAttributes(gl, drawProgramInfo, drawBufferInfo);
twgl.drawBufferInfo(gl, drawBufferInfo);
}
Insert cell
Object.values(spherePosition)
Insert cell
md`### Variables, functions`
Insert cell
spherePosition = ({x:0,y:0,z:0, theta:0})
Insert cell
{
const tween1 = new TWEEN.Tween(spherePosition).to({x: 5, y: 0, z: 0}, 2000).easing(TWEEN.Easing.Elastic.Out).delay(5000);
const tween2 = new TWEEN.Tween(spherePosition).to({theta: 360}, 5000);
const tween3 = new TWEEN.Tween(spherePosition).to({x: 0, y: 0, z: 0}, 1000);
const tween4 = new TWEEN.Tween(spherePosition).to({theta: 0}, 500);
tween1.chain(tween2);
tween2.chain(tween3);
tween3.chain(tween4);
tween4.chain(tween1);
tween1.start();
}
Insert cell
viewMatrix = {
const center = [0,0,0];
const distance = 10
const viewDirection = [0,0,distance];
const eye = [center[0]+viewDirection[0], center[1]+viewDirection[1], center[2]+viewDirection[2]];
const up = [0, 1, 0];
return mat4.lookAt([], eye, center, vec3.rotateZ([],[0,1,0],[0,0,0],0))
}
Insert cell
perspectiveMatrix = {
const aspect = canvasWidth/canvasHeight;
const radius = 1;
return mat4.perspective([],deg2radian(63), aspect,0.001*radius, 10*radius)
}
Insert cell
canvasWidth = 512
Insert cell
canvasHeight = 512
Insert cell
deg2radian = deg=>deg*Math.PI/180
Insert cell
mat4 = glMatrix.mat4
Insert cell
vec3 = glMatrix.vec3
Insert cell
C = Math.cos
Insert cell
S = Math.cos
Insert cell
md`### Texture data`
Insert cell
checkerTexture = twgl.createTexture(gl, {
mag: gl.NEAREST,
min: gl.MIPMAP,
wrap: gl.REPEAT,
width: 4,
height: 4,
src: [
255,
255,
255,
255,
128,
128,
128,
255,
255,
255,
255,
255,
128,
128,
128,
255,

128,
128,
128,
255,
255,
255,
255,
255,
128,
128,
128,
255,
255,
255,
255,
255,

255,
255,
255,
255,
128,
128,
128,
255,
255,
255,
255,
255,
128,
128,
128,
255,

128,
128,
128,
255,
255,
255,
255,
255,
128,
128,
128,
255,
255,
255,
255,
255
]
})
Insert cell
md`### WebGL2 context`
Insert cell
gl = {
const myCanvas = DOM.canvas(canvasWidth, canvasHeight);

const gl = myCanvas.getContext("webgl2", { stencil: true });
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.5, 0.4, 0.4, 1);
gl.clearStencil(0);
return gl;
}
Insert cell
md`### Libraries and imports`
Insert cell
TWEEN = require('tween.js')
Insert cell
glMatrix = require('https://bundle.run/gl-matrix@3.3.0')
Insert cell
import {sphere} from "@spattana/general-obj2sc"
Insert cell
reglCreate = require("regl")
Insert cell
twgl = require("twgl.js")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more