private void ResolveRenderingTextures(OperationParameters iParameters) { // Prepare render textures. floorOcclusionMask = new PixelPerfectRT(operationParameters.fovPPRTParameter); wallFloorOcclusionMask = new PixelPerfectRT(operationParameters.fovPPRTParameter); mTex2DWallFloorOcclusionMask = new Texture2D(wallFloorOcclusionMask.renderTexture.width, wallFloorOcclusionMask.renderTexture.height, TextureFormat.RGB24, false); objectOcclusionMask = new PixelPerfectRT(operationParameters.lightPPRTParameter); obstacleLightMask = new PixelPerfectRT(operationParameters.obstacleLightPPRTParameter); // Let members handle their own textures. // Possibly move to container? mPostProcessingStack.ResetRenderingTextures(iParameters); mBackgroundRenderer.ResetRenderingTextures(iParameters); }
public void CreateWallLightMask( PixelPerfectRT iLightMask, PixelPerfectRT iObstacleLightMask, RenderSettings iRenderSettings, float iCameraSize) { // Down Scale light mask and blur it. PixelPerfectRT.Transform(iLightMask, iObstacleLightMask, mMaterialContainer); mMaterialContainer.lightWallBlurMaterial.SetVector("_MultiLimit", new Vector4(iRenderSettings.occlusionMaskMultiplier, iRenderSettings.occlusionMaskLimit, 0, 0)); Blur(iObstacleLightMask.renderTexture, mMaterialContainer.lightWallBlurMaterial, iRenderSettings.occlusionBlurInterpolation, iRenderSettings.occlusionBlurIterations, blurRenderTextureOccLight, iCameraSize); }
public void GenerateFovMask( PixelPerfectRT iRawOcclusionMask, PixelPerfectRT iGlobalOcclusionExtendedMask, RenderSettings iRenderSettings, Vector3 iFovCenterInViewSpace, float iFovDistance, OperationParameters iOperationParameters) { mMaterialContainer.fovMaterial.SetVector("_PositionOffset", iFovCenterInViewSpace); mMaterialContainer.fovMaterial.SetFloat("_OcclusionSpread", iRenderSettings.fovOcclusionSpread); // Adjust scale from Extended mask to Screen size mask. float _yUVScale = 1 / ((float)iGlobalOcclusionExtendedMask.renderTexture.width / iGlobalOcclusionExtendedMask.renderTexture.height); Vector3 _adjustedDistance = iFovDistance * iOperationParameters.cameraViewportUnitsInWorldSpace * iRawOcclusionMask.orthographicSize / iGlobalOcclusionExtendedMask.orthographicSize; mMaterialContainer.fovMaterial.SetVector("_Distance", new Vector3(_adjustedDistance.x, _yUVScale, iRenderSettings.fovHorizonSmooth)); iRawOcclusionMask.renderTexture.filterMode = FilterMode.Bilinear; PixelPerfectRT.Blit(iRawOcclusionMask, iGlobalOcclusionExtendedMask, mMaterialContainer.fovMaterial); }
public PixelPerfectRT Render( Camera iCameraToMatch, PixelPerfectRTParameter iPPRTParameter, bool iMatrixRotationMode) { // Arrange. Vector2 _renderPosition; if (iMatrixRotationMode == false) { _renderPosition = iPPRTParameter.GetFilteredRendererPosition(iCameraToMatch.transform.position, mPreviousCameraPosition, mPreviousFilteredPosition); } else { // Note: Do not apply PixelPerfect position when matrix is rotating. _renderPosition = iCameraToMatch.transform.position; } mPreviousCameraPosition = iCameraToMatch.transform.position; mPreviousFilteredPosition = _renderPosition; mMaskCamera.enabled = false; mMaskCamera.backgroundColor = new Color(0, 0, 0, 0); mMaskCamera.transform.position = _renderPosition; mMaskCamera.orthographicSize = iPPRTParameter.orthographicSize; if (mPPRenderTexture == null) { mPPRenderTexture = new PixelPerfectRT(iPPRTParameter); } else { mPPRenderTexture.Update(iPPRTParameter); } // Execute. mPPRenderTexture.Render(mMaskCamera); return(mPPRenderTexture); }
private void OnRenderImage(RenderTexture iSource, RenderTexture iDestination) { if (renderSettings.doubleFrameRenderingMode) { if (mDoubleFrameRendererSwitch) { var _blitMaterial = materialContainer.blitMaterial; _blitMaterial.SetVector("_LightTransform", mlightPPRT.GetTransformation(mMainCamera)); _blitMaterial.SetVector("_OcclusionTransform", floorOcclusionMask.GetTransformation(mMainCamera)); Graphics.Blit(iSource, iDestination, _blitMaterial); mDoubleFrameRendererSwitch = false; return; } mDoubleFrameRendererSwitch = true; } if (materialContainer.blitMaterial == null) { Debug.Log($"FovSystemManager: Unable to blit Fov mask. {nameof(materialContainer.blitMaterial)} not provided."); return; } if (objectOcclusionMask == null) { Graphics.Blit(iSource, iDestination); return; } using (new DisposableProfiler("5. Light Mask Render (No Gfx Time)")) { mlightPPRT = mLightMaskRenderer.Render( mMainCamera, operationParameters.lightPPRTParameter, floorOcclusionMask, renderSettings, matrixRotationMode); } using (new DisposableProfiler("6. Generate Obstacle Light Mask")) { mPostProcessingStack.CreateWallLightMask( mlightPPRT, obstacleLightMask, renderSettings, operationParameters.cameraOrthographicSize); } // Debug View Selection. if (renderSettings.viewMode == RenderSettings.ViewMode.LightLayer) { PixelPerfectRT.Transform(mlightPPRT, iDestination, mMainCamera, materialContainer); return; } else if (renderSettings.viewMode == RenderSettings.ViewMode.WallLayer) { PixelPerfectRT.Transform(obstacleLightMask, iDestination, mMainCamera, materialContainer); return; } else if (renderSettings.viewMode == RenderSettings.ViewMode.FovObjectOcclusion) { PixelPerfectRT.Transform(objectOcclusionMask, iDestination, mMainCamera, materialContainer); return; } else if (renderSettings.viewMode == RenderSettings.ViewMode.FovFloorOcclusion) { PixelPerfectRT.Transform(floorOcclusionMask, iDestination, mMainCamera, materialContainer); return; } else if (renderSettings.viewMode == RenderSettings.ViewMode.FovWallAndFloorOcclusion) { PixelPerfectRT.Transform(wallFloorOcclusionMask, iDestination, mMainCamera, materialContainer); return; } else if (renderSettings.viewMode == RenderSettings.ViewMode.Obstacle) { PixelPerfectRT.Transform(mOcclusionPPRT, iDestination, mMainCamera, materialContainer); return; } using (new DisposableProfiler("7. Light Mask Blur")) { mPostProcessingStack.BlurLightMask(mlightPPRT.renderTexture, renderSettings, operationParameters.cameraOrthographicSize, mMatrixRotationModeBlend); } RenderTexture _backgroundMask = null; using (new DisposableProfiler("8. Render Background")) { _backgroundMask = mBackgroundRenderer.Render(renderSettings); } // Debug Views Selection. if (renderSettings.viewMode == RenderSettings.ViewMode.LightLayerBlurred) { PixelPerfectRT.Transform(mlightPPRT, iDestination, mMainCamera, materialContainer); return; } else if (renderSettings.viewMode == RenderSettings.ViewMode.Background) { Graphics.Blit(_backgroundMask, iDestination); return; } using (new DisposableProfiler("9. Blit Scene with Mixed Lights")) { mlightPPRT.renderTexture.filterMode = FilterMode.Bilinear; obstacleLightMask.renderTexture.filterMode = FilterMode.Bilinear; floorOcclusionMask.renderTexture.filterMode = matrixRotationMode ? FilterMode.Bilinear : FilterMode.Point; var _blitMaterial = materialContainer.blitMaterial; _blitMaterial.SetTexture("_LightMask", mlightPPRT.renderTexture); _blitMaterial.SetTexture("_OcclusionMask", floorOcclusionMask.renderTexture); _blitMaterial.SetTexture("_ObstacleLightMask", obstacleLightMask.renderTexture); _blitMaterial.SetVector("_LightTransform", mlightPPRT.GetTransformation(mMainCamera)); _blitMaterial.SetVector("_OcclusionTransform", floorOcclusionMask.GetTransformation(mMainCamera)); _blitMaterial.SetTexture("_BackgroundTex", _backgroundMask); _blitMaterial.SetVector("_AmbLightBloomSA", new Vector4(renderSettings.ambient, renderSettings.lightMultiplier, renderSettings.bloomSensitivity, renderSettings.bloomAdd)); _blitMaterial.SetFloat("_BackgroundMultiplier", renderSettings.backgroundMultiplier); Graphics.Blit(iSource, iDestination, _blitMaterial); } }
private void OnPreRender() { if (renderSettings.doubleFrameRenderingMode && mDoubleFrameRendererSwitch == false) { Shader.SetGlobalVector("_ObjectFovMaskTransformation", objectOcclusionMask.GetTransformation(mMainCamera)); return; } using (new DisposableProfiler("1. Occlusion Mask Render (No Gfx Time)")) { mOcclusionPPRT = mOcclusionRenderer.Render(mMainCamera, operationParameters.occlusionPPRTParameter, matrixRotationMode); if (mMatrixRotationModeBlend > 0.001f) { mPostProcessingStack.BlurOcclusionMaskRotation(mOcclusionPPRT.renderTexture, renderSettings, operationParameters.cameraOrthographicSize, mMatrixRotationModeBlend); } } using (new DisposableProfiler("2. Generate FoV")) { if (wallFloorOcclusionMask == null) { floorOcclusionMask = new PixelPerfectRT(operationParameters.fovPPRTParameter); wallFloorOcclusionMask = new PixelPerfectRT(operationParameters.fovPPRTParameter); } else { floorOcclusionMask.Update(operationParameters.fovPPRTParameter); wallFloorOcclusionMask.Update(operationParameters.fovPPRTParameter); } // This step will result in two masks: floorOcclusionMask used later in light mixing, and floorWallOcclusionMask which is only used for calculating // objects / wallmounts sprite visibility. Vector3 _fovCenterInWorldSpace = transform.TransformPoint(fovCenterOffset); Vector3 _fovCenterOffsetInViewSpace = mMainCamera.WorldToViewportPoint(_fovCenterInWorldSpace) - new Vector3(0.5f, 0.5f, 0); Vector3 _fovCenterOffsetInExtendedViewSpace = _fovCenterOffsetInViewSpace * (float)operationParameters.cameraOrthographicSize / mOcclusionPPRT.orthographicSize; mPostProcessingStack.GenerateFovMask(mOcclusionPPRT, floorOcclusionMask, wallFloorOcclusionMask, renderSettings, _fovCenterOffsetInExtendedViewSpace, fovDistance, operationParameters); if (!renderSettings.disableAsyncGPUReadback && SystemInfo.supportsAsyncGPUReadback) { // Request asynchronous callback for access to texture data. // Used for sampling point visibility from mask. AsyncGPUReadback.Request(wallFloorOcclusionMask.renderTexture, 0, AsyncReadCallback); } else { //async readback not supported, instead use synchronous readback RenderTexture.active = wallFloorOcclusionMask.renderTexture; mTex2DWallFloorOcclusionMask.ReadPixels(new Rect(0, 0, wallFloorOcclusionMask.renderTexture.width, wallFloorOcclusionMask.renderTexture.height), 0, 0); mTex2DWallFloorOcclusionMask.Apply(); } } using (new DisposableProfiler("3. Object Occlusion Mask")) { // These step calculates the objectOcclusionMask using the wallFloorOcclusionMask, so that objects / wallmounts will be hidden // if they are not in view objectOcclusionMask.Update(operationParameters.lightPPRTParameter); PixelPerfectRT.Transform(wallFloorOcclusionMask, objectOcclusionMask, materialContainer); // Update shader global transformation for occlusionMaskExtended so sprites can transform mask correctly. Shader.SetGlobalVector("_ObjectFovMaskTransformation", objectOcclusionMask.GetTransformation(mMainCamera)); } using (new DisposableProfiler("4. Blur Object Occlusion Mask")) { // Note: This blur is used only with shaders during scene render, so 1 pass should be enough. mPostProcessingStack.BlurOcclusionMask(objectOcclusionMask.renderTexture, renderSettings, operationParameters.cameraOrthographicSize); objectOcclusionMask.renderTexture.filterMode = FilterMode.Point; } // Note: After execution of this method, MainCamera.Render will be executed and scene will be drawn. }