参考文章:Canvas绘制光源效果


<canvas id="canvas" :class="['compound-canvas']" ref="compound-canvas" width="200" height="200"></canvas>

// 向量差运算
function sub(v1, v2) {
  return [
    v1[0] - v2[0],
    v1[1] - v2[1],
    v1[2] - v2[2],
  ];
}
// 向量点乘运算
function dot(v1, v2) {
  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
// 求向量的单位化向量
function normalize(v) {
  const len = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  return [
    v[0] / len,
    v[1] / len,
    v[2] / len,
  ];
}
const pointLight = {
  position: [100, 100, 40],
  color: { r: 255, g: 255, b: 255 },
};
const plane = {
  center: [100, 100, 0],
  width: 200,
  height: 200,
  normal: [0, 0, 1],
  color: { r: 255, g: 215, b: 0 },
};
const ctx = this.$refs['compound-canvas'].getContext('2d');
const imageData = ctx.createImageData(200, 200);
for (let x = 0; x < imageData.width; x += 1) {
  for (let y = 0; y < imageData.height; y += 1) {
    const index = y * imageData.width + x;
    const point = [x, y, 0];
    const normal = [0, 0, 1];
    const reverseLightDirection = normalize(sub(pointLight.position, point));
    const light = dot(reverseLightDirection, normal);
    imageData.data[index * 4] = Math.min((pointLight.color.r + plane.color.r) * light, 255);
    imageData.data[index * 4 + 1] = Math.min((pointLight.color.g + plane.color.g) * light, 255);
    imageData.data[index * 4 + 2] = Math.min((pointLight.color.b + plane.color.b) * light, 255);
    imageData.data[index * 4 + 3] = 255;
  }
}
ctx.putImageData(imageData, 0, 0);

标签: canvas

添加新评论

0%