Skip to content

Instantly share code, notes, and snippets.

@diska
Last active February 2, 2021 15:42
Show Gist options
  • Select an option

  • Save diska/202d511ead0f34c464dde2bd8a6ca84b to your computer and use it in GitHub Desktop.

Select an option

Save diska/202d511ead0f34c464dde2bd8a6ca84b to your computer and use it in GitHub Desktop.
webglの「viewportとscissorとclearあたりの挙動の関係」を学習するために書いてみたコード。
<style>textarea{background-color: burlywood;}</style>
<canvas width="384" height="256"></canvas><hr/>
<textarea id="LOG" cols="48" rows="14"></textarea>
<script>"use strict";
const vsrc=`attribute vec4 p;uniform mat4 m;
void main(){
gl_Position=p*m;gl_Position.w=1.+gl_Position.z*.5;
gl_PointSize=6./gl_Position.w;
}`;
const fsrc=`precision highp float;
uniform vec4 c;
void main(){
float f=1.+gl_FragCoord.z;
gl_FragColor=vec4(vec3(c.rgb/(f*f)),1);
}`;
let cx=document.querySelector("canvas").getContext("webgl");
let pg; try{pg=getPg(vsrc,fsrc)}catch(e){LOG.value+=e;throw e}
cx.useProgram(pg);
let p=cx.getAttribLocation(pg,"p");
let m=cx.getUniformLocation(pg,"m");
let pc=cx.getUniformLocation(pg,"c");
let md=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);
let data=new Int8Array(3000);
for(let i=0;i<3000;i++){data[i]=Math.random()*128-64;}
let bf=cx.createBuffer(); cx.bindBuffer(cx.ARRAY_BUFFER,bf);{
cx.bufferData(cx.ARRAY_BUFFER,new Int8Array(data),cx.STATIC_DRAW);
cx.vertexAttribPointer(0,3,cx.BYTE,true,0,0);
cx.enableVertexAttribArray(0);
}; cx.bindBuffer(cx.ARRAY_BUFFER,null);
cx.enable(cx.SCISSOR_TEST); cx.enable(cx.DEPTH_TEST);
function draw(now){
let th=now/1000, c=Math.cos(th),s=Math.sin(th);
md[0]=c; md[2]=s; md[8]=-s; md[10]=c;
cx.uniformMatrix4fv(m,false,md);
cx.uniform4fv(pc,[0,1,0,1]);
cx.scissor(0,0,256,128); cx.viewport(0,0,256,128);
cx.clearColor(.3,.0,.0,1); cx.clear(0x4000); cx.drawArrays(0,0,1000);
cx.uniformMatrix4fv(m,false,md);
cx.uniform4fv(pc,[1,0,0,1]);
cx.scissor(256,0,128,128); cx.viewport(256,0,128,128);
cx.clearColor(.0,.3,.0,1); cx.clear(0x4000); cx.drawArrays(0,0,1000);
md[0]=c; md[2]=-s; md[8]=s; md[10]=c;
cx.uniformMatrix4fv(m,false,md);
cx.uniform4fv(pc,[1,1,0,1]);
cx.scissor(0,128,128,128); cx.viewport(0,128,128,128);
cx.clearColor(.0,.0,0.3,1); cx.clear(0x4000); cx.drawArrays(0,0,1000);
cx.uniformMatrix4fv(m,false,md);
cx.uniform4fv(pc,[1,1,1,1]);
cx.scissor(128,128,256,128); cx.viewport(128,128,256,128);
cx.clearColor(.3,.3,.3,1); cx.clear(0x4000); cx.drawArrays(0,0,1000);
cx.uniform4fv(pc,[.5,.5,.5,1]);
cx.scissor(0,0,384,256); cx.viewport(0,0,384,256);
cx.drawArrays(0,0,1000);
requestAnimationFrame(draw);
}; requestAnimationFrame(draw);
function getPg(vsrc,fsrc){
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);
if(cx.getProgramParameter(pg,cx.LINK_STATUS)) return pg;
let log=`pg:${cx.getProgramInfoLog(pg)}\n`;
log+=`vs:${cx.getShaderInfoLog(vs)}\nfs:${cx.getShaderInfoLog(fs)}\n`;
throw log;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment