Skip to content

Instantly share code, notes, and snippets.

@diska
Created December 17, 2021 06:56
Show Gist options
  • Save diska/209a708cfa41556ec21358c0fc7b6f7d to your computer and use it in GitHub Desktop.
Save diska/209a708cfa41556ec21358c0fc7b6f7d to your computer and use it in GitHub Desktop.
WebGL自由研究。Suzanne.gltf専用ローダ(viewer)54行。
<canvas width="256" height="256"></canvas><hr/>
<script>"use strict";
let cx=document.querySelector("canvas").getContext("webgl");
let vsrc=`attribute vec4 p,n,uv;uniform mat4 m;varying vec3 vn;
void main(){gl_Position=p*m;gl_Position.xy/=1.+gl_Position.z*.5;vn=(n*m).xyz;}`;
let fsrc=`precision highp float;varying vec3 vn;
void main(){gl_FragColor=vec4(vec3(1)*dot(vec3(-.5),vn),1);}`;
let pg=cx.createProgram();{
let vs=cx.createShader(cx.VERTEX_SHADER);cx.attachShader(pg,vs);
let fs=cx.createShader(cx.FRAGMENT_SHADER);cx.attachShader(pg,fs);
cx.shaderSource(vs,vsrc);cx.compileShader(vs);
cx.shaderSource(fs,fsrc);cx.compileShader(fs);cx.linkProgram(pg);
}; cx.enable(cx.DEPTH_TEST);
let bf=cx.createBuffer(), ef=cx.createBuffer();
let gltf=[],vNum=0, AB=cx.ARRAY_BUFFER,EB=cx.ELEMENT_ARRAY_BUFFER;
let ldBf=(b)=>{
cx.bindBuffer(AB,bf);
cx.bufferData(AB,b,cx.STATIC_DRAW);
cx.bindBuffer(AB,null);
cx.bindBuffer(EB,ef);
cx.bufferData(EB,b.slice(62912,62912+5808),cx.STATIC_DRAW);
cx.bindBuffer(EB,null);
}
let ldJson=(r)=>{
fetch(r.buffers[0].uri).then(r=>r.arrayBuffer()).then(ldBf);gltf=r;
}
let ldAcc=()=>{
for(let i=0;i<gltf.accessors.length;i++){
let bufferView=gltf.accessors[i].bufferView;
let type=gltf.accessors[i].type;
let byteOffset=gltf.bufferViews[bufferView].byteOffset;
let size={"SCALAR":1,"VEC2":2,"VEC3":3,"VEC4":4}[type];
if(size!=1){
cx.bindBuffer(AB,bf);
cx.enableVertexAttribArray(bufferView);
cx.vertexAttribPointer(bufferView,size,cx.FLOAT,false,0,byteOffset);
cx.bindBuffer(AB,null);
}
}; vNum=gltf.accessors[3].count;
}
let mp=cx.getUniformLocation(pg,"m");
let m=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,2]);
let th, cos=Math.cos;
let draw=(now)=>{
th=now/1500, m[0]=m[10]=cos(th), m[2]=cos(th+Math.PI/2), m[8]=-m[2];
cx.useProgram(pg); cx.uniformMatrix4fv(mp,false,m);
cx.clearColor(0,0,.1,1);cx.clear(0x4000);cx.bindBuffer(EB,ef);{
cx.drawElements(cx.TRIANGLES,vNum,cx.UNSIGNED_SHORT,0);
};cx.bindBuffer(EB,null);
requestAnimationFrame(draw);
}
let ftJson=f=>fetch(f).then(r=>r.json()).then(ldJson);
ftJson("suzanne.gltf").then(ldAcc).then(draw);
</script>
@diska
Copy link
Author

diska commented Dec 17, 2021

多分arrayBufferを拾う練習がテーマだったので、bufferのoffset等の設定は手動です。
gltfファイルから読むか、JSON型変数"gltf"から拾ってください。
CORS云々はVS CodeのHTML viewerとかでやると楽かもです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment