Public
Edited
Feb 11
1 fork
Insert cell
Insert cell
{
let canvas = html`<canvas width="${width}" height="400"/>`

let projection = glm.mat4.create();
let model = glm.mat4.create();
let view = glm.mat4.create();
let ident = glm.mat4.create();
let sphere = null;

function setup(gl) {
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.3,0.3,0.3,1.0);
glm.mat4.perspective(projection,(45*Math.PI)/180,width/400,0.1,100);
sphere = sphereGeometry(gl);
gl_utils.viewHandler(canvas,(x,y,z)=>{
glm.mat4.lookAt(view,[x,y,z],[0,0,0],[0,1,0]);
});
}
function draw(gl) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
sphere.draw({model, view, projection});
}
return gl_utils.appLoop(canvas,{setup,draw});
}
Insert cell
function sphereGeometry(gl) {

let atribs = geraAtributos(50,50,esfera(3));

const prog = gl_utils.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 a_texture = gl.getAttribLocation(prog,"a_texture");
let vao = gl.createVertexArray()
gl.bindVertexArray(vao)
gl.enableVertexAttribArray(a_position);
gl.enableVertexAttribArray(a_normal);
gl.enableVertexAttribArray(a_texture);

let position_vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,position_vbo);
gl.bufferData(gl.ARRAY_BUFFER,atribs.posicoes,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,atribs.normais,gl.STATIC_DRAW);
gl.vertexAttribPointer(a_normal, 3, gl.FLOAT, false, 0, 0);

let texture_vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,texture_vbo);
gl.bufferData(gl.ARRAY_BUFFER,atribs.textura,gl.STATIC_DRAW);
gl.vertexAttribPointer(a_texture, 2, gl.FLOAT, false, 0, 0);

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

function draw(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.TRIANGLE_STRIP,atribs.indices.length,gl.UNSIGNED_SHORT,0);
}

return { draw };
}
Insert cell
Insert cell
Insert cell
function esfera(r) {
return (u,v) => {
let theta = u*Math.PI-Math.PI/2;
let phi = v*2*Math.PI;
return [
r * Math.cos(theta) * Math.cos(phi),
r * Math.sin(theta),
r * Math.cos(theta) * Math.sin(phi)
]
}
}
Insert cell
// * * * * * * * * * * │ * Vertice Comum V(i,j)
// │
// X * * * * * * * * * * X │ X Vertices Degenerados:
// │ N LINHAS(i)
// X * * * * * * * * * * X │ V(i,0)
// │ V(i+1,0)-1
// * * * * * * * * * * │
// V(i,j) = i*M+j
// ───────────────────
// M COLUNAS(j)

function geraIndices(M,N) {
let indices = new Uint16Array(M*(N-1)*2+(N-2)*2);
let k = 0;
for(let i=0; i<N-1; i++) {
if(i>0) {
// Triângulos degenerados no inicio / fim de uma linha
indices[k++] = (i+1)*(M)-1;
indices[k++] = i*(M);
}
for(let j=0; j<M; j++) {
indices[k++] = i*(M)+j;
indices[k++] = (i+1)*(M)+j;
}
}
return indices;
}


Insert cell
function geraPosicoes(M,N,f) {
let posicoes = new Float32Array(M*N*3);
let k = 0;
for(let i=0; i<M; i++) {
let u = i/(M-1);
for(let j=0; j<N; j++) {
let v = j/(N-1);
let [x,y,z] = f(u,v);
posicoes[k++] = x;
posicoes[k++] = y;
posicoes[k++] = z;
}
}
return posicoes;
}
Insert cell
function geraNormais(M,N,f) {
const epsilon = 0.001;
let normais = new Float32Array(M*N*3);
let k = 0;
for(let i=0; i<M; i++) {
let u = i/(M-1);
let du = u + epsilon;
for(let j=0; j<N; j++) {
let v = j/(N-1);
let dv = v + epsilon;
let [x,y,z] = f(u,v);
let [x1,y1,z1] = f(du,v);
let [x2,y2,z2] = f(u,dv);
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);
normais[k++] = vnx/vlen;
normais[k++] = vny/vlen;
normais[k++] = vnz/vlen;
}
}
return normais;
}


Insert cell
function geraCoordenadasTextura(M,N) {
let coordenadasTextura = new Float32Array(M*N*2);
let k = 0;
for(let i=0; i<M; i++) {
let u = i/(M-1);
for(let j=0; j<N; j++) {
let v = j/(N-1);
coordenadasTextura[k++] = u;
coordenadasTextura[k++] = v;
}
}
return coordenadasTextura;
}


Insert cell
function geraAtributos(M,N,f) {
return {
indices: geraIndices(M,N),
posicoes: geraPosicoes(M,N,f),
normais: geraNormais(M,N,f),
textura: geraCoordenadasTextura(M,N)
}
}
Insert cell
glm = import("gl-matrix")
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