Skip to content

Instantly share code, notes, and snippets.

@Akiyah
Created March 8, 2014 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akiyah/9434634 to your computer and use it in GitHub Desktop.
Save Akiyah/9434634 to your computer and use it in GitHub Desktop.
forked: レイトレーシング練習
html {
height:100%;
}
body {
margin: 0;
padding: 0;
background: gray;
width:100%;
height:100%;
overflow : hidden;
}
canvas {
width:100%;
height:100%;
}
<canvas id="canvas" width="400"></canvas>
function sum(p, q) {
return [p[0]+q[0], p[1]+q[1], p[2]+q[2]];
}
function multi(p, m) {
return [p[0]*m, p[1]*m, p[2]*m];
}
function innerProduct(p, q) {
return p[0]*q[0] + p[1]*q[1] + p[2]*q[2];
}
function norm(p) {
return Math.sqrt(innerProduct(p, p));
}
function normalization(p) {
return multi(p, 1/norm(p));
}
function cos(v, w) {
return innerProduct(v, w)/norm(v)/norm(w);
}
function diffuseReflection(normal, light) {
return Math.max(-cos(light, normal), 0);
}
function specularReflection(normal, light, eye, n) {
var m = -2 * innerProduct(light,normal)/innerProduct(normal,normal)
var light1 = sum(light, multi(normal, m));
var c = -cos(light1, eye);
if (c < 0) {
return 0;
}
return Math.pow(c, n);
}
function init() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var r = 200;
var r2 = 20;
var x0 = 200;
var y0 = 200;
function mapxy(f) {
var data = [];
for (var x = 0; x < WIDTH; x++) {
data[x] = [];
for (var y = 0; y < HEIGHT; y++) {
var i = (y * WIDTH + x) * 4;
data[x][y] = f(x, y, i);
}
}
return data;
}
var imageData = context.getImageData(0, 0, WIDTH, HEIGHT);
var data = imageData.data;
var bump = mapxy(function(x, y, i) {
//var x = x1 - x0; // 右が大きくなる方向
//var y = y0 - y1; // 上が大きくなる方向
var lx = 27*3;
var ly = 17*3;
var dx = 5*3;
var dy = 5*3;
var dz = 8*3;
var x2 = x - lx;
var y2 = y - ly;
if (Math.abs(y2) < ly && Math.abs(x2) < lx ) {
if (Math.abs(y2) < ly-dy && Math.abs(x2) < lx-dx ) {
return [0,0,1,10];
}
if (0 < y2 && 0 <= dx*(y2-ly)-dy*(x2-lx) && 0 <= dx*(y2-ly)-dy*(-x2-lx)) {
return [0,dz,dx, 10];
}
if (y2 < 0 && 0 <= dx*(-y2-ly)-dy*(x2-lx) && 0 <= dx*(-y2-ly)-dy*(-x2-lx)) {
return [0,-dz,dx, 10];
}
if (0 < x2 && dx*(y2-ly)-dy*(x2-lx) < 0 && dx*(-y2-ly)-dy*(x2-lx) < 0) {
return [dz,0,dy, 10];
}
if (x2 < 0 && dx*(y2-ly)-dy*(-x2-lx) < 0 && dx*(-y2-ly)-dy*(-x2-lx) < 0) {
return [-dz,0,dy, 10];
}
}
/*
if (y > r2) {
return null;
}
if (y > 0) {
if (Math.abs(x) < r-r2) {
var z = Math.sqrt(r2*r2 - y*y);
return {p: [x,y,z], n: [0,y,z]};
}
var x2 = x > 0 ? x-(r-r2) : x+(r-r2);
if (x2*x2+y*y < r2*r2) {
var z = Math.sqrt(r2*r2 - (x2*x2 + y*y));
return {p: [x,y,z], n: [x2,y,z]};
}
return null;
}
if (x*x + y*y < r*r) {
var normal;
if (x*x + y*y < (r-r2)*(r-r2)) {
return {p: [x,y,r2], n: [0,0,1]};
} else {
var x2 = x - x / Math.sqrt(x*x+y*y) * (r-r2);
var y2 = y - y / Math.sqrt(x*x+y*y) * (r-r2);
var z2 = Math.sqrt(r2*r2 - (x2*x2 + y2*y2));
return {p: [x,y,z2], n: [x2,y2,z2]};
}
return null;
}
*/
return null;
});
// ゆらす
/*
var heights = mapxy(function(x, y, i) {
var d = heights[x][y];
if (d) {
var n = normalization(d.n);
var m = normalization([Math.cos((x+y)/30)/10,Math.cos((x-2*y)/30)/10,1]);
d.n = normalization(sum(n, m))
}
return d;
});
*/
// 複製
var bump = mapxy(function(x, y, i) {
if (x < 5 || y < 5) {
return null;
}
return bump[(x-5) % (27*3*2+10)][(y-5) % (17*3*2+10)];
});
function draw(light) {
var eye_position = [0, 0, 100];
mapxy(function(x, y, i) {
var d = bump[x][y];
if (d) {
var position = [x, y, d[3]];
var normal = d;
var eye = sum(position, multi(eye_position, -1));
var c0 = 1;
var c1 = diffuseReflection(normal, light);
var c2 = specularReflection(normal, light, eye, 10);
data[i+0] = (c0 + c1 + c2)/3* 0xa0;
data[i+1] = (c0 + c1 + c2)/3* 0x64;
data[i+2] = (c0 + c1 + c2)/3* 0x13;
data[i+3] = 255;
}
});
context.putImageData(imageData, 0, 0);
}
var i = 0;
setInterval(function() {
var y = Math.sin(-i / 180 * Math.PI * 5) * 10;
draw([-1,y,-1]);
i++;
}, 100);
$("body").mousemove(function(e) {
//console.log(e);
//draw([-1,y,-1]);
});
}
$(function() {
var obj = $('#canvas');
$('#canvas').attr({width:obj.width(), height:obj.height()});
console.log(obj);
init();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment