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); }
public override void UpdateLodData() { if (!enabled) { return; } base.UpdateLodData(); ClearBufferIfLightChanged(); if (!StartInitLight()) { enabled = false; return; } if (!s_processData) { return; } if (BufCopyShadowMap == null) { BufCopyShadowMap = new CommandBuffer(); BufCopyShadowMap.name = "Shadow data"; } 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; } // TODO - this is in SRP, so i can't ifdef it? what is a good plan here - wait for it to be removed completely? #pragma warning disable 618 using (new ProfilingSample(BufCopyShadowMap, "CrestSampleShadows")) #pragma warning restore 618 { var lt = OceanRenderer.Instance._lodTransform; for (var lodIdx = lt.LodCount - 1; lodIdx >= 0; lodIdx--) { #if UNITY_EDITOR lt._renderData[lodIdx].Validate(0, SimName); #endif _renderMaterial[lodIdx].SetVector(sp_CenterPos, lt._renderData[lodIdx]._posSnapped); var scale = OceanRenderer.Instance.CalcLodScale(lodIdx); _renderMaterial[lodIdx].SetVector(sp_Scale, new Vector3(scale, 1f, scale)); _renderMaterial[lodIdx].SetVector(sp_JitterDiameters_CurrentFrameWeights, new Vector4(Settings._jitterDiameterSoft, Settings._jitterDiameterHard, Settings._currentFrameWeightSoft, Settings._currentFrameWeightHard)); _renderMaterial[lodIdx].SetMatrix(sp_MainCameraProjectionMatrix, GL.GetGPUProjectionMatrix(camera.projectionMatrix, renderIntoTexture: true) * camera.worldToCameraMatrix); _renderMaterial[lodIdx].SetFloat(sp_SimDeltaTime, Time.deltaTime); // 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); _renderMaterial[lodIdx].SetFloat(sp_LD_SliceIndex, lodIdx); _renderMaterial[lodIdx].SetFloat(sp_LD_SliceIndex_Source, srcDataIdx); _renderMaterial[lodIdx].SetTexture(GetParamIdSampler(true), _sources); _renderMaterial[lodIdx].SetBuffer(sp_cascadeDataSrc, OceanRenderer.Instance._bufCascadeDataSrc); BufCopyShadowMap.Blit(Texture2D.blackTexture, _targets, _renderMaterial[lodIdx].material, -1, lodIdx); } // Disable single pass double-wide stereo rendering for these commands since we are rendering to // rendering texture. Otherwise, it will render double. Single pass instanced is broken here, but that // appears to be a Unity bug only for the legacy VR system. if (camera.stereoEnabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePass) { BufCopyShadowMap.SetSinglePassStereo(SinglePassStereoMode.None); BufCopyShadowMap.DisableShaderKeyword("UNITY_SINGLE_PASS_STEREO"); } // Process registered inputs. for (var lodIdx = lt.LodCount - 1; lodIdx >= 0; lodIdx--) { BufCopyShadowMap.SetRenderTarget(_targets, _targets.depthBuffer, 0, CubemapFace.Unknown, lodIdx); SubmitDraws(lodIdx, BufCopyShadowMap); } // Restore single pass double-wide as we cannot rely on remaining pipeline to do it for us. if (camera.stereoEnabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePass) { BufCopyShadowMap.SetSinglePassStereo(SinglePassStereoMode.SideBySide); BufCopyShadowMap.EnableShaderKeyword("UNITY_SINGLE_PASS_STEREO"); } // Set the target texture as to make sure we catch the 'pong' each frame Shader.SetGlobalTexture(GetParamIdSampler(), _targets); } }