Example #1
0
        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);
            }
        }