Ejemplo n.º 1
0
    void LateUpdate()
    {
        //求阴影产生物体的包围盒
        Bounds b = new Bounds();

        for (int i = 0; i < _shadowCasterList.Count; i++)
        {
            if (_shadowCasterList[i] != null)
            {
                b.Encapsulate(_shadowCasterList[i].bounds);
            }
        }
        b.extents += Vector3.one * boundsOffset;

//        Bounds bc = new Bounds();
//        for (int i = 0; i < _boxCasterList.Count; i++)
//        {
//            if (_boxCasterList[i] != null)
//            {
//                bc.Encapsulate(_boxCasterList[i].bounds);
//            }
//        }
//        bc.extents += Vector3.one * boundsOffset;
#if UNITY_EDITOR
        _boundsCollider.center = b.center;
        _boundsCollider.size   = b.size;
#endif
        //根据mainCamera来更新lightCamera和projector的位置,和设置参数
        ShadowUtils.SetLightCamera(b, _lightCamera);
        _projector.aspectRatio      = _lightCamera.aspect;
        _projector.orthographicSize = _lightCamera.orthographicSize;
        _projector.nearClipPlane    = _lightCamera.nearClipPlane;
        _projector.farClipPlane     = _lightCamera.farClipPlane;
    }
Ejemplo n.º 2
0
    void LateUpdate()
    {
        //求阴影产生物体的包围盒

        /*Bounds b = new Bounds();
         * for (int i = 0; i < _shadowCasterList.Count; i++)
         * {
         *  if(_shadowCasterList[i] != null)
         *  {
         *      b.Encapsulate(_shadowCasterList[i].bounds);
         *  }
         * }
         * b.extents += Vector3.one * boundsOffset;
         #if UNITY_EDITOR
         * _boundsCollider.center = b.center;
         * _boundsCollider.size = b.size;
         #endif
         * //根据mainCamera来更新lightCamera和projector的位置,和设置参数
         * ShadowUtils.SetLightCamera(b, _lightCamera);*/

        if (_mainCamera == null)
        {
            _mainCamera = Camera.main;
        }
        if (_mainCamera == null)
        {
            return;
        }
        ShadowUtils.SetLightCamera(_mainCamera, _lightCamera);
        _projector.aspectRatio      = _lightCamera.aspect;
        _projector.orthographicSize = _lightCamera.orthographicSize;
        _projector.nearClipPlane    = _lightCamera.nearClipPlane;
        _projector.farClipPlane     = _lightCamera.farClipPlane;
    }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a new <c>MainLightShadowCasterPass</c> instance.
        /// </summary>
        /// <param name="evt">The <c>RenderPassEvent</c> to use.</param>
        /// <seealso cref="RenderPassEvent"/>
        public MainLightShadowCasterPass(RenderPassEvent evt)
        {
            base.profilingSampler = new ProfilingSampler(nameof(MainLightShadowCasterPass));
            renderPassEvent       = evt;

            m_MainLightShadowMatrices = new Matrix4x4[k_MaxCascades + 1];
            m_CascadeSlices           = new ShadowSliceData[k_MaxCascades];
            m_CascadeSplitDistances   = new Vector4[k_MaxCascades];

            MainLightShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_MainLightWorldToShadow");
            MainLightShadowConstantBuffer._ShadowParams  = Shader.PropertyToID("_MainLightShadowParams");
            MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0    = Shader.PropertyToID("_CascadeShadowSplitSpheres0");
            MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1    = Shader.PropertyToID("_CascadeShadowSplitSpheres1");
            MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2    = Shader.PropertyToID("_CascadeShadowSplitSpheres2");
            MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3    = Shader.PropertyToID("_CascadeShadowSplitSpheres3");
            MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii = Shader.PropertyToID("_CascadeShadowSplitSphereRadii");
            MainLightShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_MainLightShadowOffset0");
            MainLightShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_MainLightShadowOffset1");
            MainLightShadowConstantBuffer._ShadowOffset2 = Shader.PropertyToID("_MainLightShadowOffset2");
            MainLightShadowConstantBuffer._ShadowOffset3 = Shader.PropertyToID("_MainLightShadowOffset3");
            MainLightShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_MainLightShadowmapSize");

            m_MainLightShadowmapID       = Shader.PropertyToID("_MainLightShadowmapTexture");
            m_EmptyLightShadowmapTexture = ShadowUtils.AllocShadowRT(1, 1, k_ShadowmapBufferBits, 1, 0, name: "_EmptyLightShadowmapTexture");
        }
Ejemplo n.º 4
0
 public void Set(float v0, float v1, float v2, float v3)
 {
     p0 = ShadowUtils.Asint(v0);
     p1 = ShadowUtils.Asint(v1);
     p2 = ShadowUtils.Asint(v2);
     p3 = ShadowUtils.Asint(v3);
 }
