Created
August 20, 2018 08:04
-
-
Save diska/a6871a5255cb4767f15d69534870e331 to your computer and use it in GitHub Desktop.
三葉レイ動画の22:01時点のコードのGLSL化。
This file contains 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
<meta charset="utf-8"><br/> | |
<canvas id="CNVS"></canvas><hr/> | |
<script> | |
const vsrc=`attribute vec4 p;void main(){gl_PointSize=64.;gl_Position=p;}`; | |
const fsrc=`precision mediump float; | |
struct Ray{ vec3 o, d;}; | |
struct Sph{ vec3 o; float r;}; | |
const float width=120., height=80.; | |
float intersect(Sph sph, Ray ray, float tmin, float tmax){ | |
vec3 op=sph.o-ray.o; | |
float bo=dot(op, ray.d); | |
float det=bo*bo-dot(op,op)+sph.r*sph.r; | |
if(det<0.){return -1.;} | |
float t1=bo-sqrt(det); | |
if(tmin<t1&&t1<tmax){return t1;} | |
float t2=bo+sqrt(det); | |
if(tmin<t2&&t2<tmax){return t2;} | |
return -1.; | |
} | |
vec3 tonemap(vec3 c){ | |
float r=pow(c.r, 1./2.2); | |
float g=pow(c.g, 1./2.2); | |
float b=pow(c.b, 1./2.2); | |
return vec3(r,g,b); | |
} | |
void getSphs1(out Sph[2] sphs){// "2 spheres" scene | |
sphs[0].o=vec3( .5,0,0), sphs[0].r=1.; | |
sphs[1].o=vec3(-.5,0,0), sphs[1].r=1.; | |
} | |
void getSphs2(out Sph[8] sphs){// Cornell Box scene | |
const float bnum=1e5; | |
sphs[0].o=vec3( bnum+1., 40.8, 81.6), sphs[0].r=bnum; | |
sphs[1].o=vec3(-bnum+99., 40.8, 81.6), sphs[1].r=bnum; | |
// sphs[0].o=vec3( .5,0,0), sphs[0].r=1.; | |
// sphs[1].o=vec3(-.5,0,0), sphs[1].r=1.; | |
sphs[2].o=vec3(50., 40.8, bnum), sphs[2].r=bnum; | |
sphs[3].o=vec3(50., bnum, 81.6), sphs[3].r=bnum; | |
sphs[4].o=vec3(50., -bnum+81.6, 81.6), sphs[4].r=bnum; | |
sphs[5].o=vec3(27., 16.5, 47.), sphs[5].r=16.5; | |
sphs[6].o=vec3(73., 16.5, 78.), sphs[6].r=16.5; | |
sphs[7].o=vec3(50., 681.6-.27, 81.6), sphs[7].r=600.; | |
} | |
void main(){ | |
const float PI=3.141592; | |
float fov=30.*PI/180., aspect=width/height; | |
// camera parameters for "2 spheres" scene | |
// vec3 eye=vec3(5,5,5), center=vec3(0,0,0); | |
// camera parameters for Cornell Box scene | |
vec3 eye=vec3(50.,52.,295.6), center=eye+vec3(0.,-0.042612,-1.); | |
vec3 up=vec3(0,1,0); | |
// basis vectors for camera coordinates | |
vec3 wE=normalize(eye-center); | |
vec3 uE=normalize(cross(up, wE)); | |
vec3 vE=cross(wE, uE); | |
// | |
float tf=tan(fov*.5); | |
vec2 rp=vec2(2.*gl_FragCoord.x/width-1., 2.*gl_FragCoord.y/height-1.); | |
vec3 wo=normalize(vec3(aspect*tf*rp.x, tf*rp.y, -1)); | |
Ray ray; | |
// ray.o=vec3(vec2(rp), 5); ray.d=vec3(0,0,-1); | |
ray.o=eye; | |
ray.d=uE*wo.x+vE*wo.y+wE*wo.z; | |
// | |
vec3 color=vec3(1,0,1); | |
Sph sph; | |
// Sph sphs[2]; getSphs1(sphs); | |
Sph sphs[8]; getSphs2(sphs); | |
float h, minh=-1., tmax=1000.; | |
for(int i=0; i<8; i++){ | |
h=intersect(sphs[i], ray, 0., tmax); | |
if(h<0.){continue;} | |
sph=sphs[i]; | |
minh=h; | |
tmax=h; | |
} | |
vec3 p, n; | |
if(minh>0.){ | |
p=ray.o+ray.d*minh; | |
n=(p-sph.o)/sph.r; | |
} | |
if(minh>0.){ | |
gl_FragColor=vec4(color,1); | |
gl_FragColor=vec4(tonemap(abs(n)),1); | |
}else{ | |
gl_FragColor=vec4(0,0,0,1); | |
} | |
}`; | |
function draw(){ | |
const width=120, height=80; // Image size | |
CNVS.width=width, CNVS.height=height; | |
var cx=CNVS.getContext("webgl"); | |
var vs=cx.createShader(cx.VERTEX_SHADER);cx.shaderSource(vs,vsrc); | |
var fs=cx.createShader(cx.FRAGMENT_SHADER);cx.shaderSource(fs,fsrc); | |
var pg=cx.createProgram();cx.attachShader(pg,vs);cx.attachShader(pg,fs); | |
cx.compileShader(vs);cx.compileShader(fs);cx.linkProgram(pg); | |
console.log(`vs:${cx.getShaderInfoLog(vs)}\nfs:${cx.getShaderInfoLog(fs)}\n`); | |
console.log(`pg:${cx.getProgramInfoLog(pg)}\n`); | |
cx.enableVertexAttribArray(0); | |
cx.useProgram(pg); | |
var abuf=cx.createBuffer(cx.ARRAY_BUFFER); | |
var data=new Float32Array([-1,-1, 1,-1, -1,1, 1,1]) | |
cx.bindBuffer(cx.ARRAY_BUFFER,abuf); | |
cx.bufferData(cx.ARRAY_BUFFER, data, cx.STATIC_DRAW); | |
cx.vertexAttribPointer(0, 2,cx.FLOAT, false, 0,0); | |
cx.bindBuffer(cx.ARRAY_BUFFER,null); | |
cx.drawArrays(cx.TRIANGLE_STRIP,0,4); | |
}; draw(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment