从3dtile渲染到primitive

本文深入探讨了Cesium源码中针对3D Tiles的解析与渲染优化方法,通过对片元着色器的直接修改,实现了更高效的数据处理流程。文章详细介绍了如何创建原始数据的批处理表,更新模型三角形计数,并通过量化属性统一化处理来提升渲染性能。

cesium源码中有这个,所以,先拷贝过来,相当于对3dtile解析了,这样渲染时,可以直接改片元着色器了

 function createPrimitive(model) {
        var batchTable = model._batchTable;

        var uniformMap = model._uniformMap;
        var vertexArray = model._vertexArray;

        var gltf = model.gltf;
        var accessors = gltf.accessors;
        var gltfMeshes = gltf.meshes;
        var primitive = gltfMeshes[0].primitives[0];
        var ix = accessors[primitive.indices];

        var positionAccessor = primitive.attributes.POSITION;
        var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor);
        var boundingSphere = BoundingSphere.fromCornerPoints(Cartesian3.fromArray(minMax.min), Cartesian3.fromArray(minMax.max));

        var offset;
        var count;
        if (defined(ix)) {
            count = ix.count;
            offset = (ix.byteOffset / IndexDatatype.getSizeInBytes(ix.componentType));  // glTF has offset in bytes.  Cesium has offsets in indices
        }
        else {
            var positions = accessors[primitive.attributes.POSITION];
            count = positions.count;
            offset = 0;
        }

        // Update model triangle count using number of indices
        model._trianglesLength += triangleCountFromPrimitiveIndices(primitive, count);

        // Allow callback to modify the uniformMap
        if (defined(model._uniformMapLoaded)) {
            uniformMap = model._uniformMapLoaded(uniformMap);
        }

        // Add uniforms for decoding quantized attributes if used
        if (model.extensionsUsed.WEB3D_quantized_attributes) {
            var quantizedUniformMap = createUniformsForQuantizedAttributes(model, primitive);
            uniformMap = combine(uniformMap, quantizedUniformMap);
        }

        var attribute = vertexArray.attributes.POSITION;
        var componentDatatype = attribute.componentDatatype;
        var typedArray = attribute.vertexBuffer;
        var byteOffset = typedArray.byteOffset;
        var bufferLength = typedArray.byteLength / ComponentDatatype.getSizeInBytes(componentDatatype);
        var positionsBuffer = ComponentDatatype.createArrayBufferView(componentDatatype, typedArray.buffer, byteOffset, bufferLength);

        attribute = vertexArray.attributes._BATCHID;
        componentDatatype = attribute.componentDatatype;
        typedArray = attribute.vertexBuffer;
        byteOffset = typedArray.byteOffset;
        bufferLength = typedArray.byteLength / ComponentDatatype.getSizeInBytes(componentDatatype);
        var vertexBatchIds = ComponentDatatype.createArrayBufferView(componentDatatype, typedArray.buffer, byteOffset, bufferLength);

        var buffer = vertexArray.indexBuffer.typedArray;
        var indices;
        if (vertexArray.indexBuffer.indexDatatype === IndexDatatype.UNSIGNED_SHORT) {
            indices = new Uint16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint16Array.BYTES_PER_ELEMENT);
        } else {
            indices = new Uint32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint32Array.BYTES_PER_ELEMENT);
        }

        positionsBuffer = arraySlice(positionsBuffer);
        vertexBatchIds = arraySlice(vertexBatchIds);
        indices = arraySlice(indices, offset, offset + count);

        var batchIds = [];
        var indexCounts = [];
        var indexOffsets = [];
        var batchedIndices = [];

        var currentId = vertexBatchIds[indices[0]];
        batchIds.push(currentId);
        indexOffsets.push(0);

        var batchId;
        var indexOffset;
        var indexCount;
        var indicesLength = indices.length;
        for (var j = 1; j < indicesLength; ++j) {
            batchId = vertexBatchIds[indices[j]];
            if (batchId !== currentId) {
                indexOffset = indexOffsets[indexOffsets.length - 1];
                indexCount = j - indexOffset;

                batchIds.push(batchId);
                indexCounts.push(indexCount);
                indexOffsets.push(j);

                batchedIndices.push(new Vector3DTileBatch({
                    offset : indexOffset,
                    count : indexCount,
                    batchIds : [currentId],
                    color : Color.WHITE
                }));

                currentId = batchId;
            }
        }

        indexOffset = indexOffsets[indexOffsets.length - 1];
        indexCount = indicesLength - indexOffset;

        indexCounts.push(indexCount);
        batchedIndices.push(new Vector3DTileBatch({
            offset : indexOffset,
            count : indexCount,
            batchIds : [currentId],
            color : Color.WHITE
        }));

        var shader = model._shaderProgram;
        var vertexShaderSource = shader.vertexShaderSource;
        var fragmentShaderSource = shader.fragmentShaderSource;
        var attributeLocations = shader.attributeLocations;
        var pickId = defined(model._pickIdLoaded) ? model._pickIdLoaded() : undefined;

        model._primitive = new Vector3DTilePrimitive({
            classificationType : model._classificationType,
            positions : positionsBuffer,
            indices : indices,
            indexOffsets : indexOffsets,
            indexCounts : indexCounts,
            batchIds : batchIds,
            vertexBatchIds : vertexBatchIds,
            batchedIndices : batchedIndices,
            batchTable : batchTable,
            boundingVolume : new BoundingSphere(), // updated in update()
            _vertexShaderSource : vertexShaderSource,
            _fragmentShaderSource : fragmentShaderSource,
            _attributeLocations : attributeLocations,
            _uniformMap : uniformMap,
            _pickId : pickId,
            _modelMatrix : new Matrix4(), // updated in update()
            _boundingSphere : boundingSphere // used to update boundingVolume
        });

        // Release CPU resources
        model._buffers = undefined;
        model._vertexArray = undefined;
        model._shaderProgram = undefined;
        model._uniformMap = undefined;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值