Ejemplo n.º 5
0
        public static void drawShadow(Canvas canvas, Path path, Color color, float elevation, bool transparentOccluder,
                                      float dpr)
        {
            float kAmbientAlpha = 0.039f;
            float kSpotAlpha    = ShadowUtils.kUseFastShadow ? 0.1f : 0.25f;
            float kLightHeight  = 600f;
            float kLightRadius  = 800f;

            Rect  bounds   = path.getBounds();
            float shadow_x = (bounds.left + bounds.right) / 2f;
            float shadow_y = bounds.top - 600.0f;

            _inAmbient    = color.withAlpha((int)(kAmbientAlpha * color.alpha));
            _inSpot       = color.withAlpha((int)(kSpotAlpha * color.alpha));
            _ambientColor = null;
            _spotColor    = null;
            ShadowUtils.computeTonalColors(_inAmbient, _inSpot, ref _ambientColor, ref _spotColor);

            _zPlane.Set(0, 0, dpr * elevation);
            _devLight.Set(shadow_x, shadow_y, dpr * kLightHeight);

            ShadowUtils.drawShadow(
                canvas,
                path,
                _zPlane,
                _devLight,
                dpr * kLightRadius,
                _ambientColor,
                _spotColor,
                0
                );
        }
Ejemplo n.º 6
0
 public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
 {
     m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth,
                                                                         m_ShadowmapHeight, k_ShadowmapBufferBits);
     ConfigureTarget(new RenderTargetIdentifier(m_MainLightShadowmapTexture));
     ConfigureClear(ClearFlag.All, Color.black);
 }
Ejemplo n.º 7
0
        public static void drawShadow(Canvas canvas, Path path, Color color, float elevation, bool transparentOccluder,
                                      float dpr)
        {
            Rect  bounds   = path.getBounds();
            float shadow_x = (bounds.left + bounds.right) / 2f;
            float shadow_y = bounds.top - 600.0f;

            uiColor uicolor = uiColor.fromColor(color);

            uiColor inAmbient    = uicolor.withAlpha((int)(kAmbientAlpha * uicolor.alpha));
            uiColor inSpot       = uicolor.withAlpha((int)(kSpotAlpha * uicolor.alpha));
            uiColor?ambientColor = null;
            uiColor?spotColor    = null;

            ShadowUtils.computeTonalColors(inAmbient, inSpot, ref ambientColor, ref spotColor);
            ShadowUtils.drawShadow(
                canvas,
                path,
                new Vector3(0, 0, dpr * elevation),
                new Vector3(shadow_x, shadow_y, dpr * kLightHeight),
                dpr * kLightRadius,
                ambientColor.Value,
                spotColor.Value,
                0
                );
        }
Ejemplo n.º 8
0
        public bool Setup(ref RenderingData renderingData)
        {
            if (!renderingData.shadowData.supportsMainLightShadows)
            {
                return(false);
            }

            Clear();
            int shadowLightIndex = renderingData.lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return(false);
            }

            VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            if (light.shadows == LightShadows.None)
            {
                return(false);
            }

            if (shadowLight.lightType != LightType.Directional)
            {
                Debug.LogWarning("Only directional lights are supported as main light.");
            }

            Bounds bounds;

            if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount;

            int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
                                                                           renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);

            m_ShadowmapWidth  = renderingData.shadowData.mainLightShadowmapWidth;
            m_ShadowmapHeight = (m_ShadowCasterCascadesCount == 2) ?
                                renderingData.shadowData.mainLightShadowmapHeight >> 1 :
                                renderingData.shadowData.mainLightShadowmapHeight;

            for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
            {
                bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                         shadowLightIndex, cascadeIndex, m_ShadowmapWidth, m_ShadowmapHeight, shadowResolution, light.shadowNearPlane,
                                                                         out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex], out m_CascadeSlices[cascadeIndex].viewMatrix, out m_CascadeSlices[cascadeIndex].projectionMatrix);

                if (!success)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 9
0
 private void Loaded()
 {
     //The control was drawn.
     //This means we can add the drop shadow
     ShadowUtils.CreateDropShadow(this);
     if (Parent != null)
     {
         Parent.Invalidate();
     }
 }
Ejemplo n.º 10
0
 public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
 {
     base.Configure(cmd, cameraTextureDescriptor);
     if (m_CharacterShadowmapTexture == null)
     {
         m_CharacterShadowmapTexture      = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth, m_ShadowmapHeight, k_ShadowmapBufferBits);
         m_CharacterShadowmapTexture.name = "CharacterShadowmapTexture";
     }
     ConfigureTarget(new RenderTargetIdentifier(m_CharacterShadowmapTexture));
     ConfigureClear(ClearFlag.All, Color.black);
 }
Ejemplo n.º 11
0
    // Start is called before the first frame update
    void Start()
    {
        //bits = 0,16,24라는데...24비트로 했을 때만 스텐실 버퍼가 생긴다함

        //rawImage.texture = testRenderTexture;
        //testRenderTexture = ShadowUtils.GetTemporaryShadowTexture(1920, 1080, 24);

        rawImage.texture  = testRenderTexture;
        testRenderTexture = ShadowUtils.GetTemporaryShadowTexture(1920, 1080, 24);
        RenderTexture.ReleaseTemporary(testRenderTexture);
    }
Ejemplo n.º 12
0
 public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
 {
     m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth,
                                                                         m_ShadowmapHeight, k_ShadowmapBufferBits);
     if (test_pcfDefine && (test_pcfDefine.forcePoint || test_pcfDefine.pt == PCFType.UE4Manual2x2PCF || test_pcfDefine.pt == PCFType.UE4Manual3x3PCF_NoGather))
     {
         m_MainLightShadowmapTexture.filterMode = FilterMode.Point;
     }
     ConfigureTarget(new RenderTargetIdentifier(m_MainLightShadowmapTexture));
     ConfigureClear(ClearFlag.All, Color.black);
 }
        void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            NativeArray <VisibleLight> visibleLights = lightData.visibleLights;

            bool          additionalLightHasSoftShadows = false;
            CommandBuffer cmd = CommandBufferPool.Get(k_RenderAdditionalLightShadows);

            using (new ProfilingSample(cmd, k_RenderAdditionalLightShadows))
            {
                int shadowmapWidth  = shadowData.additionalLightsShadowmapWidth;
                int shadowmapHeight = shadowData.additionalLightsShadowmapHeight;

                m_AdditionalLightsShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(shadowmapWidth, shadowmapHeight, k_ShadowmapBufferBits);

                SetRenderTarget(cmd, m_AdditionalLightsShadowmapTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
                                ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                for (int i = 0; i < m_AdditionalShadowCastingLightIndices.Count; ++i)
                {
                    int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                    VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                    if (m_AdditionalShadowCastingLightIndices.Count > 1)
                    {
                        ShadowUtils.ApplySliceTransform(ref m_AdditionalLightSlices[i], shadowmapWidth, shadowmapHeight);
                    }

                    var     settings   = new ShadowDrawingSettings(cullResults, shadowLightIndex);
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex,
                                                                   ref shadowData, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_AdditionalLightSlices[i], ref settings, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].viewMatrix);
                    additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft;
                }

                SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData);
            }

            // We share soft shadow settings for main light and additional lights to save keywords.
            // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows
            // to enable the keyword.
            // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster.
            bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows &&
                                           lightData.mainLightIndex != -1 &&
                                           visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft;

            bool softShadows = shadowData.supportsSoftShadows && (mainLightHasSoftShadows || additionalLightHasSoftShadows);

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
        {
            if (m_AdditionalLightsShadowmapTexture != null)
            {
                Debug.LogWarning($"Texture {m_AdditionalLightsShadowmapTexture.name} wasn't released");
                FrameCleanup(cmd);
            }

            cmd.name += " (Additional lights)";
            m_AdditionalLightsShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth, m_ShadowmapHeight, k_ShadowmapBufferBits);
            ConfigureTarget(new RenderTargetIdentifier(m_AdditionalLightsShadowmapTexture));
            ConfigureClear(ClearFlag.All, Color.black);
        }
Ejemplo n.º 15
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
            // Currently there's an issue which results in mismatched markers.
            CommandBuffer cmd = CommandBufferPool.Get();

            using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MainLightShadow)))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    //settings.splitData = m_CascadeSlices[cascadeIndex].splitData; // NOTE: currently DrawShadows culls more casters if no ShadowSplitData.cullingPlanes are set (version cds 8652678b), so it is currently better to not pass the m_CascadeSlices[cascadeIndex].splitData object returned by CullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives (change introduced in 8bf71cf). Culling is only based on the ShadowSplitData.cullingSphere distances.
                    var splitData = settings.splitData;
                    splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    settings.splitData      = splitData;

                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.CastingPunctualLightShadow, false);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, shadowData.mainLightShadowCascadesCount == 1);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                SetupMainLightShadowReceiverConstants(cmd, shadowLight, shadowData.supportsSoftShadows);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
Ejemplo n.º 16
0
            protected override void AllocateShadows(FrameId frameId, VisibleLight[] lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload)
            {
                ShadowData sd = new ShadowData();

                shadowDatas.Reserve(totalGranted);
                shadowIndices.Reserve(grantedRequests.Count());
                for (uint i = 0, cnt = grantedRequests.Count(); i < cnt; ++i)
                {
                    VisibleLight        vl  = lights[grantedRequests[i].index];
                    Light               l   = vl.light;
                    AdditionalLightData ald = l.GetComponent <AdditionalLightData>();

                    // set light specific values that are not related to the shadowmap
                    GPUShadowType shadowtype;
                    ShadowUtils.MapLightType(ald.archetype, vl.lightType, out sd.lightType, out shadowtype);
                    sd.bias    = l.shadowBias;
                    sd.quality = 0;

                    shadowIndices.AddUnchecked((int)shadowDatas.Count());

                    int smidx = 0;
                    while (smidx < k_MaxShadowmapPerType)
                    {
                        if (m_ShadowmapsPerType[(int)shadowtype, smidx].Reserve(frameId, ref sd, grantedRequests[i], (uint)ald.shadowResolution, (uint)ald.shadowResolution, ref shadowDatas, ref shadowmapPayload, lights))
                        {
                            break;
                        }
                        smidx++;
                    }
                    if (smidx == k_MaxShadowmapPerType)
                    {
                        throw new ArgumentException("The requested shadows do not fit into any shadowmap.");
                    }
                }

                // final step for shadowmaps that only gather data during the previous loop and do the actual allocation once they have all the data.
                foreach (var sm in m_Shadowmaps)
                {
                    if (!sm.ReserveFinalize(frameId, ref shadowDatas, ref shadowmapPayload))
                    {
                        throw new ArgumentException("Shadow allocation failed in the ReserveFinalize step.");
                    }
                }
            }
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);

            using (new ProfilingSample(cmd, m_ProfilerTag))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    var splitData = settings.splitData;
                    splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    settings.splitData      = splitData;
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);

                //* pwrd majiao: frag阶段计算shadowCoord //
                CoreUtils.SetKeyword(cmd, "_TRADITIONAL_SHADOW", shadowData.useTraditionalShadow);
                //* pwrd majiao //

                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                SetupMainLightShadowReceiverConstants(cmd, shadowLight, softShadows);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
