console
window.onload = function () {
var myCanvas = document.querySelector('#myCanvas');
var ctx = myCanvas.getContext('2d');
var girdSize = 60;
var CanvasWidth = ctx.canvas.width;
var CanvasHeight = ctx.canvas.height;
var xLineTotals = Math.floor(CanvasHeight / girdSize);
var yLineTotals = Math.floor(CanvasWidth / girdSize);
const spacing = CanvasWidth / girdSize;
const vertices = [];
for (let x = 0; x < girdSize; x++) {
const row = [];
for (let y = 0; y < girdSize; y++) {
const z = Math.random() * 50;
row.push([x * spacing, y * spacing, z]);
}
vertices.push(row);
}
for (let i = 0; i < girdSize - 1; i++) {
for (let j = 0; j < girdSize - 1; j++) {
const v1 = vertices[i][j];
const v2 = vertices[i + 1][j];
const v3 = vertices[i + 1][j + 1];
const v4 = vertices[i][j + 1];
const n1 = calculateNormal(v1, v2, v3);
const n2 = calculateNormal(v1, v3, v4);
const normal = [
(n1[0] + n2[0]) / 2,
(n1[1] + n2[1]) / 2,
(n1[2] + n2[2]) / 2,
];
const intensity = calculateIntensity(normal);
const color = `rgb(${intensity}, ${intensity}, ${intensity})`;
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(v1[0], v1[1]);
ctx.lineTo(v2[0], v2[1]);
ctx.lineTo(v3[0], v3[1]);
ctx.lineTo(v4[0], v4[1]);
ctx.closePath();
ctx.fill();
const midpoint = [
(v1[0] + v2[0] + v3[0] + v4[0]) / 4,
(v1[1] + v2[1] + v3[1] + v4[1]) / 4,
(v1[2] + v2[2] + v3[2] + v4[2]) / 4,
];
const normalLineEnd = [
midpoint[0] + normal[0] * 10,
midpoint[1] + normal[1] * 10,
midpoint[2] + normal[2] * 10,
];
}
}
for (var i = 0; i < xLineTotals; i++) {
ctx.beginPath();
ctx.moveTo(0, girdSize * i - 0.5);
ctx.lineTo(CanvasWidth, girdSize * i - 0.5);
ctx.strokeStyle = "#ccc";
ctx.stroke();
}
for (var j = 0; j < yLineTotals; j++) {
ctx.beginPath();
ctx.moveTo(girdSize * j, 0);
ctx.lineTo(girdSize * j, CanvasHeight);
ctx.strokeStyle = "#ccc";
ctx.stroke();
}
}
function normalizeVector(v) {
const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
return [v[0] / length, v[1] / length, v[2] / length];
}
function crossProduct(v1, v2) {
return [
v1[1] * v2[2] - v1[2] * v2[1],
v1[2] * v2[0] - v1[0] * v2[2],
v1[0] * v2[1] - v1[1] * v2[0]
];
}
function calculateNormal(v1, v2, v3) {
const vector1 = subtractVectors(v2, v1);
const vector2 = subtractVectors(v3, v1);
const normal = crossProduct(vector1, vector2);
return normalizeVector(normal);
}
function subtractVectors(a, b) {
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
}
function calculateIntensity(normal) {
const lightDirection = [0, 0, 1];
normalizeVector(lightDirection);
const intensity = dotProduct(normal, lightDirection) * 255;
return intensity;
}
function dotProduct(v1, v2) {
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
function drawLine(midpoint, normalLineEnd, rgb) {
ctx.beginPath();
ctx.moveTo(girdSize * j, 0);
ctx.lineTo(girdSize * j, CanvasHeight);
ctx.strokeStyle = rgb;
ctx.stroke();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas{
border: 1px solid #cccccc;
margin-top: 100px;
margin-left: 100px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>