Public
Edited
Feb 11
Insert cell
Insert cell
simpleCubeCanvas ={
let projection = glm.mat4.create();
let model = glm.mat4.create();
let view = glm.mat4.create();
let canvas = createWebGLCanvas(width,400,gl=>{
let cube = pyramidGeometry(gl);
glm.mat4.lookAt(view,[-3,-3,3],[0,0,0],[0,1,0]);
glm.mat4.perspective(projection,(45*Math.PI)/180,width/400,0.1,100);
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.4,0.4,0.4,1.0);

return () => {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
cube({model, view, projection});
}
});
canvas.updateView = (x,y,z) => {
glm.mat4.lookAt(view,[x,y,z],[0,0,0],[0,1,0]);
};
viewHandler(canvas,canvas.updateView);
return canvas;
}
Insert cell
function calculaNormal(a,b,c) {
let [x,y,z] = a;
let [x1,y1,z1] = b;
let [x2,y2,z2] = c;
let [v1x,v1y,v1z] = [x1-x, y1-y, z1-z];
let [v2x,v2y,v2z] = [x2-x, y2-y, z2-z];
let [vnx, vny, vnz] = [v1y*v2z-v1z*v2y, v1z*v2x-v1x*v2z, v1x*v2y-v1y*v2x];
let vlen = Math.sqrt(vnx*vnx+vny*vny+vnz*vnz);
return [ vnx/vlen, vny/vlen, vnz/vlen ];
}
Insert cell
function pyramidGeometry(gl) {

const RED = [ 1.0, 0.0, 0.0 ];
const YELLOW = [ 1.0, 1.0, 0.0 ];
const GREEN = [ 0.0, 1.0, 0.0 ];
const CYAN = [ 0.0, 1.0, 1.0 ];
const BLUE = [ 0.0, 0.0, 1.0 ];
const PURPLE = [ 1.0, 0.0, 1.0 ];
const [A, B, C, D, E] = [
[ 0.0, 1.0, 0.0 ], // Topo
[-1.0, 0.0, 1.0 ], // Base
[ 1.0, 0.0, 1.0 ], // Base
[ 1.0, 0.0, -1.0 ], // Base
[-1.0, 0.0, -1.0 ] // Base
];

// Faces triangulares (4 lados + 2 para a base)
const position = new Float32Array([
...A, ...B, ...C, // Frente
...A, ...C, ...D, // Direita
...A, ...D, ...E, // Trás
...A, ...E, ...B, // Esquerda
...B, ...C, ...D, // Base 1
...B, ...D, ...E // Base 2
]);

const color = new Float32Array([
...RED, ...RED, ...RED,
...GREEN, ...GREEN, ...GREEN,
...BLUE, ...BLUE, ...BLUE,
...YELLOW, ...YELLOW, ...YELLOW,
...CYAN, ...CYAN, ...CYAN,
...CYAN, ...CYAN, ...CYAN
]);

const index = new Uint16Array([
0, 1, 2, // Frente
3, 4, 5, // Direita
6, 7, 8, // Trás
9, 10, 11, // Esquerda
12, 13, 14, // Base 1
15, 16, 17 // Base 2
]);

const normal = new Float32Array([
...calculaNormal(A,B,C), ...calculaNormal(A,B,C), ...calculaNormal(A,B,C),
...calculaNormal(A,C,D), ...calculaNormal(A,C,D), ...calculaNormal(A,C,D),
...calculaNormal(A,D,E), ...calculaNormal(A,D,E), ...calculaNormal(A,D,E),
...calculaNormal(A,E,B), ...calculaNormal(A,E,B), ...calculaNormal(A,E,B),
...calculaNormal(B,C,D), ...calculaNormal(B,C,D), ...calculaNormal(B,C,D),
...calculaNormal(B,D,E), ...calculaNormal(B,D,E), ...calculaNormal(B,D,E)
]);

const prog = createProgram(gl, [
[ gl.VERTEX_SHADER, vertexShader ],
[ gl.FRAGMENT_SHADER, fragmentShader ]
]);
let a_position = gl.getAttribLocation(prog,"a_position");
let a_normal = gl.getAttribLocation(prog,"a_normal");
let vao = gl.createVertexArray()
gl.bindVertexArray(vao)
gl.enableVertexAttribArray(a_position);
gl.enableVertexAttribArray(a_normal);

let position_vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,position_vbo);
gl.bufferData(gl.ARRAY_BUFFER,position,gl.STATIC_DRAW);
gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 0, 0);

let normal_vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,normal_vbo);
gl.bufferData(gl.ARRAY_BUFFER,normal,gl.STATIC_DRAW);
gl.vertexAttribPointer(a_normal, 3, gl.FLOAT, false, 0, 0);

let index_vbo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,index_vbo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,index,gl.STATIC_DRAW);

return (uniforms) => {
gl.bindVertexArray(vao);
gl.useProgram(prog);
gl.uniformMatrix4fv(gl.getUniformLocation(prog,"model"),false,uniforms.model);
gl.uniformMatrix4fv(gl.getUniformLocation(prog,"view"),false,uniforms.view);
gl.uniformMatrix4fv(gl.getUniformLocation(prog,"projection"),false,uniforms.projection);
gl.drawElements(gl.TRIANGLES,index.length,gl.UNSIGNED_SHORT,0);
}
}
Insert cell
Insert cell
Insert cell
function createWebGLCanvas(width, height, drawFactory) {
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const gl = canvas.getContext("webgl2");
if (!gl) throw new Error("WebGL unsupported");
const draw = drawFactory(gl);
const f = () => {
draw();
window.requestAnimationFrame(f);
};
window.requestAnimationFrame(f);
return canvas;
}
Insert cell
pedras = FileAttachment("texture_2.jpg").image()
Insert cell
Insert cell
glm = import("gl-matrix")
Insert cell
import {viewHandler} from "@rmauro/cubo-mouse"

Insert cell
import {gl_utils} from "@rmauro/webgl-utils"
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