Skip to content

Instantly share code, notes, and snippets.

@diska
Last active March 17, 2018 17:08
Show Gist options
  • Select an option

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

Select an option

Save diska/f44f1114bdf5f43a0b047d8d4648334d to your computer and use it in GitHub Desktop.
素人が、WebGLで、遠近法について、考えているコード。
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const vssrc=`attribute vec4 position;varying vec4 vcolor;
void main(void){
vec3 eye=vec3(0,0,-1.5); // 目はここに置く!
float l=distance(eye.xyz, position.xyz); // 「遠く」…それは…
gl_PointSize=(1.0/l)*32.; // 遠いほど
gl_Position.xy=position.xy*(1.0/l); // 小さい!
gl_Position.z=position.z;
gl_Position.w=1.0;
vcolor=vec4(vec3(1)/l/l,1.0); // 目が白く光った!遠くは暗い!
}`;
const fssrc=`precision mediump float;varying vec4 vcolor;
void main(void){
// if(distance(gl_PointCoord,vec2(0.5))>0.5)discard;
gl_FragColor=vcolor*1.0;
gl_FragColor.rb*=0.5; // なんとなく赤青が暗くて緑色。
}`;
const vertexPosition=[0,1,0, 1,0,0, -1,0,0, 1,0,0, -1,0,0, 0,-1,0, ];
onload=function(){
var gl, program1, buffer1;
const c=document.getElementById("canvas");
try{
gl=c.getContext("webgl");
gl.clearColor(0, 0, 0, 1); gl.clearDepth(1);
gl.enable(gl.DEPTH_TEST);
buffer1=new ArrayBuffer(gl, vertexPosition);
program1=new Program(gl, vssrc, fssrc);
program1.addAttribute("position", 3, enable=true);
program1.setAttribute("position", buffer1);
}catch(e){
console.log(e); // alert(e);
}
program1.use();
program1.draw=function(now){
move(now/1000);
buffer1.setData(vertexPosition);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.drawArrays(gl.POINTS, 0, 6);
requestAnimationFrame(program1.draw);
}; program1.draw();
// y軸を軸に手動で回転。
function move(time){
vertexPosition[3]= Math.cos(0+time); // v[1].x
vertexPosition[5]= Math.sin(0+time); // v[1].z
vertexPosition[6]=-Math.cos(0+time); // v[2].x
vertexPosition[8]=-Math.sin(0+time); // v[2].z
}
}
</Script>
<Script>
function Program(gl, vssrc, fssrc){
this.gl=gl;this.program=this.getProgram(vssrc, fssrc);
}
Program.prototype={
use:function(){this.gl.useProgram(this.program)},
// シェーダのattribute"position"をつかむ。
addAttribute:function(name, length, enable=false){
var gl=this.gl;
this[name]=gl.getAttribLocation(this.program, name);
this[name+"Length"]=length;
if(enable){gl.enableVertexAttribArray(this[name])}
},
// attributeの入力をbufferにつなぐ
setAttribute:function(name, buffer){
var gl=this.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, buffer.vbo);
gl.vertexAttribPointer(this[name], this[name+"Length"], gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
getProgram:function(vssrc, fssrc){
var gl=this.gl;
var program=gl.createProgram();
gl.attachShader(program, getShader(gl.VERTEX_SHADER,vssrc));
gl.attachShader(program, getShader(gl.FRAGMENT_SHADER,fssrc));
gl.linkProgram(program);
if(!gl.getProgramParameter(program, gl.LINK_STATUS)){
throw gl.getProgramInfoLog(program);
}
return program;
function getShader(type, src){
var shader=gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
throw gl.getShaderInfoLog(shader);
}
return shader;
}
},
}
///////////////////////////////////////////////////////////////////////
function ArrayBuffer(gl, data=null){
this.gl=gl; this.vbo=gl.createBuffer();
if(data!=null){this.setData(data);}
}
ArrayBuffer.prototype={
setData:function(data){
var gl=this.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment