Cesium里自定义primitive

在不改Cesium源码下,在外部添加一个primitive。

创建drawCommand

我们去定义primitive,其实实际上我们就是在去构建以一个drawCommand,交由引擎去渲染。那么构建一个drawCommand。
Cesium里自定义primitive_第1张图片
上图是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,
});

update方法

在Cesium的Primtive或者GroundPrimitive架构设计里,都有一个update方法。因为Cesium在场景渲染时候会在updateAndRenderPrimitives()方法里去更新所有的primitive,其实就是遍历所有的primitive去调它自身的update(frameState)方法,然后我们可以在更新的时候去创建drawCommand,然后交给frameState.commandList,等着在render时候渲染。

加载

最后我们构建添加即可。

var primitive = new MyPrimitive(options);
viewer.scene.primitives.add(primitive);

完整代码参见该处。

你可能感兴趣的:(cesium,cesium)