Ogre --InstanceBatchHW

1、InstanceBatchHW 简介

InstanceBatchHW 全名 InstanceBatch hardware 即硬件缓存存储批次中entity信息, 创建同一个批次模型时,将每个模型的节点仿射矩阵(3×4或4×4)存储到顶点纹理缓存中(矩阵纹理缓存), 最后GPU利用该矩阵更新顶点位置。
注:InstanceBatchHW 不支持entity动画。

2、InstanceBatchHW 创建

  1. InstanceBatchHW 基本信息的创建
  2. InstanceBatchHW 设置顶点缓存
    先复值原Entity中的顶点数据到mRenderOperation对象里,删除该动画数据(删除顶点类型:VES_BLEND_WEIGHTS、VES_BLEND_INDICES和对应的顶点数据),然后声明至少3个顶点纹理类型(如果附加自定义变量需要创建更多顶点类型),最后创建顶点数据和顶点索引不需要修改直接拷贝。
    如下代码:
 void InstanceBatchHW::setupVertices( const SubMesh* baseSubMesh )
    {
        mRenderOperation.vertexData = baseSubMesh->vertexData->clone();
        mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed)
           
        VertexData *thisVertexData = mRenderOperation.vertexData;

        //No skeletal animation support in this technique, sorry
        removeBlendData();

        //Modify the declaration so it contains an extra source, where we can put the per instance data
        size_t offset               = 0;
        unsigned short nextTexCoord = thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate();
        const unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1;
        for( unsigned char i=0; i<3 + mCreator->getNumCustomParams(); ++i )
        {
            thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4,
                                                            VES_TEXTURE_COORDINATES, nextTexCoord++ );
            offset = thisVertexData->vertexDeclaration->getVertexSize( newSource );
        }

        //Create the vertex buffer containing per instance data
        HardwareVertexBufferSharedPtr vertexBuffer =
                                        HardwareBufferManager::getSingleton().createVertexBuffer(
                                        thisVertexData->vertexDeclaration->getVertexSize(newSource),
                                        mInstancesPerBatch,
                                        HardwareBuffer::HBU_STATIC_WRITE_ONLY );
        thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer );
        vertexBuffer->setIsInstanceData( true );
        vertexBuffer->setInstanceDataStepRate( 1 );
    }

3、InstanceBatchHW 写入矩阵纹理数据

  1. 获取每个entity对象的节点的转换矩阵(3×4),将矩阵信息写到mRenderOperation对象里上一步创建的顶点纹理数据中。
    如下代码:
size_t InstanceBatchHW::updateVertexBuffer( Camera *currentCamera )
    {
        size_t retVal = 0;

        //Now lock the vertex buffer and copy the 4x3 matrices, only those who need it!
        const Oushort bufferIdx = Oushort(mRenderOperation.vertexData->vertexBufferBinding->getBufferCount()-1);
        float *pDest = static_cast<float*>(mRenderOperation.vertexData->vertexBufferBinding->
                                            getBuffer(bufferIdx)->lock( HardwareBuffer::HBL_DISCARD ));

        InstancedEntityVec::const_iterator itor = mInstancedEntities.begin();
        InstancedEntityVec::const_iterator end  = mInstancedEntities.end();

        unsigned char numCustomParams           = mCreator->getNumCustomParams();
        size_t customParamIdx                   = 0;

        while( itor != end )
        {
            //Cull on an individual basis, the less entities are visible, the less instances we draw.
            //No need to use null matrices at all!
            if( (*itor)->findVisible( currentCamera ) )
            {
                const size_t floatsWritten = (*itor)->getTransforms3x4( pDest );

                if( mManager->getCameraRelativeRendering() )
                    makeMatrixCameraRelative3x4( pDest, floatsWritten );

                pDest += floatsWritten;

                //Write custom parameters, if any
                for( unsigned char i=0; i<numCustomParams; ++i )
                {
                    *pDest++ = mCustomParams[customParamIdx+i].x;
                    *pDest++ = mCustomParams[customParamIdx+i].y;
                    *pDest++ = mCustomParams[customParamIdx+i].z;
                    *pDest++ = mCustomParams[customParamIdx+i].w;
                }

                ++retVal;
            }
            ++itor;

            customParamIdx += numCustomParams;
        }

        mRenderOperation.vertexData->vertexBufferBinding->getBuffer(bufferIdx)->unlock();

        return retVal;
    }

4、InstanceBatchHW GPU顶点着色器数据更新

  1. 代码注释详解 如下代码:
#version 120

//Vertex input
attribute vec4 vertex;   //顶点数据
attribute vec3 normal;   //法向量
attribute vec4 uv0;      //纹理坐标
attribute vec4 uv1;      //矩阵纹理第一行数据
attribute vec4 uv2;      //矩阵纹理第二行数据
attribute vec4 uv3;      //矩阵纹理第三行数据
attribute vec3 tangent;  //自定义变量()

//Parameters
uniform mat4 viewProjMatrix;

#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
uniform vec4 depthRange;
#endif

#if DEPTH_SHADOWRECEIVER
uniform mat4 texViewProjMatrix;
#endif

//Output
#if DEPTH_SHADOWCASTER
	varying vec2 depth;
#else
	varying vec2 _uv0;
	varying vec3 oNormal;
	varying vec3 oVPos;
	#if DEPTH_SHADOWRECEIVER
		varying vec4 oLightSpacePos;
	#endif
#endif

//---------------------------------------------
//Main Vertex Shader
//---------------------------------------------
void main(void)
{
	//构建纹理矩阵
	mat4 worldMatrix;
	worldMatrix[0] = uv1;
	worldMatrix[1] = uv2;
	worldMatrix[2] = uv3;
	worldMatrix[3] = vec4( 0, 0, 0, 1 );

	vec4 worldPos		= vertex * worldMatrix;
	vec3 worldNorm		= normal * mat3(worldMatrix);

	//Transform the position
	gl_Position			= viewProjMatrix * worldPos;
	
#if DEPTH_SHADOWCASTER
	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
	depth.y				= depthRange.w;
#else
	_uv0		= uv0.xy;
	oNormal		= worldNorm;
	oVPos		= worldPos.xyz;

	#if DEPTH_SHADOWRECEIVER
		oLightSpacePos		= texViewProjMatrix * worldPos;
		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
	#endif
#endif
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值