在不改Cesium源码下,在外部添加一个primitive。
我们去定义primitive,其实实际上我们就是在去构建以一个drawCommand,交由引擎去渲染。那么构建一个drawCommand。
上图是Cesium的DrawCommand的构造函数,所以我们需要传入相应的参数。modelMatrix
则是该primitive的模型矩阵,用来决定位置,我们可以从外部传进来:
var origin = Cesium.Cartesian3.fromDegrees(120, 26, 250);
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
vertexArray
是顶点数组,我们可以自己去拼顶点然后去new Cesium.VertexArray
来构建,也可以利用Cesium.VertexArray.fromGeometry
方法从Cesium里已有的各种geometry去取出来:
var box = new Cesium.BoxGeometry({
vertexFormat: Cesium.VertexFormat.POSITION_NORMAL_AND_ST,
maximum: new Cesium.Cartesian3(250000.0, 250000.0, 250000.0),
minimum: new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0),
});
var geometry = Cesium.BoxGeometry.createGeometry(box);
var attributeLocations =
Cesium.GeometryPipeline.createAttributeLocations(geometry);
var va = Cesium.VertexArray.fromGeometry({
context: context,
geometry: geometry,
attributeLocations: attributeLocations,
});
shaderProgram
就是着色器程序,只要我们构建好顶点着色器和片元着色器,并传入attributeLocations
即可创建。
var shaderProgram = Cesium.ShaderProgram.fromCache({
context: context,
vertexShaderSource: vs, // 顶点着色器代码
fragmentShaderSource: fs, // 片元着色器代码
attributeLocations: attributeLocations,
});
然后是uniformMap
,主要是传入uniform变量的。
var uniformMap = {
color() {
return Cesium.Color.GRAY;
},
};
还有renderState
渲染状态,可以定义背面剔除、深度测试等状态。
var renderState = Cesium.RenderState.fromCache({
cull: {
enabled: true,
face: Cesium.CullFace.BACK,
},
depthTest: {
enabled: true,
},
});
最后我们就可以创建DrawCommand了,pass
指定了该drawCommand在哪个pass下渲染。
this.drawCommand = new Cesium.DrawCommand({
modelMatrix: modelMatrix,
vertexArray: va,
shaderProgram: shaderProgram,
uniformMap: uniformMap,
renderState: renderState,
pass: Cesium.Pass.OPAQUE,
});
在Cesium的Primtive或者GroundPrimitive架构设计里,都有一个update
方法。因为Cesium在场景渲染时候会在updateAndRenderPrimitives()
方法里去更新所有的primitive,其实就是遍历所有的primitive去调它自身的update(frameState)
方法,然后我们可以在更新的时候去创建drawCommand,然后交给frameState.commandList
,等着在render
时候渲染。
最后我们构建添加即可。
var primitive = new MyPrimitive(options);
viewer.scene.primitives.add(primitive);
完整代码参见该处。