void VPostProcessFXAA::Execute() { if (!IsActive() || !m_bIsInitialized) return; INSERT_PERF_MARKER_SCOPE("FXAA"); RenderingOptimizationHelpers_cl::SetShaderPreference(112); if (m_spFrameCopyTexture != NULL) { Vision::Renderer.CopyToTexture(m_spFrameCopyTexture, 0, 0, m_iWidth, m_iHeight); } VCompiledShaderPass *pPass = m_spMask->GetTechnique()->GetShader(0); VShaderConstantBuffer *pPS = pPass->GetConstantBuffer(VSS_PixelShader); hkvVec4 invScreenSize(1.0f / m_iWidth, 1.0f / m_iHeight, 0, 0); if (m_iRegScreenSize >= 0) { pPS->SetSingleRegisterF(m_iRegScreenSize, invScreenSize.data); } tempMasks.Clear(); tempMasks.AppendEntryFast(m_spMask); Vision::RenderLoopHelper.RenderScreenMasks(tempMasks); }
void VTerrainDecorationEntityModel::RenderBatchIR(VTerrainVisibilityCollectorComponent *pInfoComp, VTerrainDecorationInstance **pInstList, int iCount, RenderMode_e eRenderMode) { // IR Rendering VTerrainDecorationModelManager* pManager = (VTerrainDecorationModelManager *)GetParentManager(); VShaderEffectLib* pEffectLib = pManager->GetInfraredShaderLib(); if (iCount > 0 && pManager->m_iInstancingBatchCount > 0 && pEffectLib != NULL) { int iMaxInstanceCount, iInstanceStreamMask; VisSurface_cl* pSurface = m_spMesh->GetSurface(0); if (m_spInstancingTechIRPrePass == NULL) { // lazy IR shader init RecreateIRShaders(pSurface, pEffectLib); } if (m_spInstancingTechIRPrePass == NULL || m_spInstancingTechIRMainPass == NULL) return; const int iPrimitiveCount = m_spModelMesh->GetCurrentPrimitiveCount(); const int iVertexCount = m_spModelMesh->GetVertexCount(); const VisMeshBuffer_cl::MB_PrimitiveType_e ePrimType = m_spModelMesh->GetPrimitiveType(); bool bPrePass = (eRenderMode == RENDER_MODE_IR_PREPASS); VCompiledShaderPass* pShader = bPrePass? m_spInstancingTechIRPrePass->GetShader(0) : m_spInstancingTechIRMainPass->GetShader(0); const int iStreamMask = m_spModelMesh->GetStreamMask() & (pShader->GetStreamMask() | VERTEX_STREAM_INDEXBUFFER); VisMeshBuffer_cl* pInstanceMesh = pManager->GetInstanceBuffer(iMaxInstanceCount, iInstanceStreamMask); iInstanceStreamMask &= pShader->GetStreamMask(); // perform the rendering Vision::RenderLoopHelper.BeginMeshRendering(); Vision::RenderLoopHelper.BindDefaultStateGroups(pSurface, pShader); if (!bPrePass || pSurface->GetTransparencyType() != VIS_TRANSP_NONE) Vision::RenderLoopHelper.BindMeshTexture(pSurface->GetBaseTextureObject(), 0, NULL); while (iCount > 0) { int iRenderCount = hkvMath::Min(iCount, iMaxInstanceCount); // fill the instance buffer: { VISION_PROFILE_FUNCTION(VTerrainSectorManager::PROFILING_RENDERDECORARION_INSTANCE_SETUP); VModelInstanceData_t* pDest = (VModelInstanceData_t *)pInstanceMesh->LockVertices(VIS_LOCKFLAG_DISCARDABLE, 0, iRenderCount); for (int i = 0; i < iRenderCount; i++, pInstList++, pDest++) pDest->Set(*pInstList[0]); pInstanceMesh->UnLockVertices(); } iCount -= iRenderCount; RENDER_INSTANCES(iRenderCount, iStreamMask); } Vision::RenderLoopHelper.EndMeshRendering(); } }
void VRendererNodeCommon::RenderSceneDepth(bool bHalfSize) { PushAndDisableGlobalWireframeState(); if (m_spDepthOnlyTechnique == NULL) { Vision::Shaders.LoadShaderLibrary("\\Shaders\\BaseShaders.ShaderLib", SHADERLIBFLAG_HIDDEN); #ifdef _VISION_XENON m_spDepthOnlyTechnique360 = Vision::Shaders.CreateTechnique("CopyDepthOnly_360", NULL); VASSERT(m_spDepthOnlyTechnique360 != NULL); #endif m_spDepthOnlyTechnique = Vision::Shaders.CreateTechnique("CopyDepthOnly", NULL); VASSERT(m_spDepthOnlyTechnique != NULL); } #ifdef _VISION_XENON if(bHalfSize == false) { VASSERT_MSG(m_bDepthRestoreInitialized, "Fast depth restore has not been initialized"); VisHiZHelper_cl::FastDepthRestore(m_fastRestoreData, m_spDepthOnlyTechnique360->GetShader(0), VisHiZHelper_cl::VR_HIZ_RESTORE); } else { #endif IVRender2DInterface *pRenderer = Vision::RenderLoopHelper.BeginOverlayRendering(); VCompiledShaderPass *pPass = m_spDepthOnlyTechnique->GetShader(0); VStateGroupTexture *pStateGroupTexture = pPass->GetStateGroupTexture(VSS_PixelShader, 0); #ifdef _VISION_PS3 if (m_spDummyDepthTexture == NULL) m_spDummyDepthTexture = RenderingOptimizationHelpers_cl::CreateAndPatchDummyTexture(m_spDepthReadTarget); if (pStateGroupTexture != NULL) { pStateGroupTexture->m_spCustomTex = m_spDummyDepthTexture; pPass->m_bModified = true; } #else if (pStateGroupTexture != NULL) { pStateGroupTexture->m_spCustomTex = m_spDepthReadTarget; pPass->m_bModified = true; } #endif Overlay2DVertex_t *pVertices; if (bHalfSize) pVertices = GetRendererNodeHelper()->GetOverlayVerticesHalfSize(); else pVertices = GetRendererNodeHelper()->GetOverlayVertices(); pRenderer->Draw2DBufferWithShader(6, pVertices, NULL, *pPass); Vision::RenderLoopHelper.EndOverlayRendering(); #ifdef _VISION_XENON } #endif PopGlobalWireframeState(); }
void VPostProcessTranslucencies::BlendQuarterSizeIntoTarget(VCompiledTechnique* pTechnique) { IVRender2DInterface *pRenderer = Vision::RenderLoopHelper.BeginOverlayRendering(); VCompiledShaderPass *pPass = pTechnique->GetShader(0); VStateGroupTexture *pStateGroupTexture = pPass->GetStateGroupTexture(VSS_PixelShader, 0); if (pStateGroupTexture != NULL) pStateGroupTexture->m_spCustomTex = m_spLowResColorTexture; pRenderer->Draw2DBufferWithShader(6, GetOwner()->GetRendererNodeHelper()->GetOverlayVertices(), m_spLowResColorTexture, *pPass); Vision::RenderLoopHelper.EndOverlayRendering(); }
void VRendererNodeCommon::FreeCustomTextureRefs(VCompiledTechniquePtr &spTech) { if (spTech==NULL) return; for (unsigned int i=0;i<spTech->GetShaderCount();i++) { VCompiledShaderPass *pPass = spTech->GetShader(0); const unsigned int iActiveSamplerCount = pPass->GetActiveSamplerCount(VSS_PixelShader); for (unsigned int j=0;j<iActiveSamplerCount;j++) { VStateGroupTexture *pStateGroupTexture = pPass->GetStateGroupTexture(VSS_PixelShader, j); VASSERT(pStateGroupTexture != NULL); pStateGroupTexture->m_spCustomTex = NULL; pPass->m_bModified = true; } } spTech = NULL; // smart pointer reference }
void VTerrainDecorationEntityModel::RenderBatchOTW(VTerrainVisibilityCollectorComponent *pInfoComp, VTerrainDecorationInstance **pInstList, int iCount) { // OTW rendering VTerrainDecorationModelManager *pManager = (VTerrainDecorationModelManager *)GetParentManager(); if (m_spInstancingTech!=NULL && iCount>4 && pManager->m_iInstancingBatchCount>0 /* && bAllowInstancing*/) { VCompiledShaderPass *pShader = m_spInstancingTech->GetShader(0); Vision::RenderLoopHelper.BeginMeshRendering(); VisSurface_cl *pSurface = m_spMesh->GetSurface(0); Vision::RenderLoopHelper.BindSurfaceTextures(pSurface,pShader,NULL); Vision::RenderLoopHelper.BindDefaultStateGroups(pSurface,pShader); VisMeshBuffer_cl::MB_PrimitiveType_e ePrimType = m_spModelMesh->GetPrimitiveType(); int iPrimitiveCount = m_spModelMesh->GetCurrentPrimitiveCount(); int iVertexCount = m_spModelMesh->GetVertexCount(); int iMaxInstanceCount, iInstanceStreamMask; VisMeshBuffer_cl *pInstanceMesh = ((VTerrainDecorationModelManager *)GetParentManager())->GetInstanceBuffer(iMaxInstanceCount,iInstanceStreamMask); // lightmap version if (m_iLightmapSampler>=0 && pInfoComp!=NULL) { #ifdef HK_DEBUG const VStateGroupTexture *pStateGroupTexture = pShader->GetStateGroupTexture(VSS_PixelShader, m_iLightmapSampler); VASSERT(pStateGroupTexture!=NULL && pStateGroupTexture->m_cTextureType==TEXTURETYPE_LIGHTMAP); #endif VStateGroupSampler *pLMSampler = pShader->GetStateGroupSampler(VSS_PixelShader, m_iLightmapSampler); VTerrainSector *pLastSector = NULL; VTextureObject *pTerrainLightmap = NULL; const VTerrainConfig& config(pInfoComp->m_pTerrain->m_Config); VTerrainSectorManager §ormanager(pInfoComp->m_pTerrain->m_SectorManager); while (iCount>0) { int iWantedRenderCount = hkvMath::Min(iCount,iMaxInstanceCount); int iRenderCount = 0; // fill the instance buffer: { VISION_PROFILE_FUNCTION(VTerrainSectorManager::PROFILING_RENDERDECORARION_INSTANCE_SETUP); VModelInstanceData_t *pDest = (VModelInstanceData_t *)pInstanceMesh->LockVertices(VIS_LOCKFLAG_DISCARDABLE,0,iWantedRenderCount); // fill buffer up to lightmap change for (int i=0;i<iWantedRenderCount;i++,iRenderCount++,pDest++) { if (pLastSector!=pInstList[i]->m_pOwnerSector) { pLastSector = pInstList[i]->m_pOwnerSector; VTextureObject *pNewLightmap = pLastSector->m_pMeshPage[0].GetSurfaceSafe().m_spModelLightmaps[0]; if (pNewLightmap!=pTerrainLightmap) { if (iRenderCount>0) // start a new batch so break here break; } } pDest->Set(*pInstList[i]); } pInstanceMesh->UnLockVertices(); } // bind sector specific properties VTerrainSector *pStateSetupSector = pInstList[0]->m_pOwnerSector; // this is where the batch starts hkvVec4 vWorld2Sector(false); // transforms worldspace to sector 0..1 range config.GetWorldSpaceToSectorTransform(pStateSetupSector->m_iIndexX,pStateSetupSector->m_iIndexY,vWorld2Sector); sectormanager.SetWorld2SectorTransform(vWorld2Sector); // standard range -> lightmap const hkvVec4 vSector2LM = pStateSetupSector->GetLightmapScaleOffset(); VisRenderStates_cl::VSSetModelUVToLightmap(vSector2LM.data); Vision::RenderLoopHelper.BindMeshTexture(pStateSetupSector->m_pMeshPage[0].GetSurfaceSafe().m_spModelLightmaps[0],m_iLightmapSampler,pLMSampler); // advance by actual render counts pInstList += iRenderCount; iCount-=iRenderCount; RENDER_INSTANCES(iRenderCount, m_iModelStreams); } } else // non-lightmapped version { while (iCount>0) { int iRenderCount = hkvMath::Min(iCount,iMaxInstanceCount); // fill the instance buffer: { VISION_PROFILE_FUNCTION(VTerrainSectorManager::PROFILING_RENDERDECORARION_INSTANCE_SETUP); VModelInstanceData_t *pDest = (VModelInstanceData_t *)pInstanceMesh->LockVertices(VIS_LOCKFLAG_DISCARDABLE,0,iRenderCount); for (int i=0;i<iRenderCount;i++,pInstList++,pDest++) pDest->Set(*pInstList[0]); pInstanceMesh->UnLockVertices(); } iCount-=iRenderCount; RENDER_INSTANCES(iRenderCount, m_iModelStreams); } } Vision::RenderLoopHelper.EndMeshRendering(); return; } ////////////////////////////////////////////////////////// // Non-instancing version const VisDrawCallInfo_t *pSurfaceShaderList; VDynamicMesh *pMesh = m_spMesh; VASSERT(m_spVegetationShaders!=NULL); VisShaderSet_cl *pSet = m_spVegetationShaders; int iAsmCount = pSet->GetShaderAssignmentList(&pSurfaceShaderList); VColorRef iLastColor; #ifdef _VR_DX11 VisRenderStates_cl::SetVSConstantBuffer(7,&m_PerInstanceData); #endif if (m_bNeedsLightmap && pInfoComp!=NULL) { VTerrainSector *pLastSector = NULL; VTextureObject *pTerrainLightmap = NULL; const VTerrainConfig& config(pInfoComp->m_pTerrain->m_Config); VTerrainSectorManager §ormanager(pInfoComp->m_pTerrain->m_SectorManager); Vision::RenderLoopHelper.BeginEntityRendering(); for (int i=0;i<iCount;i++,pInstList++) { if (pLastSector!=(*pInstList)->m_pOwnerSector) { pLastSector = (*pInstList)->m_pOwnerSector; VTextureObject *pNewLightmap = pLastSector->m_pMeshPage[0].GetSurfaceSafe().m_spModelLightmaps[0]; if (pNewLightmap!=pTerrainLightmap) { // assign new model lightmaps const int iSrfCount = m_spMesh->GetSurfaceCount(); for (int j=0;j<iSrfCount;j++) m_spMesh->GetSurface(j)->m_spModelLightmaps[0] = pNewLightmap; // and also force a shader re-binding for (int j=0;j<iAsmCount;j++) pSurfaceShaderList[j].GetShader()->m_bModified=true; pTerrainLightmap = pNewLightmap; } hkvVec4 vWorld2Sector(false); // transforms worldspace to sector 0..1 range config.GetWorldSpaceToSectorTransform(pLastSector->m_iIndexX,pLastSector->m_iIndexY,vWorld2Sector); sectormanager.SetWorld2SectorTransform(vWorld2Sector); // standard range -> lightmap const hkvVec4 vSector2LM = pLastSector->GetLightmapScaleOffset(); VisRenderStates_cl::VSSetModelUVToLightmap(vSector2LM.data); } // per instance tint color if (i==0 || iLastColor!=(*pInstList)->m_InstanceColor) { iLastColor = (*pInstList)->m_InstanceColor; VPerInstanceData_t &data(m_PerInstanceData.BeginUpdate()); VColorRef::RGBA_To_Float((*pInstList)->m_InstanceColor, data.vPerInstanceColor); m_PerInstanceData.EndUpdate(); #ifndef _VR_DX11 VisRenderStates_cl::SetVSConstantBuffer(7,&m_PerInstanceData); #endif } // finally render object hkvMat4 transform((*pInstList)->m_Orientation,(*pInstList)->m_vPosition); Vision::RenderLoopHelper.RenderModelWithSurfaceShaderList(m_spMesh,transform.getPointer (),iAsmCount,pSurfaceShaderList); } VisRenderStates_cl::SetVSConstantBuffer(7,NULL); Vision::RenderLoopHelper.EndEntityRendering(); } else { Vision::RenderLoopHelper.BeginEntityRendering(); // no lightmaps -> simple loop for (int i=0;i<iCount;i++,pInstList++) { // per instance tint color if (i==0 || iLastColor!=(*pInstList)->m_InstanceColor) { iLastColor = (*pInstList)->m_InstanceColor; VPerInstanceData_t &data(m_PerInstanceData.BeginUpdate()); VColorRef::RGBA_To_Float((*pInstList)->m_InstanceColor, data.vPerInstanceColor); m_PerInstanceData.EndUpdate(); #ifndef _VR_DX11 VisRenderStates_cl::SetVSConstantBuffer(7,&m_PerInstanceData); #endif } hkvMat4 transform((*pInstList)->m_Orientation,(*pInstList)->m_vPosition); Vision::RenderLoopHelper.RenderModelWithSurfaceShaderList(m_spMesh,transform.getPointer(),iAsmCount,pSurfaceShaderList); } VisRenderStates_cl::SetVSConstantBuffer(7,NULL); Vision::RenderLoopHelper.EndEntityRendering(); } }
void VRendererNodeCommon::RenderSceneTextureWithDepth(bool bHalfSize) { PushAndDisableGlobalWireframeState(); if (m_spSceneDepthTechnique == NULL) { Vision::Shaders.LoadShaderLibrary("\\Shaders\\BaseShaders.ShaderLib", SHADERLIBFLAG_HIDDEN); m_spSceneDepthTechnique = Vision::Shaders.CreateTechnique("CopyWithDepthOutput", NULL); VASSERT(m_spSceneDepthTechnique != NULL); } #ifdef _VISION_XENON if(bHalfSize) { // first make sure the stencil buffer is cleared. // we clear it to all 1's, and then reset all geometry pixels to 0 // For this the shader simply checks a pixels depth and does a discard on sky pixels (depth == 1.0). // On all pixels that pass the test, the stencil value is set to zero. Vision::RenderLoopHelper.ClearScreen(VisRenderLoopHelper_cl::VCTF_DepthStencil, VColorRef (0, 0, 0, 0), 1.0f, 255); #endif IVRender2DInterface *pRenderer = Vision::RenderLoopHelper.BeginOverlayRendering(); VCompiledShaderPass *pPass = m_spSceneDepthTechnique->GetShader(0); VStateGroupTexture *pStateGroupTexture = pPass->GetStateGroupTexture(VSS_PixelShader, 0); if (pStateGroupTexture != NULL) pStateGroupTexture->m_spCustomTex = m_spColorReadTarget; pStateGroupTexture = pPass->GetStateGroupTexture(VSS_PixelShader, 1); #ifdef _VISION_PS3 if (m_spDummyDepthTexture == NULL) m_spDummyDepthTexture = RenderingOptimizationHelpers_cl::CreateAndPatchDummyTexture(m_spDepthReadTarget); if (pStateGroupTexture != NULL) { pStateGroupTexture->m_spCustomTex = m_spDummyDepthTexture; pPass->m_bModified = true; } #else if (pStateGroupTexture != NULL) { pStateGroupTexture->m_spCustomTex = m_spDepthReadTarget; pPass->m_bModified = true; } #endif Overlay2DVertex_t *pVertices; if (bHalfSize) pVertices = GetRendererNodeHelper()->GetOverlayVerticesHalfSize(); else pVertices = GetRendererNodeHelper()->GetOverlayVertices(); pRenderer->Draw2DBufferWithShader(6, pVertices, NULL, *pPass); Vision::RenderLoopHelper.EndOverlayRendering(); #ifdef _VISION_XENON } else { if(m_spDepthOnlyTechnique360 == NULL) { m_spDepthOnlyTechnique360 = Vision::Shaders.CreateTechnique("CopyDepthOnly_360", NULL); VASSERT(m_spDepthOnlyTechnique360 != NULL); } VASSERT_MSG(m_bDepthRestoreInitialized, "Fast depth restore has not been initialized"); //Restore color first (can't do this in one step because of a certification issue with Depth only rendering right after MRT rendering) RenderSceneTexture(bHalfSize); //Restore depth and stencil with xbox 360 specific implementation VisHiZHelper_cl::FastDepthRestore(m_fastRestoreData, m_spDepthOnlyTechnique360->GetShader(0)); } #endif PopGlobalWireframeState(); }
void VCoronaManager::RenderCorona (VCoronaCandidate& coronaCandidate, VTextureObject*& pTexture) { #ifdef SUPPORTS_CORONAS VCoronaComponent *pCorona = coronaCandidate.m_pCorona; VisRenderContext_cl* pContext = VisRenderContext_cl::GetCurrentContext(); VisLightSource_cl* pLight = (VisLightSource_cl*)pCorona->GetOwner(); hkvVec3 vLightPos(hkvNoInitialization); pLight->GetVirtualPosition(vLightPos, pContext); hkvVec3 vEyePos(hkvNoInitialization); pContext->GetCamera()->GetPosition(vEyePos); hkvVec3 vDir = pContext->GetCamera()->GetDirection(); // Corona texture VTextureObject *pTex = pCorona->GetCoronaTexture(); if (pTex == NULL) return; if (pTexture != pTex) { pTexture = pTex; Vision::RenderLoopHelper.BindMeshTexture(pTexture,0); } // Get light color VColorRef color = pLight->GetColor(); hkvVec3 vDist = vLightPos - vEyePos; float fEyeDist = vDir.dot(vDist); //determine if camera is in light cone if the light is directional float fDirectionalDampening = 1.0f; if ( pLight->GetType() == VIS_LIGHT_SPOTLIGHT && pCorona->GetOnlyVisibleInSpotLight() ) { fDirectionalDampening = 0.0f; float fConeAngle = pLight->GetProjectionAngle(); float fConeLength = pLight->GetRadius(); hkvVec3 fConeDirection = pLight->GetDirection(); fConeDirection.normalize(); hkvVec3 vLightEyeDist = vEyePos - vLightPos; //#2 check if the camera is inside the angle of the cone float cosinusAngle = (vLightEyeDist/vLightEyeDist.getLength()).dot(fConeDirection); float fDegree = hkvMath::acosDeg(cosinusAngle); float normRadius = fDegree / (fConeAngle/2.0f); if (normRadius < 1.0f) { //hardcoded falloff. For better performance, we avoid sampling the projection texture here. const float fEpsilon = 64.0f/256.0f; const float fQuadFactor = 1.0f/fEpsilon - 1.0f; fDirectionalDampening = 1.0f / (1.0f + fQuadFactor*normRadius*normRadius); // scale the function so that the value is exactly 0.0 at the edge and 1.0 in the center fDirectionalDampening = (fDirectionalDampening - fEpsilon) / (1.0f - fEpsilon); } } // Fog params float fFogDampening = 1.0f; if (pLight->GetType() != VIS_LIGHT_DIRECTED && Vision::World.IsLinearDepthFogEnabled()) { const VFogParameters &fog = Vision::World.GetFogParameters(); float fFogStart = fog.fDepthStart; float fFogEnd = fog.fDepthEnd; float fFogFactor = (fFogEnd > fFogStart) ? ((fEyeDist - fFogStart) / (fFogEnd - fFogStart)) : 0.f; fFogDampening = 1.0f - hkvMath::clamp(fFogFactor, 0.0f, 1.0f); } // Get corona rotation float fRotation = 0.0f; hkvVec4 vRotation(1.0f, 0.0f, 0.0f, 1.0f); if (pCorona->CoronaFlags & VIS_CORONASCALE_ROTATING) { fRotation = hkvMath::mod (fEyeDist * 0.5f, 360.f); vRotation.x = hkvMath::cosDeg (fRotation); vRotation.y = -hkvMath::sinDeg (fRotation); vRotation.z = -vRotation.y; vRotation.w = vRotation.x; } // Texture dimensions int iSizeX, iSizeY, depth; pTex->GetTextureDimensions(iSizeX, iSizeY, depth); hkvVec4 vScale(0.0f, 0.0f, 0.0f, 0.0f); int iMainWidth, iMainHeight, iWidth, iHeight; pContext->GetSize(iWidth, iHeight); VisRenderContext_cl::GetMainRenderContext()->GetSize(iMainWidth, iMainHeight); // Preserve texture aspect ratio int iTexHeight = pTex->GetTextureHeight(); int iTexWidth = pTex->GetTextureWidth(); // Perspective scaling // This scaling ensures roughly the same size on 720p as the old implementation. vScale.z = iTexWidth * pCorona->CoronaScaling * 0.25f; vScale.w = iTexHeight * pCorona->CoronaScaling * 0.25f; // Screen-space scaling // This scaling ensures roughly the same size on 720p as the old implementation. const float fScaleFactor = pCorona->CoronaScaling * iMainHeight / 11.0f; vScale.x = ((float)iTexWidth / 128.0f) * fScaleFactor * (float(iWidth) / float(iMainWidth)); vScale.y = ((float)iTexHeight / 128.0f) * fScaleFactor * (float(iHeight) / float(iMainHeight)); vScale.x *= 2.0f / iWidth; vScale.y *= 2.0f / iHeight; // Scale by visibility if (pCorona->CoronaFlags & VIS_CORONASCALE_VISIBLEAREA) { vScale.x *= coronaCandidate.m_fCurrentVisibility; vScale.y *= coronaCandidate.m_fCurrentVisibility; vScale.z *= coronaCandidate.m_fCurrentVisibility; vScale.w *= coronaCandidate.m_fCurrentVisibility; } VCompiledShaderPass* pShader = m_spCoronaTechnique->GetShader(0); VShaderConstantBuffer *pVertexConstBuffer = pShader->GetConstantBuffer(VSS_VertexShader); // xyz = worldspace position, w = 1.0 if VIS_CORONASCALE_DISTANCE is true, otherwise zero. pVertexConstBuffer->SetSingleParameterF("coronaPosition", vLightPos.x, vLightPos.y, vLightPos.z, (pCorona->CoronaFlags & VIS_CORONASCALE_DISTANCE) ? 1.0f : 0.0f); // xyz = light color, w = corona visibility. pVertexConstBuffer->SetSingleParameterF("coronaColor", color.r/255.0f, color.g/255.0f, color.b/255.0f, coronaCandidate.m_fCurrentVisibility * fFogDampening * fDirectionalDampening); // xyzw = 2x2 rotation matrix. float2x2 is not supported in shader model 2, so a float4 is used and multiplication is done manually in the shader. pVertexConstBuffer->SetSingleParameterF("coronaRotation", vRotation.x, vRotation.y, vRotation.z, vRotation.w); // xy = screen-space scaling. zw = view-space scaling. pVertexConstBuffer->SetSingleParameterF("coronaScale", vScale.x, vScale.y, vScale.z, vScale.w); Vision::RenderLoopHelper.RenderMeshes(pShader, VisMeshBuffer_cl::MB_PRIMTYPE_TRILIST, 0, 2, 6); #endif }