Ejemplo n.º 18
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
            // Currently there's an issue which results in mismatched markers.
            CommandBuffer cmd = CommandBufferPool.Get();

            using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MainLightShadow)))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);
                settings.useRenderingLayerMaskTest = UniversalRenderPipeline.asset.supportsLightLayers;

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    settings.splitData = m_CascadeSlices[cascadeIndex].splitData;

                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.CastingPunctualLightShadow, false);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, shadowData.mainLightShadowCascadesCount == 1);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                SetupMainLightShadowReceiverConstants(cmd, shadowLight, shadowData.supportsSoftShadows);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
Ejemplo n.º 19
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderMainLightShadowmapTag);

            using (new ProfilingSample(cmd, k_RenderMainLightShadowmapTag))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);

                m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth,
                                                                                    m_ShadowmapHeight, k_ShadowmapBufferBits);
                SetRenderTarget(cmd, m_MainLightShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    var splitData = settings.splitData;
                    splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    settings.splitData      = splitData;
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                SetupMainLightShadowReceiverConstants(cmd, ref shadowData, shadowLight);
            }

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
Ejemplo n.º 20
0
            protected override void PrioritizeShadowCasters(Camera camera, VisibleLight[] lights, uint shadowRequestsCount, int[] shadowRequests)
            {
                // this function simply looks at the projected area on the screen, ignoring all light types and shapes
                m_TmpSortKeys.Reset(shadowRequestsCount);

                for (int i = 0; i < shadowRequestsCount; ++i)
                {
                    int          vlidx = shadowRequests[i];
                    VisibleLight vl    = lights[vlidx];
                    Light        l     = vl.light;

                    // use the screen rect as a measure of importance
                    float area = vl.screenRect.width * vl.screenRect.height;
                    long  val  = ShadowUtils.Asint(area);
                    val <<= 32;
                    val  |= (long)(uint)vlidx;
                    m_TmpSortKeys.AddUnchecked(val);
                }
                m_TmpSortKeys.Sort();
                m_TmpSortKeys.ExtractTo(shadowRequests, 0, out shadowRequestsCount, delegate(long key) { return((int)(key & 0xffffffff)); });
            }
Ejemplo n.º 21
0
    void LateUpdate()
    {
        //calculate bounding box of the shadow caster
        Bounds b = new Bounds();

        for (int i = 0; i < _shadowCasterList.Count; i++)
        {
            if (_shadowCasterList[i] != null)
            {
                b.Encapsulate(_shadowCasterList[i].bounds);
            }
        }
        b.extents += Vector3.one * boundsOffset;
#if UNITY_EDITOR
        _boundsCollider.center = b.center;
        _boundsCollider.size   = b.size;
#endif
        //according to the mainCamera,updating position of lightCamera and projector
        ShadowUtils.SetLightCamera(b, _lightCamera);
        _projector.aspectRatio      = _lightCamera.aspect;
        _projector.orthographicSize = _lightCamera.orthographicSize;
        _projector.nearClipPlane    = _lightCamera.nearClipPlane;
        _projector.farClipPlane     = _lightCamera.farClipPlane;
    }
