Skip to content

Instantly share code, notes, and snippets.

@diska
Last active March 23, 2021 00:08
Show Gist options
  • Save diska/1ecca49b9a84c9695329a6c1f766d4b9 to your computer and use it in GitHub Desktop.
Save diska/1ecca49b9a84c9695329a6c1f766d4b9 to your computer and use it in GitHub Desktop.
terrainの基本的な仕組みを実装したかったWebGLコード。
<canvas width="512" height="512"></canvas><hr/>
rotX:<input id="ROTX" type="range" value="50"><hr/>
<textarea id="LOG" cols="40" rows="15"></textarea>
<script>"use strict";
let cx=document.querySelector("canvas").getContext("webgl");
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);
let vsrc=`attribute vec4 p;uniform mat4 m;uniform sampler2D tx;uniform vec2 u;
varying vec4 c;void main(){
gl_Position=vec4(p.xy,texture2D(tx,p.xy*.5+u).a,1)*m;
gl_Position.xyz/=1.+gl_Position.z*0.2;gl_PointSize=4./gl_Position.w;
gl_Position.z*=.6; c=(2.-texture2D(tx,p.xy*.5+u)*16.).aaaa;
}`;
let fsrc=`precision mediump float;varying vec4 c;
void main(){gl_FragColor=c;gl_FragColor.rb*=.5;}`;
cx.shaderSource(vs,vsrc); cx.compileShader(vs);
cx.shaderSource(fs,fsrc); cx.compileShader(fs); cx.linkProgram(pg);
LOG.value+=`pg:${cx.getProgramInfoLog(pg)}\n`;
LOG.value+=`vs:${cx.getShaderInfoLog(vs)}\nfs:${cx.getShaderInfoLog(fs)}\n`;
let pgM=cx.getUniformLocation(pg,"m");
let pgU=cx.getUniformLocation(pg,"u");
let dim=100, data=new Float32Array(dim*dim*2);
for(let i=0;i<dim*dim;i++)data.set([(i%dim)/50-1, Math.floor(i/dim)/50-1], i*2)
let bf=cx.createBuffer(); let BP=cx.ARRAY_BUFFER;
cx.bindBuffer(BP,bf);{
cx.bufferData(BP,data,cx.STATIC_DRAW);
cx.enableVertexAttribArray(0);cx.vertexAttribPointer(0,2,cx.FLOAT,false,0,0);
};cx.bindBuffer(BP,null);
let tex=new Uint8Array(16*16*4);for(let i=0;i<16*16*4;i++)tex[i]=Math.random()*50;
let tx=cx.createTexture(); let TP=cx.TEXTURE_2D;
cx.activeTexture(cx.TEXTURE0+0);cx.bindTexture(TP,tx);{
cx.texImage2D(TP,0,cx.RGBA,16,16,0,cx.RGBA,cx.UNSIGNED_BYTE,tex);
cx.generateMipmap(TP);
}
cx.useProgram(pg); cx.enable(cx.DEPTH_TEST);
let x=0,y=0,ki={};
function draw(){
let th=ROTX.value/500+.2; let c=Math.cos(th*Math.PI), s=Math.sin(th*Math.PI);
let m=[1,0,0,0, 0,c,-s,0, 0,s,c,0, 0,0,0,1]; cx.uniformMatrix4fv(pgM,false,m);
x=(x+((ki.a?-1:0)+(ki.d?1:0))/3)%100;
y=(y+((ki.s?-1:0)+(ki.w?1:0))/3)%100;
cx.uniform2fv(pgU,[x/50-1,y/50-1]); LOG.value=`(${x.toFixed()},${y.toFixed()})`
cx.clearColor(0,0,1,1);cx.clear(0x4000); cx.drawArrays(0,0,dim*dim);
requestAnimationFrame(draw);
}; draw();
window.addEventListener("keydown",e=>ki[e.key]=true);
window.addEventListener("keyup",e=>ki[e.key]=false);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment