无法用Canvas 2D上下文真正渲染带动态光影的3D模型,必须使用WebGL或Three.js等封装库;纯2D仅支持有限伪3D光照模拟。
直接用 Canvas 2D 上下文无法真正渲染 3D 模型,它不支持深度测试、透视投影或 GPU 加速的光照计算。要实现“动态光影的网页版 3D 模型”,必须借助 WebGL(Canvas 的 webgl 上下文),或使用封装了 WebGL 的高级库(如 Three.js)。纯 2D Canvas 只能做伪 3D 投影+手工模拟光照,效果有限且难以维护。
这是最贴近“Canvas 绘制接口”又具备真实光影能力的方式——本质是把 Canvas 当作 WebGL 的渲染目标:
webgl 上下文而非 2d: const gl = canvas.getContext('webgl');,检查是否可用dot(normal, lightDir))算漫反射强度vec3 aPosition 和法向量 vec3 aNormal: 法向量决定光照响应,必须随模型旋转实时归一化并变换到世界/视图空间lightPos,传给着色器 uniform 变量gl.enable(gl.DEPTH_TEST),避免前后遮挡错误更推荐此方案——它基于 WebGL,但屏蔽底层复杂性,仍运行在 Canvas 元素上:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
THREE.DirectionalLight(模拟太阳)和一个 THREE.AmbientLight(防止背光全黑)BoxGeometry),赋予带光照响应的材质(如 MeshStandardMaterial)renderer.render(scene, camera)
适用于轻量、风格化、非物理精确的需求(如数据可视化标签云、简易球面文字):
立即学习“前端免费学习笔记(深入)”;
ctx.fillStyle 根据点乘结果动态设置 RGB 值(如 rgb(255 * intensity, 255 * intensity, 200 * intensity))fillRect 或 beginPath + arc),配合 globalAlpha 或渐变模拟高光无论选哪种路径,以下三点直接影响光影真实感:
canvas.width = canvas.offsetWidth * window.devicePixelRatio;canvas.height = canvas.offsetHeight * window.devicePixelRatio;ctx.scale(window.devicePixelRatio, window.devicePixelRatio);