batch渲染

batch渲染目的是降低渲染drawcall次数,但是这个降低的成本是以cpu计算为代价的

理论上只要材质相同都可以使用,但是考虑cpu计算成本,所以batch使用的条件是

每个模型定点数很小才合算,否则降低的gpu负担结果导致cpu负担过重,所以合适

用batch渲染莫过于粒子草皮之类的~

以jme为例,可能是为了追求通用行,效率真的很低,每个顶点先通过矩阵变换,再

做顶点修改过去

下面是jme3每帧调用顶点操作堆栈

BatchNode.updateSubBatch(Geometry) line: 133	
BatchNode.onTransformChange(Geometry) line: 104	
Geometry.updateWorldTransforms() line: 315	
Geometry(Spatial).updateGeometricState() line: 905	
BatchNode(Node).updateGeometricState() line: 271	
Node.updateGeometricState() line: 271	
TestBatchNode(SimpleApplication).update() line: 245	
LwjglDisplay(LwjglAbstractDisplay).runLoop() line: 151	

    @Override
    protected void updateWorldTransforms() {
        super.updateWorldTransforms();
        computeWorldMatrix();

        if (isGrouped()) {//如果是普通geometry,只要矩阵计算一下就可以了,但是isGrouped为真的时候,需要cpu中变换顶点且更新到合并后的顶点buffer中
	//当然在渲染流程中有isGrouped为真就会跳过渲染,当作被裁剪掉了
            groupNode.onTransformChange(this);
        }

        // geometry requires lights to be sorted
        worldLights.sort(true);
    }


    public void updateGeometricState(){
        if (refreshFlags == 0) {
            // This branch has no geometric state that requires updates.
            return;
        }
        if ((refreshFlags & RF_LIGHTLIST) != 0){
            updateWorldLightList();
        }
        if ((refreshFlags & RF_TRANSFORM) != 0){
            // combine with parent transforms- same for all spatial
            // subclasses.
            updateWorldTransforms();
        }
        if ((refreshFlags & RF_MATPARAM_OVERRIDE) != 0) {
            updateMatParamOverrides();
        }

        refreshFlags &= ~RF_CHILD_LIGHTLIST;
        if (!children.isEmpty()) {
            // the important part- make sure child geometric state is refreshed
            // first before updating own world bound. This saves
            // a round-trip later on.
            // NOTE 9/19/09
            // Although it does save a round trip,
            for (Spatial child : children.getArray()) {//这里会要求每个geometry更新过去
                child.updateGeometricState();
            }
        }

下面是挨个顶点更新过去,不是像粒子那样就是几个顶点就不要玩合并了,如果确定是不更新的,就是初始化时候更新那还好,不过jme好像没有关闭更新接口
如果针对静态不变的需要加个接口控制
private void doTransforms(FloatBuffer bindBufPos, FloatBuffer bindBufNorm, FloatBuffer bufPos, FloatBuffer bufNorm, int start, int end, Matrix4f transform) {
        TempVars vars = TempVars.get();
        Vector3f pos = vars.vect1;
        Vector3f norm = vars.vect2;

        int length = (end - start) * 3;

        // offset is given in element units
        // convert to be in component units
        int offset = start * 3;
        bindBufPos.rewind();
        bindBufNorm.rewind();
        //bufPos.position(offset);
        //bufNorm.position(offset);
        bindBufPos.get(tmpFloat, 0, length);
        bindBufNorm.get(tmpFloatN, 0, length);
        int index = 0;
        while (index < length) {
            pos.x = tmpFloat[index];
            norm.x = tmpFloatN[index++];
            pos.y = tmpFloat[index];
            norm.y = tmpFloatN[index++];
            pos.z = tmpFloat[index];
            norm.z = tmpFloatN[index];

            transform.mult(pos, pos);
            transform.multNormal(norm, norm);

            index -= 2;
            tmpFloat[index] = pos.x;
            tmpFloatN[index++] = norm.x;
            tmpFloat[index] = pos.y;
            tmpFloatN[index++] = norm.y;
            tmpFloat[index] = pos.z;
            tmpFloatN[index++] = norm.z;

        }
        vars.release();
        bufPos.position(offset);
        //using bulk put as it's faster
        bufPos.put(tmpFloat, 0, length);
        bufNorm.position(offset);
        //using bulk put as it's faster
        bufNorm.put(tmpFloatN, 0, length);
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值