Ejemplo n.º 22
0
        void SetupMainLightShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight, bool supportsSoftShadows)
        {
            Light light       = shadowLight.light;
            bool  softShadows = shadowLight.light.shadows == LightShadows.Soft && supportsSoftShadows;

            int cascadeCount = m_ShadowCasterCascadesCount;

            for (int i = 0; i < cascadeCount; ++i)
            {
                m_MainLightShadowMatrices[i] = m_CascadeSlices[i].shadowTransform;
            }

            // We setup and additional a no-op WorldToShadow matrix in the last index
            // because the ComputeCascadeIndex function in Shadows.hlsl can return an index
            // out of bounds. (position not inside any cascade) and we want to avoid branching
            Matrix4x4 noOpShadowMatrix = Matrix4x4.zero;

            noOpShadowMatrix.m22 = (SystemInfo.usesReversedZBuffer) ? 1.0f : 0.0f;
            for (int i = cascadeCount; i <= k_MaxCascades; ++i)
            {
                m_MainLightShadowMatrices[i] = noOpShadowMatrix;
            }

            float invShadowAtlasWidth      = 1.0f / renderTargetWidth;
            float invShadowAtlasHeight     = 1.0f / renderTargetHeight;
            float invHalfShadowAtlasWidth  = 0.5f * invShadowAtlasWidth;
            float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
            float softShadowsProp          = softShadows ? 1.0f : 0.0f;

            ShadowUtils.GetScaleAndBiasForLinearDistanceFade(m_MaxShadowDistanceSq, m_CascadeBorder, out float shadowFadeScale, out float shadowFadeBias);

            cmd.SetGlobalTexture(m_MainLightShadowmap.id, m_MainLightShadowmapTexture);
            cmd.SetGlobalMatrixArray(MainLightShadowConstantBuffer._WorldToShadow, m_MainLightShadowMatrices);
            cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams,
                                new Vector4(light.shadowStrength, softShadowsProp, shadowFadeScale, shadowFadeBias));

            if (m_ShadowCasterCascadesCount > 1)
            {
                cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0,
                                    m_CascadeSplitDistances[0]);
                cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1,
                                    m_CascadeSplitDistances[1]);
                cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2,
                                    m_CascadeSplitDistances[2]);
                cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3,
                                    m_CascadeSplitDistances[3]);
                cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii, new Vector4(
                                        m_CascadeSplitDistances[0].w * m_CascadeSplitDistances[0].w,
                                        m_CascadeSplitDistances[1].w * m_CascadeSplitDistances[1].w,
                                        m_CascadeSplitDistances[2].w * m_CascadeSplitDistances[2].w,
                                        m_CascadeSplitDistances[3].w * m_CascadeSplitDistances[3].w));
            }

            // Inside shader soft shadows are controlled through global keyword.
            // If any additional light has soft shadows it will force soft shadows on main light too.
            // As it is not trivial finding out which additional light has soft shadows, we will pass main light properties if soft shadows are supported.
            // This workaround will be removed once we will support soft shadows per light.
            if (supportsSoftShadows)
            {
                if (m_SupportsBoxFilterForShadows)
                {
                    cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset0,
                                        new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
                    cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset1,
                                        new Vector4(invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
                    cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset2,
                                        new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
                    cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset3,
                                        new Vector4(invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
                }

                // Currently only used when !SHADER_API_MOBILE but risky to not set them as it's generic
                // enough so custom shaders might use it.
                cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth,
                                                                                              invShadowAtlasHeight,
                                                                                              renderTargetWidth, renderTargetHeight));
            }
        }
        public bool Setup(ref RenderingData renderingData)
        {
            Clear();

            m_ShadowmapWidth  = renderingData.shadowData.additionalLightsShadowmapWidth;
            m_ShadowmapHeight = renderingData.shadowData.additionalLightsShadowmapHeight;

            var visibleLights         = renderingData.lightData.visibleLights;
            int additionalLightsCount = renderingData.lightData.additionalLightsCount;

            if (m_AdditionalLightSlices == null || m_AdditionalLightSlices.Length < additionalLightsCount)
            {
                m_AdditionalLightSlices = new ShadowSliceData[additionalLightsCount];
            }

            if (m_AdditionalLightsShadowData == null || m_AdditionalLightsShadowData.Length < additionalLightsCount)
            {
                m_AdditionalLightsShadowData = new ShaderInput.ShadowData[additionalLightsCount];
            }

            // By default visible lights do not have shadow light indices.
            for (int i = 0; i < visibleLights.Length; ++i)
            {
                m_ShadowCastingLightIndicesMap.Add(-1);
            }

            int  validShadowCastingLights = 0;
            bool supportsSoftShadows      = renderingData.shadowData.supportsSoftShadows;

            for (int i = 0; i < visibleLights.Length && m_AdditionalShadowCastingLightIndices.Count < additionalLightsCount; ++i)
            {
                VisibleLight shadowLight = visibleLights[i];

                // Skip main directional light as it is not packed into the shadow atlas
                if (i == renderingData.lightData.mainLightIndex)
                {
                    continue;
                }

                int  shadowCastingLightIndex = m_AdditionalShadowCastingLightIndices.Count;
                bool isValidShadowSlice      = false;
                if (renderingData.cullResults.GetShadowCasterBounds(i, out var bounds))
                {
                    // We need to iterate the lights even though additional lights are disabled because
                    // cullResults.GetShadowCasterBounds() does the fence sync for the shadow culling jobs.
                    if (!renderingData.shadowData.supportsAdditionalLightShadows)
                    {
                        continue;
                    }

                    if (IsValidShadowCastingLight(ref renderingData.lightData, i))
                    {
                        bool success = ShadowUtils.ExtractSpotLightMatrix(ref renderingData.cullResults,
                                                                          ref renderingData.shadowData,
                                                                          i,
                                                                          out var shadowTransform,
                                                                          out m_AdditionalLightSlices[shadowCastingLightIndex].viewMatrix,
                                                                          out m_AdditionalLightSlices[shadowCastingLightIndex].projectionMatrix);

                        if (success)
                        {
                            m_AdditionalShadowCastingLightIndices.Add(i);
                            var     light          = shadowLight.light;
                            float   shadowStrength = light.shadowStrength;
                            float   softShadows    = (supportsSoftShadows && light.shadows == LightShadows.Soft) ? 1.0f : 0.0f;
                            Vector4 shadowParams   = new Vector4(shadowStrength, softShadows, 0.0f, 0.0f);
                            if (m_UseStructuredBuffer)
                            {
                                m_AdditionalLightsShadowData[shadowCastingLightIndex].worldToShadowMatrix = shadowTransform;
                                m_AdditionalLightsShadowData[shadowCastingLightIndex].shadowParams        = shadowParams;
                            }
                            else
                            {
                                m_AdditionalLightsWorldToShadow[shadowCastingLightIndex] = shadowTransform;
                                m_AdditionalLightsShadowParams[shadowCastingLightIndex]  = shadowParams;
                            }
                            isValidShadowSlice = true;
                            validShadowCastingLights++;
                        }
                    }
                }

                if (m_UseStructuredBuffer)
                {
                    // When using StructuredBuffers all the valid shadow casting slices data
                    // are stored in a the ShadowData buffer and then we setup a index map to
                    // map from light indices to shadow buffer index. A index map of -1 means
                    // the light is not a valid shadow casting light and there's no data for it
                    // in the shadow buffer.
                    int indexMap = (isValidShadowSlice) ? shadowCastingLightIndex : -1;
                    m_AdditionalShadowCastingLightIndicesMap.Add(indexMap);
                }
                else if (!isValidShadowSlice)
                {
                    // When NOT using structured buffers we have no performant way to sample the
                    // index map as int[]. Unity shader compiler converts int[] to float4[] to force memory alignment.
                    // This makes indexing int[] arrays very slow. So, in order to avoid indexing shadow lights we
                    // setup slice data and reserve shadow map space even for invalid shadow slices.
                    // The data is setup with zero shadow strength. This has the same visual effect of no shadow
                    // attenuation contribution from this light.
                    // This makes sampling shadow faster but introduces waste in shadow map atlas.
                    // The waste increases with the amount of additional lights to shade.
                    // Therefore Universal RP try to keep the limit at sane levels when using uniform buffers.
                    Matrix4x4 identity = Matrix4x4.identity;
                    m_AdditionalShadowCastingLightIndices.Add(i);
                    m_AdditionalLightsWorldToShadow[shadowCastingLightIndex]          = identity;
                    m_AdditionalLightsShadowParams[shadowCastingLightIndex]           = Vector4.zero;
                    m_AdditionalLightSlices[shadowCastingLightIndex].viewMatrix       = identity;
                    m_AdditionalLightSlices[shadowCastingLightIndex].projectionMatrix = identity;
                }

                m_ShadowCastingLightIndicesMap[i] = isValidShadowSlice ? shadowCastingLightIndex : -1;
            }

            // Lights that need to be rendered in the shadow map atlas
            if (validShadowCastingLights == 0)
            {
                return(false);
            }

            int atlasWidth      = renderingData.shadowData.additionalLightsShadowmapWidth;
            int atlasHeight     = renderingData.shadowData.additionalLightsShadowmapHeight;
            int sliceResolution = ShadowUtils.GetMaxTileResolutionInAtlas(atlasWidth, atlasHeight, validShadowCastingLights);

            // In the UI we only allow for square shadow map atlas. Here we check if we can fit
            // all shadow slices into half resolution of the atlas and adjust height to have tighter packing.
            int maximumSlices = (m_ShadowmapWidth / sliceResolution) * (m_ShadowmapHeight / sliceResolution);

            if (validShadowCastingLights <= (maximumSlices / 2))
            {
                m_ShadowmapHeight /= 2;
            }

            int   shadowSlicesPerRow = (atlasWidth / sliceResolution);
            float oneOverAtlasWidth  = 1.0f / m_ShadowmapWidth;
            float oneOverAtlasHeight = 1.0f / m_ShadowmapHeight;

            int       sliceIndex = 0;
            int       shadowCastingLightsBufferCount = m_AdditionalShadowCastingLightIndices.Count;
            Matrix4x4 sliceTransform = Matrix4x4.identity;

            sliceTransform.m00 = sliceResolution * oneOverAtlasWidth;
            sliceTransform.m11 = sliceResolution * oneOverAtlasHeight;

            for (int i = 0; i < shadowCastingLightsBufferCount; ++i)
            {
                // we can skip the slice if strength is zero. Some slices with zero
                // strength exists when using uniform array path.
                if (!m_UseStructuredBuffer && Mathf.Approximately(m_AdditionalLightsShadowParams[i].x, 0.0f))
                {
                    continue;
                }

                m_AdditionalLightSlices[i].offsetX    = (sliceIndex % shadowSlicesPerRow) * sliceResolution;
                m_AdditionalLightSlices[i].offsetY    = (sliceIndex / shadowSlicesPerRow) * sliceResolution;
                m_AdditionalLightSlices[i].resolution = sliceResolution;

                sliceTransform.m03 = m_AdditionalLightSlices[i].offsetX * oneOverAtlasWidth;
                sliceTransform.m13 = m_AdditionalLightSlices[i].offsetY * oneOverAtlasHeight;

                // We bake scale and bias to each shadow map in the atlas in the matrix.
                // saves some instructions in shader.
                if (m_UseStructuredBuffer)
                {
                    m_AdditionalLightsShadowData[i].worldToShadowMatrix = sliceTransform * m_AdditionalLightsShadowData[i].worldToShadowMatrix;
                }
                else
                {
                    m_AdditionalLightsWorldToShadow[i] = sliceTransform * m_AdditionalLightsWorldToShadow[i];
                }
                sliceIndex++;
            }

            return(true);
        }
        void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            NativeArray <VisibleLight> visibleLights = lightData.visibleLights;

            bool additionalLightHasSoftShadows = false;
            // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
            // Currently there's an issue which results in mismatched markers.
            CommandBuffer cmd = CommandBufferPool.Get();

            using (new ProfilingScope(cmd, m_ProfilingSampler))
            {
                bool anyShadowSliceRenderer = false;
                int  shadowSlicesCount      = m_AdditionalShadowCastingLightIndices.Count;
                for (int i = 0; i < shadowSlicesCount; ++i)
                {
                    // we do the shadow strength check here again here because when using
                    // the uniform array path we might have zero strength shadow lights.
                    // In that case we need the shadow data buffer but we can skip
                    // rendering them to shadowmap.
                    if (!m_UseStructuredBuffer && Mathf.Approximately(m_AdditionalLightsShadowParams[i].x, 0.0f))
                    {
                        continue;
                    }

                    // Index of the VisibleLight
                    int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                    VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                    ShadowSliceData shadowSliceData = m_AdditionalLightSlices[i];

                    var     settings   = new ShadowDrawingSettings(cullResults, shadowLightIndex);
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex,
                                                                   ref shadowData, shadowSliceData.projectionMatrix, shadowSliceData.resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref shadowSliceData, ref settings);
                    additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft;
                    anyShadowSliceRenderer         = true;
                }

                // We share soft shadow settings for main light and additional lights to save keywords.
                // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows
                // to enable the keyword.
                // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster.
                bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows &&
                                               lightData.mainLightIndex != -1 &&
                                               visibleLights[lightData.mainLightIndex].light.shadows ==
                                               LightShadows.Soft;

                bool softShadows = shadowData.supportsSoftShadows &&
                                   (mainLightHasSoftShadows || additionalLightHasSoftShadows);

                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, anyShadowSliceRenderer);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                if (anyShadowSliceRenderer)
                {
                    SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData, softShadows);
                }
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        public bool Setup(RenderTargetHandle destination, ref RenderingData renderingData, int maxVisibleAdditinalLights)
        {
            Clear();
            this.destination = destination;

            if (m_AdditionalLightShadowMatrices.Length != maxVisibleAdditinalLights)
            {
                m_AdditionalLightShadowMatrices  = new Matrix4x4[maxVisibleAdditinalLights];
                m_AdditionalLightSlices          = new ShadowSliceData[maxVisibleAdditinalLights];
                m_AdditionalLightsShadowStrength = new float[maxVisibleAdditinalLights];
            }
            m_AdditionalShadowCastingLightIndices.Clear();

            Bounds bounds;
            var    visibleLights         = renderingData.lightData.visibleLights;
            int    additionalLightsCount = renderingData.lightData.additionalLightsCount;

            for (int i = 0; i < visibleLights.Length && m_AdditionalShadowCastingLightIndices.Count < additionalLightsCount; ++i)
            {
                if (i == renderingData.lightData.mainLightIndex)
                {
                    continue;
                }

                VisibleLight shadowLight = visibleLights[i];
                Light        light       = shadowLight.light;

                if (shadowLight.lightType == LightType.Spot && light != null && light.shadows != LightShadows.None)
                {
                    if (renderingData.cullResults.GetShadowCasterBounds(i, out bounds))
                    {
                        m_AdditionalShadowCastingLightIndices.Add(i);
                    }
                }
            }

            int shadowCastingLightsCount = m_AdditionalShadowCastingLightIndices.Count;

            if (shadowCastingLightsCount == 0)
            {
                return(false);
            }

            // TODO: Add support to point light shadows. We make a simplification here that only works
            // for spot lights and with max spot shadows per pass.
            int atlasWidth      = renderingData.shadowData.additionalLightsShadowmapWidth;
            int atlasHeight     = renderingData.shadowData.additionalLightsShadowmapHeight;
            int sliceResolution = ShadowUtils.GetMaxTileResolutionInAtlas(atlasWidth, atlasHeight, shadowCastingLightsCount);

            bool anyShadows         = false;
            int  shadowSlicesPerRow = (atlasWidth / sliceResolution);

            for (int i = 0; i < shadowCastingLightsCount; ++i)
            {
                int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                // Currently Only Spot Lights are supported in additional lights
                Debug.Assert(shadowLight.lightType == LightType.Spot);
                Matrix4x4 shadowTransform;
                bool      success = ShadowUtils.ExtractSpotLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                       shadowLightIndex, out shadowTransform, out m_AdditionalLightSlices[i].viewMatrix, out m_AdditionalLightSlices[i].projectionMatrix);

                if (success)
                {
                    // TODO: We need to pass bias and scale list to shader to be able to support multiple
                    // shadow casting additional lights.
                    m_AdditionalLightSlices[i].offsetX         = (i % shadowSlicesPerRow) * sliceResolution;
                    m_AdditionalLightSlices[i].offsetY         = (i / shadowSlicesPerRow) * sliceResolution;
                    m_AdditionalLightSlices[i].resolution      = sliceResolution;
                    m_AdditionalLightSlices[i].shadowTransform = shadowTransform;

                    m_AdditionalLightsShadowStrength[i] = shadowLight.light.shadowStrength;
                    anyShadows = true;
                }
                else
                {
                    m_AdditionalShadowCastingLightIndices.RemoveAt(i--);
                }
            }

            return(anyShadows);
        }
