Skip to content

Instantly share code, notes, and snippets.

@diska
Last active November 16, 2020 22:35
Show Gist options
  • Select an option

  • Save diska/9109b26bfba7e3dd5cfcba8de4fc32e7 to your computer and use it in GitHub Desktop.

Select an option

Save diska/9109b26bfba7e3dd5cfcba8de4fc32e7 to your computer and use it in GitHub Desktop.
「canvas2dでdepth書いてモデルデータ得るのはどんなかな」というWebGLコード。
<style>canvas,textarea{background-color: bisque;}</style>
<canvas width="512" height="512"></canvas><hr/>
<textarea id="LOG" cols="32" rows="15"></textarea>
<script>"use strict"
const vsrc=`attribute vec4 p;uniform sampler2D tx0;uniform mat4 m4;
varying vec4 v4;
void main(){gl_PointSize=7.0;
v4=texture2D(tx0,vec2(p.x/2.+.5,-p.y/2.+.5));
vec4 p2=p; p2.z-=v4.r/5.;
gl_Position=p2*m4;
gl_Position.xy*=5./(5.+gl_Position.z);
}`;
const fsrc=`precision mediump float;varying vec4 v4;
void main(){if(length(gl_PointCoord-.5)>.5)discard; gl_FragColor=v4;}`;
const π=Math.PI, res=64;
let gl=document.querySelector("canvas").getContext("webgl");
gl.enable(gl.DEPTH_TEST);
let pg=getMyProg(res);
pg.m4=gl.getUniformLocation(pg,"m4");
gl.useProgram(pg);
let m4=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];
function draw(now){
let t=now/1000;
m4[ 0]=Math.cos(t+0.0*π); m4[ 2]=Math.cos(t+0.5*π);
m4[ 8]=Math.cos(t-0.5*π); m4[10]=m4[ 0];
gl.uniformMatrix4fv(pg.m4,false,m4);
gl.clearColor(0,0,1,1); gl.clear(0x4000); gl.drawArrays(0,0,res*res);
requestAnimationFrame(draw);
}; requestAnimationFrame(draw);
//
function getMyProg(res){
let pg; try{pg=getPg(vsrc,fsrc);}catch(e){LOG.value=e;throw e;}
gl.uniform1i(gl.getUniformLocation(pg,"tx0"), getUnit(0, getImage()));
let p=gl.getAttribLocation(pg,"p");
gl.bindBuffer(gl.ARRAY_BUFFER, getBf(getDat(res)));{
gl.enableVertexAttribArray(p);
gl.vertexAttribPointer(p,2,gl.BYTE,true,0,0);
};gl.bindBuffer(gl.ARRAY_BUFFER,null);
return pg;
//
function getDat(res){
let dat=new Int8Array(res*res*2);
for(let i=0;i<res*res;i++){
dat[i*2+0]=((i%res)-res/2); dat[i*2+0]*=(256/res);
dat[i*2+1]=(i/res); dat[i*2+1]*=(256/res);
} return dat;
}
function getImage(){
let cv=document.createElement("canvas"), cc=cv.getContext("2d");
cc.canvas.width=cc.canvas.height=32; cc.font="16px serif";
cc.fillStyle="#333"; cc.fillRect(0,0,32,32);
cc.fillStyle="#999"; cc.fillRect(8,8,16,16);
cc.fillStyle="#cf0"; cc.fillText("はろー",0,24,32); return cv;
}
function getBf(dat){
let bf=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,bf);{
gl.bufferData(gl.ARRAY_BUFFER,dat,gl.STATIC_DRAW);
}; gl.bindBuffer(gl.ARRAY_BUFFER,null);
return bf;
};
function getUnit(unit,obj){
let tx=gl.createTexture();
gl.activeTexture(gl.TEXTURE0+unit);gl.bindTexture(gl.TEXTURE_2D,tx);{
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,obj);
gl.generateMipmap(gl.TEXTURE_2D);
}; return unit;
}
function getPg(vsrc,fsrc){
let pg=gl.createProgram();
let vs=gl.createShader(gl.VERTEX_SHADER); gl.attachShader(pg,vs);
let fs=gl.createShader(gl.FRAGMENT_SHADER); gl.attachShader(pg,fs);
gl.shaderSource(vs,vsrc); gl.compileShader(vs);
gl.shaderSource(fs,fsrc); gl.compileShader(fs); gl.linkProgram(pg);
if(gl.getProgramParameter(pg, gl.LINK_STATUS))return pg;
let err=`pg:${gl.getProgramInfoLog(pg)}\n`;
err+=`vs:${gl.getShaderInfoLog(vs)}\n`+`fs:${gl.getShaderInfoLog(fs)}\n`;
throw err;
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment