public override void UpdateLodData() { if (!enabled) { return; } base.UpdateLodData(); if (_mainLight != OceanRenderer.Instance._primaryLight) { if (_mainLight) { _mainLight.RemoveCommandBuffer(LightEvent.BeforeScreenspaceMask, BufCopyShadowMap); BufCopyShadowMap = null; TextureArrayHelpers.ClearToBlack(_sources); TextureArrayHelpers.ClearToBlack(_targets); } _mainLight = null; } if (!OceanRenderer.Instance._primaryLight) { if (!Settings._allowNullLight) { Debug.LogWarning("Primary light must be specified on OceanRenderer script to enable shadows.", OceanRenderer.Instance); } return; } if (!_mainLight) { if (!StartInitLight()) { enabled = false; return; } } if (BufCopyShadowMap == null && s_processData) { BufCopyShadowMap = new CommandBuffer(); BufCopyShadowMap.name = "Shadow data"; _mainLight.AddCommandBuffer(LightEvent.BeforeScreenspaceMask, BufCopyShadowMap); } else if (!s_processData && BufCopyShadowMap != null) { _mainLight.RemoveCommandBuffer(LightEvent.BeforeScreenspaceMask, BufCopyShadowMap); BufCopyShadowMap = null; } if (!s_processData) { return; } // Update the camera if it has changed. if (_cameraMain.transform != OceanRenderer.Instance.Viewpoint) { UpdateCameraMain(); } Swap(ref _sources, ref _targets); BufCopyShadowMap.Clear(); ValidateSourceData(); // clear the shadow collection. it will be overwritten with shadow values IF the shadows render, // which only happens if there are (nontransparent) shadow receivers around. this is only reliable // in play mode, so don't do it in edit mode. #if UNITY_EDITOR if (UnityEditor.EditorApplication.isPlaying) #endif { TextureArrayHelpers.ClearToBlack(_targets); } var lt = OceanRenderer.Instance._lodTransform; for (var lodIdx = lt.LodCount - 1; lodIdx >= 0; lodIdx--) { _renderProperties.Initialise(BufCopyShadowMap, _updateShadowShader, krnl_UpdateShadow); lt._renderData[lodIdx].Validate(0, SimName); _renderProperties.SetVector(sp_CenterPos, lt._renderData[lodIdx]._posSnapped); var scale = OceanRenderer.Instance.CalcLodScale(lodIdx); _renderProperties.SetVector(sp_Scale, new Vector3(scale, 1f, scale)); if (OceanRenderer.Instance.Viewpoint != null) { _renderProperties.SetVector(sp_CamPos, OceanRenderer.Instance.Viewpoint.position); _renderProperties.SetVector(sp_CamForward, OceanRenderer.Instance.Viewpoint.forward); } _renderProperties.SetVector(sp_JitterDiameters_CurrentFrameWeights, new Vector4(Settings._jitterDiameterSoft, Settings._jitterDiameterHard, Settings._currentFrameWeightSoft, Settings._currentFrameWeightHard)); _renderProperties.SetMatrix(sp_MainCameraProjectionMatrix, _cameraMain.projectionMatrix * _cameraMain.worldToCameraMatrix); _renderProperties.SetFloat(sp_SimDeltaTime, OceanRenderer.Instance.DeltaTimeDynamics); // compute which lod data we are sampling previous frame shadows from. if a scale change has happened this can be any lod up or down the chain. var srcDataIdx = lodIdx + ScaleDifferencePow2; srcDataIdx = Mathf.Clamp(srcDataIdx, 0, lt.LodCount - 1); _renderProperties.SetInt(sp_LD_SliceIndex, lodIdx); _renderProperties.SetInt(sp_LD_SliceIndex_Source, srcDataIdx); BindSourceData(_renderProperties, false); _renderProperties.SetTexture(sp_LD_TexArray_Target, _targets); BufCopyShadowMap.DispatchCompute(_updateShadowShader, krnl_UpdateShadow, OceanRenderer.Instance.LodDataResolution / THREAD_GROUP_SIZE_X, OceanRenderer.Instance.LodDataResolution / THREAD_GROUP_SIZE_Y, 1); } }
public override void UpdateLodData() { if (!enabled) { return; } base.UpdateLodData(); if (_mainLight != OceanRenderer.Instance._primaryLight) { if (_mainLight) { _mainLight.RemoveCommandBuffer(LightEvent.BeforeScreenspaceMask, BufCopyShadowMap); BufCopyShadowMap = null; TextureArrayHelpers.ClearToBlack(_sources); TextureArrayHelpers.ClearToBlack(_targets); } _mainLight = null; } if (!OceanRenderer.Instance._primaryLight) { if (!Settings._allowNullLight) { Debug.LogWarning("Primary light must be specified on OceanRenderer script to enable shadows.", OceanRenderer.Instance); } return; } if (!_mainLight) { if (!StartInitLight()) { enabled = false; return; } } if (BufCopyShadowMap == null && s_processData) { BufCopyShadowMap = new CommandBuffer(); BufCopyShadowMap.name = "Shadow data"; _mainLight.AddCommandBuffer(LightEvent.BeforeScreenspaceMask, BufCopyShadowMap); } else if (!s_processData && BufCopyShadowMap != null) { _mainLight.RemoveCommandBuffer(LightEvent.BeforeScreenspaceMask, BufCopyShadowMap); BufCopyShadowMap = null; } if (!s_processData) { return; } Swap(ref _sources, ref _targets); BufCopyShadowMap.Clear(); ValidateSourceData(); // clear the shadow collection. it will be overwritten with shadow values IF the shadows render, // which only happens if there are (nontransparent) shadow receivers around. this is only reliable // in play mode, so don't do it in edit mode. #if UNITY_EDITOR if (UnityEditor.EditorApplication.isPlaying) #endif { TextureArrayHelpers.ClearToBlack(_targets); } // Cache the camera for further down. var camera = OceanRenderer.Instance.ViewCamera; if (camera == null) { // We want to return early after clear. return; } { // Run shadow update // It feels like quite a lot could be optimized out of the below. I think the same params are written repeatedly, and probably // a bunch of them are already available in existing ocean globals. _renderProperties.Initialise(BufCopyShadowMap, _updateShadowShader, krnl_UpdateShadow); _renderProperties.SetVector(sp_CamPos, camera.transform.position); _renderProperties.SetVector(sp_CamForward, camera.transform.forward); _renderProperties.SetVector(sp_JitterDiameters_CurrentFrameWeights, new Vector4(Settings._jitterDiameterSoft, Settings._jitterDiameterHard, Settings._currentFrameWeightSoft, Settings._currentFrameWeightHard)); _renderProperties.SetMatrix(sp_MainCameraProjectionMatrix, camera.projectionMatrix * camera.worldToCameraMatrix); _renderProperties.SetFloat(sp_SimDeltaTime, OceanRenderer.Instance.DeltaTimeDynamics); _renderProperties.SetTexture(GetParamIdSampler(true), (Texture)_sources); _renderProperties.SetTexture(sp_LD_TexArray_Target, _targets); _renderProperties.SetBuffer(sp_cascadeDataSrc, OceanRenderer.Instance._bufCascadeDataSrc); var lt = OceanRenderer.Instance._lodTransform; for (var lodIdx = lt.LodCount - 1; lodIdx >= 0; lodIdx--) { #if UNITY_EDITOR lt._renderData[lodIdx].Validate(0, SimName); #endif _renderProperties.SetVector(sp_CenterPos, lt._renderData[lodIdx]._posSnapped); var scale = OceanRenderer.Instance.CalcLodScale(lodIdx); _renderProperties.SetVector(sp_Scale, new Vector3(scale, 1f, scale)); // compute which lod data we are sampling previous frame shadows from. if a scale change has happened this can be any lod up or down the chain. var srcDataIdx = lodIdx + ScaleDifferencePow2; srcDataIdx = Mathf.Clamp(srcDataIdx, 0, lt.LodCount - 1); _renderProperties.SetInt(sp_LD_SliceIndex, lodIdx); _renderProperties.SetInt(sp_LD_SliceIndex_Source, srcDataIdx); BufCopyShadowMap.DispatchCompute(_updateShadowShader, krnl_UpdateShadow, OceanRenderer.Instance.LodDataResolution / THREAD_GROUP_SIZE_X, OceanRenderer.Instance.LodDataResolution / THREAD_GROUP_SIZE_Y, 1); } #if ENABLE_VR && ENABLE_VR_MODULE // Disable for XR SPI otherwise input will not have correct world position. if (XRSettings.enabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced) { BufCopyShadowMap.DisableShaderKeyword("STEREO_INSTANCING_ON"); } #endif // Process registered inputs. for (var lodIdx = lt.LodCount - 1; lodIdx >= 0; lodIdx--) { BufCopyShadowMap.SetRenderTarget(_targets, _targets.depthBuffer, 0, CubemapFace.Unknown, lodIdx); SubmitDraws(lodIdx, BufCopyShadowMap); } #if ENABLE_VR && ENABLE_VR_MODULE // Restore XR SPI as we cannot rely on remaining pipeline to do it for us. if (XRSettings.enabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced) { BufCopyShadowMap.EnableShaderKeyword("STEREO_INSTANCING_ON"); } #endif } // Set the target texture as to make sure we catch the 'pong' each frame Shader.SetGlobalTexture(GetParamIdSampler(), _targets); }