Ejemplo n.º 26
0
 void LateUpdate()
 {
     ShadowUtils.SetLightCamera(_mainCamera, _lightCamera);
 }
Ejemplo n.º 27
0
        public bool Setup(ref RenderingData renderingData)
        {
            using var profScope = new ProfilingScope(null, m_ProfilingSetupSampler);

            if (!renderingData.shadowData.supportsMainLightShadows)
            {
                return(false);
            }

            Clear();
            int shadowLightIndex = renderingData.lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return(false);
            }

            VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            if (light.shadows == LightShadows.None)
            {
                return(false);
            }

            if (shadowLight.lightType != LightType.Directional)
            {
                Debug.LogWarning("Only directional lights are supported as main light.");
            }

            Bounds bounds;

            if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount;

            int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
                                                                           renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);

            renderTargetWidth  = renderingData.shadowData.mainLightShadowmapWidth;
            renderTargetHeight = (m_ShadowCasterCascadesCount == 2) ?
                                 renderingData.shadowData.mainLightShadowmapHeight >> 1 :
                                 renderingData.shadowData.mainLightShadowmapHeight;

            for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
            {
                bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                         shadowLightIndex, cascadeIndex, renderTargetWidth, renderTargetHeight, shadowResolution, light.shadowNearPlane,
                                                                         out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex]);

                if (!success)
                {
                    return(false);
                }
            }

            m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits);
            m_MaxShadowDistanceSq       = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance;
            m_CascadeBorder             = renderingData.shadowData.mainLightShadowCascadeBorder;

            return(true);
        }
