static void updateJointMatricesNoJob( tAnimHierarchy* pAnimHierarchy, tMatrix44* aAnimMatrices ) { // update joint matrices in hierarchy // use worker threads int iJoint = 0; int iLevel = 0; for( ;; ) { if( iJoint >= pAnimHierarchy->miNumJoints ) { break; } tJoint* pJoint = &pAnimHierarchy->maJoints[iJoint]; if( pJoint->miLevel > iLevel ) { // update next level ++iLevel; } int iJointIndex = 0; int iNumHierarchyJoints = pAnimHierarchy->miNumJoints; for( iJointIndex = 0; iJointIndex < iNumHierarchyJoints; iJointIndex++ ) { if( !strcmp( pAnimHierarchy->maJoints[iJointIndex].mszName, pJoint->mszName ) ) { break; } } WTFASSERT2( iJointIndex < iNumHierarchyJoints, "can't find joint in hierarchy" ); // transform tMatrix44 const* pParentMatrix = &gIdentityMat; if( pJoint->mpParent ) { pParentMatrix = pJoint->mpParent->mpTotalMatrix; } // M(total) = M(parent) * M(local) * M(anim) tMatrix44 parentLocalMatrix; tMatrix44* pTotalMatrix = pJoint->mpTotalMatrix; tMatrix44* pSkinMatrix = pJoint->mpSkinMatrix; Matrix44Multiply( &parentLocalMatrix, pParentMatrix, pJoint->mpLocalMatrix ); //Matrix44Multiply( pTotalMatrix, &parentLocalMatrix, pJoint->mpAnimMatrix ); Matrix44Multiply( pTotalMatrix, &parentLocalMatrix, &aAnimMatrices[iJointIndex]); // M(skin) = M(total) * M(invPose) Matrix44Multiply( pJoint->mpSkinMatrix, pTotalMatrix, pJoint->mpInvPoseMatrix ); // M(invTransposeSkin) tMatrix44 invSkinMatrix; Matrix44Inverse( &invSkinMatrix, pSkinMatrix ); Matrix44Transpose( pJoint->mpInvTransSkinningMatrix, &invSkinMatrix ); ++iJoint; } }
void LightList::QueueTiledLightCulling(Renderer& rRenderer, const Camera& rCamera) { RdrResourceCommandList* pResCommandList = rRenderer.GetActionCommandList(); Vec2 viewportSize = rRenderer.GetViewportSize(); uint tileCountX = RdrComputeOp::getThreadGroupCount((uint)viewportSize.x, TILEDLIGHTING_TILE_SIZE); uint tileCountY = RdrComputeOp::getThreadGroupCount((uint)viewportSize.y, TILEDLIGHTING_TILE_SIZE); bool tileCountChanged = false; if (m_tiledLightData.tileCountX != tileCountX || m_tiledLightData.tileCountY != tileCountY) { m_tiledLightData.tileCountX = tileCountX; m_tiledLightData.tileCountY = tileCountY; tileCountChanged = true; } ////////////////////////////////////// // Depth min max if (tileCountChanged) { if (m_tiledLightData.hDepthMinMaxTex) pResCommandList->ReleaseResource(m_tiledLightData.hDepthMinMaxTex); m_tiledLightData.hDepthMinMaxTex = pResCommandList->CreateTexture2D(tileCountX, tileCountY, RdrResourceFormat::R16G16_FLOAT, RdrResourceUsage::Default, nullptr); } // Update constants Matrix44 viewMtx; Matrix44 invProjMtx; rCamera.GetMatrices(viewMtx, invProjMtx); invProjMtx = Matrix44Inverse(invProjMtx); invProjMtx = Matrix44Transpose(invProjMtx); uint constantsSize = sizeof(Vec4) * 4; Vec4* pConstants = (Vec4*)RdrFrameMem::AllocAligned(constantsSize, 16); for (int i = 0; i < 4; ++i) { pConstants[i].x = invProjMtx.m[i][0]; pConstants[i].y = invProjMtx.m[i][1]; pConstants[i].z = invProjMtx.m[i][2]; pConstants[i].w = invProjMtx.m[i][3]; } m_tiledLightData.hDepthMinMaxConstants = pResCommandList->CreateUpdateConstantBuffer(m_tiledLightData.hDepthMinMaxConstants, pConstants, constantsSize, RdrCpuAccessFlags::Write, RdrResourceUsage::Dynamic); // Fill draw op RdrComputeOp* pDepthOp = RdrFrameMem::AllocComputeOp(); pDepthOp->shader = RdrComputeShader::TiledDepthMinMax; pDepthOp->threads[0] = tileCountX; pDepthOp->threads[1] = tileCountY; pDepthOp->threads[2] = 1; pDepthOp->ahWritableResources.assign(0, m_tiledLightData.hDepthMinMaxTex); pDepthOp->ahResources.assign(0, rRenderer.GetPrimaryDepthBuffer()); pDepthOp->ahConstantBuffers.assign(0, m_tiledLightData.hDepthMinMaxConstants); rRenderer.AddComputeOpToPass(pDepthOp, RdrPass::LightCulling); ////////////////////////////////////// // Light culling if (tileCountChanged) { if (m_tiledLightData.hLightIndices) pResCommandList->ReleaseResource(m_tiledLightData.hLightIndices); m_tiledLightData.hLightIndices = pResCommandList->CreateDataBuffer(nullptr, tileCountX * tileCountY * TILEDLIGHTING_BLOCK_SIZE, RdrResourceFormat::R16_UINT, RdrResourceUsage::Default); } // Update constants constantsSize = sizeof(TiledLightCullingParams); TiledLightCullingParams* pParams = (TiledLightCullingParams*)RdrFrameMem::AllocAligned(constantsSize, 16); Matrix44 mtxProj; rCamera.GetMatrices(pParams->mtxView, mtxProj); pParams->mtxView = Matrix44Transpose(pParams->mtxView); pParams->proj_11 = mtxProj._11; pParams->proj_22 = mtxProj._22; pParams->cameraNearDist = rCamera.GetNearDist(); pParams->cameraFarDist = rCamera.GetFarDist(); pParams->screenSize = viewportSize; pParams->fovY = rCamera.GetFieldOfViewY(); pParams->aspectRatio = rCamera.GetAspectRatio(); pParams->spotLightCount = m_spotLights.size(); pParams->pointLightCount = m_pointLights.size(); pParams->tileCountX = tileCountX; pParams->tileCountY = tileCountY; m_tiledLightData.hCullConstants = pResCommandList->CreateUpdateConstantBuffer(m_tiledLightData.hCullConstants, pParams, constantsSize, RdrCpuAccessFlags::Write, RdrResourceUsage::Dynamic); // Fill draw op RdrComputeOp* pCullOp = RdrFrameMem::AllocComputeOp(); pCullOp->threads[0] = tileCountX; pCullOp->threads[1] = tileCountY; pCullOp->threads[2] = 1; pCullOp->ahWritableResources.assign(0, m_tiledLightData.hLightIndices); pCullOp->ahResources.assign(0, m_hSpotLightListRes); pCullOp->ahResources.assign(1, m_hPointLightListRes); pCullOp->ahResources.assign(2, m_tiledLightData.hDepthMinMaxTex); pCullOp->ahConstantBuffers.assign(0, m_tiledLightData.hCullConstants); rRenderer.AddComputeOpToPass(pCullOp, RdrPass::LightCulling); }