Last active
March 17, 2018 17:08
-
-
Save diska/f44f1114bdf5f43a0b047d8d4648334d to your computer and use it in GitHub Desktop.
素人が、WebGLで、遠近法について、考えているコード。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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