Ejemplo n.º 28
0
            override public bool Reserve(FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray <ShadowData> entries, ref VectorArray <ShadowPayload> payload, VisibleLight[] lights)
            {
                ShadowData sd    = shadowData;
                ShadowData dummy = new ShadowData();

                if (sr.shadowType != GPUShadowType.Point && sr.shadowType != GPUShadowType.Spot && sr.shadowType != GPUShadowType.Directional)
                {
                    return(false);
                }

                if (sr.shadowType == GPUShadowType.Directional)
                {
                    for (uint i = 0; i < k_MaxCascadesInShader; ++i)
                    {
                        m_TmpSplits[i].Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
                    }
                }

                Key key;

                key.id            = sr.instanceId;
                key.faceIdx       = 0;
                key.visibleIdx    = (int)sr.index;
                key.shadowDataIdx = entries.Count();

                uint originalEntryCount    = entries.Count();
                uint originalPayloadCount  = payload.Count();
                uint originalActiveEntries = m_ActiveEntriesCount;

                uint facecnt  = sr.facecount;
                uint facemask = sr.facemask;
                uint bit      = 1;
                int  resIdx   = 0;

                entries.Reserve(6);

                float nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;

                while (facecnt > 0)
                {
                    if ((bit & facemask) != 0)
                    {
                        uint width  = widths[resIdx];
                        uint height = heights[resIdx];
                        uint ceIdx;
                        if (!Alloc(frameId, key, width, height, out ceIdx, payload))
                        {
                            entries.Purge(entries.Count() - originalEntryCount);
                            payload.Purge(payload.Count() - originalPayloadCount);
                            uint added = m_ActiveEntriesCount - originalActiveEntries;
                            for (uint i = originalActiveEntries; i < m_ActiveEntriesCount; ++i)
                            {
                                m_EntryCache.Swap(i, m_EntryCache.Count() - i - 1);
                            }
                            m_EntryCache.Purge(added, Free);
                            m_ActiveEntriesCount = originalActiveEntries;
                            return(false);
                        }

                        // read
                        CachedEntry ce = m_EntryCache[ceIdx];
                        // modify
                        Matrix4x4 vp;
                        if (sr.shadowType == GPUShadowType.Point)
                        {
                            vp = ShadowUtils.ExtractPointLightMatrix(lights[sr.index], key.faceIdx, 2.0f, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int)sr.index);
                        }
                        else if (sr.shadowType == GPUShadowType.Spot)
                        {
                            vp = ShadowUtils.ExtractSpotLightMatrix(lights[sr.index], out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData);
                        }
                        else if (sr.shadowType == GPUShadowType.Directional)
                        {
                            vp = ShadowUtils.ExtractDirectionalLightMatrix(lights[sr.index], key.faceIdx, m_CascadeCount, m_CascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int)sr.index);
                            m_TmpSplits[key.faceIdx]    = ce.current.splitData.cullingSphere;
                            m_TmpSplits[key.faceIdx].w *= ce.current.splitData.cullingSphere.w;
                        }
                        else
                        {
                            vp = Matrix4x4.identity; // should never happen, though
                        }
                        // write :(
                        m_EntryCache[ceIdx] = ce;

                        sd.worldToShadow = vp.transpose; // apparently we need to transpose matrices that are sent to HLSL
                        sd.scaleOffset   = new Vector4(ce.current.viewport.width * m_WidthRcp, ce.current.viewport.height * m_HeightRcp, ce.current.viewport.x, ce.current.viewport.y);
                        sd.texelSizeRcp  = new Vector2(m_WidthRcp, m_HeightRcp);
                        sd.PackShadowmapId(m_TexSlot, m_SampSlot, ce.current.slice);
                        sd.shadowType    = sr.shadowType;
                        sd.payloadOffset = payload.Count();
                        entries.AddUnchecked(sd);

                        resIdx++;
                        facecnt--;
                        key.shadowDataIdx++;
                    }
                    else
                    {
                        // we push a dummy face in, otherwise we'd need a mapping from face index to shadowData in the shader as well
                        entries.AddUnchecked(dummy);
                    }
                    key.faceIdx++;
                    bit <<= 1;
                }

                if (sr.shadowType == GPUShadowType.Directional)
                {
                    ShadowPayload sp = new ShadowPayload();
                    payload.Reserve(k_MaxCascadesInShader);
                    for (uint i = 0; i < k_MaxCascadesInShader; i++)
                    {
                        sp.Set(m_TmpSplits[i]);
                        payload.AddUnchecked(sp);
                    }
                }

                return(true);
            }