平面表面着色器(Flat Surface Shader, FSS)
利用JavaScript编写的简单轻量级平面表面着色器,它可以在WebGL、Canvas 2D和SVG等不同上下文中渲染带光照的三角形。查看这个演示,感受其强大的视觉效果。
光照理解
FSS基于拉普拉斯反射模型计算三角形颜色,该模型中包含了场景中的多个光源。每个光由三维位置向量和两个颜色对象定义,分别表示环境光和直射光。这些颜色通道与网格的材质相互作用,来确定三角形的颜色。
技术构成
- 光:由3D位置向量和两种颜色(环境光和直射光)组成。
- 三角形:由三个顶点构建,自动衍生出中心点(质心)和法向量(表面方向)。
- 几何体:仅是三角形的集合。
- 材质:由环境光和直射光的颜色定义。
- 网格:由几何体和材质构成,所有几何体内的三角形都使用相同的材质渲染。
- 场景:管理网格和光的对象数组。
- 渲染器:根据场景信息将内容渲染到特定上下文,支持WebGL、Canvas 2D和SVG。
计算过程
对场景中的每一个三角形执行以下步骤:
- 计算从三角形质心到光源位置的向量,并规范化,作为从光源出发的一束光线。
- 计算这个光线与三角形法向量之间的角度,使用点乘得出角度范围在-1到1之间。
- 将光源的直射光颜色与材质的直射光颜色相乘,然后乘以上述角度,得到最终的直射光颜色。
- 环境光颜色不受角度影响,直接相乘。
- 最终的三角形颜色是直射光和环境光颜色的总和。
示例代码
// 创建指定渲染上下文的渲染器
var renderer = new FSS.CanvasRenderer();
// 添加渲染器元素至DOM
var container = document.getElementById('container');
container.appendChild(renderer.element);
// 创建一个场景
var scene = new FSS.Scene();
// 创建几何体和材质,组合成网格并加入场景
var geometry = new FSS.Plane(200, 100, 4, 2);
var material = new FSS.Material('#444444', '#FFFFFF');
var mesh = new FSS.Mesh(geometry, material);
scene.add(mesh);
// 创建并添加灯光到场景
var light = new FSS.Light('#FF0000', '#0000FF');
scene.add(light);
// 渲染场景
renderer.render(scene);
构建与灵感
安装依赖:
npm install uglify-js@2.2.5
构建:
node build.js
本项目的架构受three.js启发,向量计算则借鉴了glMatrix库。
致谢
感谢朋友Tobias van Schneider在Behance上的案例研究。
作者与许可
作者:Matthew Wagerfield: @mwagerfield
许可证:遵循MIT开源协议。
快来尝试这个项目,让您的网页图形设计充满无限可能吧!