目标
使用Gouraud着色算法实现顶点着色
实现
增加Uniform
进行顶点着色之前,需要先给Shader增加两个Uniform变量。其一是法向量变换矩阵,其二是摄像机在世界空间的坐标。
如果你不记得什么是“法向量变换”,可以回顾这篇文章 Java软光栅渲染器-空间变换 中的“法向量变换”部分。
在Renderer中添加一个法向量变换矩阵和一个摄像机位置,并在 render(ListgeomList, Camera camera) 方法中计算它们的值。
// 法向量变换矩阵
private Matrix3f normalMatrix = new Matrix3f();
// 摄像机位置
private Vector3f cameraPosition = new Vector3f();
/**
* 渲染场景
* @param scene
* @param camera
*/
public void render(List geomList, Camera camera) {
// 根据Camera初始化观察变换矩阵。
viewMatrix.set(camera.getViewMatrix());
projectionMatrix.set(camera.getProjectionMatrix());
viewProjectionMatrix.set(camera.getViewProjectionMatrix());
cameraPosition.set(camera.getLocation());
// TODO 剔除那些不可见的物体
// 遍历场景中的Mesh
for(int i=0; i
Geometry geom = geomList.get(i);
// 根据物体的世界变换,计算MVP等变换矩阵。
worldMatrix.set(geom.getWorldTransform().toTransformMatrix());
viewMatrix.mult(worldMatrix, worldViewMatrix);
viewProjectionMatrix.mult(worldMatrix, worldViewProjectionMatrix);
// 计算法向量变换矩阵
worldMatrix.toRotationMatrix(normalMatrix);
// FIXME 先判断是否为正交矩阵,然后在决定是否要计算Invert、Transpose矩阵。
normalMatrix.invertLocal();
normalMatrix.transposeLocal();
// TODO 使用包围体,剔除不可见物体
// 渲染
render(geom);
}
}
在Shader类中定义同样两个protected成员,并在Renderer中调用shader的set方法设置这些值。
/**
* 渲染单个物体
* @param geometry
*/
protected void render(Geometry geometry) {
// 设置材质
this.material = geometry.getMaterial();
// 设置渲染状态
this.raster.setRenderState(material.getRenderState());
//