Esempio n. 1
0
    void RenderSpotShadows(int index, int split, int tileSize)
    {
        ShadowedOtherLight light = shadowedOtherLights[index];
        var shadowSettings       =
            new ShadowDrawingSettings(cullingResults, light.visibleLightIndex)
        {
            useRenderingLayerMaskTest = true
        };

        cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(
            light.visibleLightIndex, out Matrix4x4 viewMatrix,
            out Matrix4x4 projectionMatrix, out ShadowSplitData splitData
            );
        shadowSettings.splitData = splitData;

        float   texelSize  = 2f / (tileSize * projectionMatrix.m00);
        float   filterSize = texelSize * ((float)settings.other.filter + 1f);
        float   bias       = light.normalBias * filterSize * 1.4142136f;
        Vector2 offset     = SetTileViewport(index, split, tileSize);
        float   tileScale  = 1f / split;

        SetOtherTileData(index, offset, tileScale, bias);
        otherShadowMatrices[index] = ConvertToAtlasMatrix(
            projectionMatrix * viewMatrix,
            offset, tileScale
            );
        buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
        buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
        ExecuteBuffer();
        context.DrawShadows(ref shadowSettings);
        buffer.SetGlobalDepthBias(0f, 0f);
    }
Esempio n. 2
0
    void RenderShadows(ScriptableRenderContext context)
    {
        shadowBuffer.GetTemporaryRT(shadowMapId, 512, 512, 16, FilterMode.Bilinear, RenderTextureFormat.Depth);
        shadowMap            = RenderTexture.GetTemporary(512, 512, 16, RenderTextureFormat.Shadowmap);
        shadowMap.filterMode = FilterMode.Bilinear;
        shadowMap.wrapMode   = TextureWrapMode.Clamp;

        CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth);
        shadowBuffer.BeginSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        Matrix4x4       viewMatrix, projectMatrix;
        ShadowSplitData splitData;

        cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out projectMatrix, out splitData);
        shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectMatrix);
        context.ExecuteCommandBuffer(shadowBuffer);

        // draw shadow
        var shadowSettings = new ShadowDrawingSettings(cullingResults, 0);

        context.DrawShadows(ref shadowSettings);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
Esempio n. 3
0
        public static bool ExtractSpotLightMatrix(ref CullingResults cullResults, ref ShadowData shadowData, int shadowLightIndex, out Matrix4x4 shadowMatrix, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData splitData)
        {
            bool success = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out viewMatrix, out projMatrix, out splitData); // returns false if input parameters are incorrect (rare)

            shadowMatrix = GetShadowTransform(projMatrix, viewMatrix);
            return(success);
        }
Esempio n. 4
0
    void SetupSpotShadow(ref ScriptableRenderContext context, ref CullingResults cullingResults, int shadowMapSize, int index, ref VisibleLight visibleLight)
    {
        Bounds shadowBounds;

        if (visibleLight.light.shadows != LightShadows.None && cullingResults.GetShadowCasterBounds(index, out shadowBounds))
        {
            ShadowLight shadowLight = new ShadowLight();
            shadowLight.cascades       = new ShadowCascade[1];
            shadowLight.cullingSpheres = null;
            shadowLight.tileSize       = shadowMapSize;

            Matrix4x4       viewMatrix;
            Matrix4x4       projectionMatrix;
            ShadowSplitData splitData;

            if (cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(index, out viewMatrix, out projectionMatrix, out splitData))
            {
                ShadowCascade shadowCascade = new ShadowCascade();
                shadowCascade.viewMatrix          = viewMatrix;
                shadowCascade.projectionMatrix    = projectionMatrix;
                shadowCascade.worldToShadowMatrix = CreateWorldToShadowMatrix(viewMatrix, projectionMatrix);
                shadowCascade.tileOffset          = Vector2Int.zero;
                shadowCascade.splitData           = splitData;
                shadowLight.cascades[0]           = shadowCascade;
            }

            shadowData.lights[index] = shadowLight;
        }
    }
        public static bool ExtractSpotLightMatrix(ref CullingResults cullResults, ref ShadowData shadowData, int shadowLightIndex, out Matrix4x4 shadowMatrix, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix)
        {
            ShadowSplitData splitData;
            bool            success = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out viewMatrix, out projMatrix, out splitData);

            shadowMatrix = GetShadowTransform(projMatrix, viewMatrix);
            return(success);
        }
Esempio n. 6
0
	private void RenderSpotLightShadow(CullingResults cull, int shadowLightCount, Light[] shadowLights, int[] shadowLightIndices) {
		_currentBuffer.GetTemporaryRTArray(ShaderManager.SPOT_LIGHT_SHADOWMAP_ARRAY, @params.spotLightParams.shadowResolution, @params.spotLightParams.shadowResolution, shadowLightCount, 16, FilterMode.Bilinear, RenderTextureFormat.Shadowmap);
		var shadowLightInverseVPArray = new Matrix4x4[shadowLightCount];
		var scaleOffset = Matrix4x4.identity;
		scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f;
		
		for (var i = 0; i < shadowLightCount; i++) {
			var light = shadowLights[i];
			
			_currentBuffer.SetGlobalFloat(ShaderManager.SHADOW_BIAS, light.shadowBias);
			_currentBuffer.SetGlobalFloat(ShaderManager.SHADOW_NORMAL_BIAS, light.shadowNormalBias);
			
			var shadowSettings = new ShadowDrawingSettings(cull, shadowLightIndices[i]);
			ResetRenderTarget(SpotLightShadowmapArrayId, CubemapFace.Unknown, i, true, false, 1, Color.black);

			if (!cull.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndices[i], out var viewMatrix, out var projectionMatrix, out var splitData)) {
				ExecuteCurrentBuffer();
				continue;
			}

			shadowSettings.splitData = splitData;
				
			_currentBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);

			if (_reversedZBuffer) {
				projectionMatrix.m20 = -projectionMatrix.m20;
				projectionMatrix.m21 = -projectionMatrix.m21;
				projectionMatrix.m22 = -projectionMatrix.m22;
				projectionMatrix.m23 = -projectionMatrix.m23;
			}
			
			shadowLightInverseVPArray[i] = scaleOffset * (projectionMatrix * viewMatrix);
			
			ExecuteCurrentBuffer();
			
			_context.DrawShadows(ref shadowSettings);
		}
		
		Extensions.Resize(ref _spotLightInverseVPBuffer, shadowLightCount);
		_spotLightInverseVPBuffer.SetData(shadowLightInverseVPArray);
		
		var inverseShadowmapSize = 1f / @params.spotLightParams.shadowResolution;
		
		_currentBuffer.SetGlobalBuffer(ShaderManager.SPOT_LIGHT_INVERSE_VP_BUFFER, _spotLightInverseVPBuffer);
		_currentBuffer.SetGlobalVector(ShaderManager.SPOT_LIGHT_SHADOWMAP_SIZE, new Vector4(inverseShadowmapSize, inverseShadowmapSize, @params.spotLightParams.shadowResolution, @params.spotLightParams.shadowResolution));
		
		if (@params.spotLightParams.softShadow) _currentBuffer.EnableShaderKeyword(ShaderManager.SPOT_LIGHT_SOFT_SHADOWS);
		else _currentBuffer.DisableShaderKeyword(ShaderManager.SPOT_LIGHT_SOFT_SHADOWS);
		
		ExecuteCurrentBuffer();
	}
Esempio n. 7
0
    void RenderShadows(ScriptableRenderContext context)
    {
        Debug.Log("Shadow Render");
        int   split;
        float tileSize, tileScale;

        SetupSplitAndTileInfo(shadowMapTileCount, out split, out tileSize, out tileScale);
        shadowBuffer.SetGlobalVector(
            globalShadowDataId, new Vector4(tileScale, shadowDistance * shadowDistance)
            );


        Rect titleViewPort = new Rect(0f, 0f, tileSize, tileSize);

        shadowMap = SetupRednerTargetForShadow();
        shadowBuffer.BeginSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
        int  tileIndex  = 0;
        bool hardShadow = false;
        bool softShadow = false;


        for (int n = mainLightExists ? 1:0; n < cullingResults.visibleLights.Length; n++)
        //for (int n = 0; n < cullingResults.visibleLights.Length; n++)
        {
            if (n == maxVisibleLights)
            {
                break;
            }

            if (shadowData[n].x <= 0f)
            {
                continue;
            }
            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;
            bool            vaildShadows;

            if (shadowData[n].z > 0f)
            {
                vaildShadows = cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(n, 0, 1, Vector3.right, (int)tileSize,
                                                                                                   cullingResults.visibleLights[n].light.shadowNearPlane, out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                vaildShadows = cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(n, out viewMatrix, out projectionMatrix, out splitData);
            }
            if (!vaildShadows)
            {
                shadowData[n].x = 0;
                continue;
            }


            Vector2 tileOffset = ConfigShadowTile(n, split, tileSize);
            shadowData[n].z = tileOffset.x * tileScale;
            shadowData[n].y = tileOffset.y * tileScale;
            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            shadowBuffer.SetGlobalFloat(shadowBiasId, cullingResults.visibleLights[n].light.shadowBias);
            shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);


            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();
            var shadowSetting = new ShadowDrawingSettings(cullingResults, n);
            context.DrawShadows(ref shadowSetting);
            worldToShadowMatrices[n] = SetupWorldToShadowMatrix(ref projectionMatrix, ref viewMatrix);

            tileIndex += 1;

            if (shadowData[n].y <= 0f)
            {
                hardShadow = true;
            }
            else
            {
                softShadow = true;
            }
        }

        shadowBuffer.DisableScissorRect();

        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize,
                                                                  shadowMapSize, shadowMapSize));
        CoreUtils.SetKeyword(shadowBuffer, shadowHardKeyWord, hardShadow);
        CoreUtils.SetKeyword(shadowBuffer, shadowSoftKeyWord, softShadow);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);

        shadowBuffer.Clear();
    }
Esempio n. 8
0
    /// <summary>
    /// 渲染阴影
    /// </summary>
    /// <param name="_context"></param>
    private void renderShadows()
    {
        int split;

        if (m_shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (m_shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (m_shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        Matrix4x4       viewMatrix, projectionMatrix;
        ShadowSplitData splitData;

        float tileSize  = m_rpp.shadowMapSize / split;
        float tileScale = 1.0f / split;

        m_shadowMap = setShadowRenderTarget();
        m_shadowBuffer.BeginSample("Render Shadows");

        m_shadowBuffer.SetGlobalVector(m_globalShadowDataId, new Vector4(tileScale, m_rpp.shadowDistance * m_rpp.shadowDistance));
        executeBuffer(m_shadowBuffer);

        m_shadowBuffer.ClearRenderTarget(true, true, Color.clear, 1);
        executeBuffer(m_shadowBuffer);

        Matrix4x4[] worldToShadowMatrices = new Matrix4x4[m_cullingResults.visibleLights.Length];

        int  tileIndex   = 0;
        bool hardShadows = false;
        bool softShadows = false;

        //主灯光跳过构建
        for (int i = m_mainLightExits ? 1 : 0; i < m_cullingResults.visibleLights.Length; i++)
        {
            if (i == m_maxVisibleLights)
            {
                break;
            }

            if (m_shadowData[i].x <= 0f)
            {
                continue;
            }

            bool bScb = m_cullingResults.GetShadowCasterBounds(i, out Bounds outBounds);

            bool bHaveShadow;

            //通过阴影数据判断是方向光还是聚光灯
            if (m_shadowData[i].z > 0.0f)
            {
                bHaveShadow = m_cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(i, 0, 1, Vector3.right, (int)tileSize,
                                                                                                    m_cullingResults.visibleLights[i].light.shadowNearPlane, out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                bHaveShadow = m_cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
            }

            if (!(bHaveShadow && bScb))
            {
                m_shadowData[i].x = 0.0f;
                continue;
            }

            Vector2 tileOffset = configureShadowTile(tileIndex, split, tileSize);

            m_shadowData[i].z = tileOffset.x * tileScale;
            m_shadowData[i].w = tileOffset.y * tileScale;

            m_shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            m_shadowBuffer.SetGlobalFloat(m_shadowBiasId, m_cullingResults.visibleLights[i].light.shadowBias);
            executeBuffer(m_shadowBuffer);

            //绘制阴影贴图
            var shadowSetting = new ShadowDrawingSettings(m_cullingResults, i);
            shadowSetting.splitData = splitData;
            m_context.DrawShadows(ref shadowSetting);

            //检查Z轴是否反向
            //将深度从-1 - 1 映射到 0 - 1
            calculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);

            tileIndex += 1;

            if (m_shadowData[i].y <= 0.0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }
        }

        //关闭裁剪
        m_shadowBuffer.DisableScissorRect();

        m_shadowBuffer.SetGlobalTexture(m_shadowMapId, m_shadowMap);
        m_shadowBuffer.SetGlobalVectorArray(m_shadowDataId, m_shadowData);
        m_shadowBuffer.SetGlobalMatrixArray(m_worldToShadowMatricesId, worldToShadowMatrices);

        float invShadowMapSize = 1.0f / m_rpp.shadowMapSize;

        m_shadowBuffer.SetGlobalVector(m_shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, m_rpp.shadowMapSize, m_rpp.shadowMapSize));
        CoreUtils.SetKeyword(m_shadowBuffer, m_shadowsHardKeyWord, hardShadows);
        CoreUtils.SetKeyword(m_shadowBuffer, m_shadowsSoftKeyWord, softShadows);

        m_shadowBuffer.EndSample("Render Shadows");
        executeBuffer(m_shadowBuffer);
    }
Esempio n. 9
0
        //渲染shadowmap
        void RenderShadows(ScriptableRenderContext context)
        {
            int split;

            if (shadowTileCount <= 1)
            {
                split = 1;
            }
            else if (shadowTileCount <= 4)
            {
                split = 2;
            }
            else if (shadowTileCount <= 9)
            {
                split = 3;
            }
            else
            {
                split = 4;
            }

            float tileSize     = shadowMapSize / split;
            float tileScale    = 1f / split;
            Rect  tileViewport = new Rect(0f, 0f, tileSize, tileSize);

            //设置shadowMap贴图的
            shadowMap = SetShadowRenderTarget();
            shadowBuffer.BeginSample(commandShadowBufferName);
            shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, shadowDistance * shadowDistance));
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            int  tileIndex   = 0;
            bool hardShadows = false;
            bool softShadows = false;

            for (int i = mainLightExists ? 1 : 0; i < culling.visibleLights.Length; ++i)
            {
                if (i == maxVisibleLights)
                {
                    break;
                }

                //跳过不需要产生阴影的灯光
                if (shadowData[i].x <= 0f)
                {
                    continue;
                }

                //获取spot等的相关矩阵
                //目前这里有报错
                Matrix4x4       viewMatrix, projectionMatrix;
                ShadowSplitData splitData;

                bool validShadows;

                if (shadowData[i].z > 0)
                {
                    validShadows = culling.ComputeDirectionalShadowMatricesAndCullingPrimitives(i, 0, 1, Vector3.right, (int)tileSize, culling.visibleLights[i].light.shadowNearPlane, out viewMatrix, out projectionMatrix, out splitData);
                }
                else
                {
                    validShadows = culling.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
                }

                if (!validShadows)
                {
                    shadowData[i].x = 0f;
                    continue;
                }

                //将16个灯光的阴影图渲染到一个rt上,将rt分成16分
                Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);
                shadowData[i].z = tileOffset.x * tileScale;
                shadowData[i].w = tileOffset.y * tileScale;

                shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
                shadowBuffer.SetGlobalFloat(shadowBiasId, culling.visibleLights[i].light.shadowBias);
                context.ExecuteCommandBuffer(shadowBuffer);
                shadowBuffer.Clear();

                //正式draw
                var shadowSettings         = new ShadowDrawingSettings(culling, i);
                var shadowSettingSplitData = shadowSettings.splitData;
                //对于方向光而言,cullingSphere包含了需要渲染进阴影图的所有物体,减少不必要物体的渲染
                shadowSettingSplitData.cullingSphere = splitData.cullingSphere;
                shadowSettings.splitData             = shadowSettingSplitData;

                context.DrawShadows(ref shadowSettings);

                CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);

                tileIndex += 1;

                if (shadowData[i].y <= 0f)
                {
                    hardShadows = true;
                }
                else
                {
                    softShadows = true;
                }
            }

            shadowBuffer.DisableScissorRect();

            CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
            CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

            shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
            shadowBuffer.SetGlobalMatrixArray(worldToShadowMatrixsId, worldToShadowMatrices);
            shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);
            float invShadowMapSize = 1f / shadowMapSize;

            shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, invShadowMapSize, invShadowMapSize));

            shadowBuffer.EndSample(commandShadowBufferName);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();
        }
    void RenderShadows(ScriptableRenderContext context)
    {
        //this will adjust the tiling of the shadowmap dynamically, so as to use the maximum amount of texture possible while still tiling multiple shadows togather
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        //because we support 16 lights, this will tile the shadowmap into 16 portions
        float tileSize     = shadowMapSize / split;
        float tileScale    = 1f / split;
        Rect  tileViewport = new Rect(0f, 0f, tileSize, tileSize);

        shadowMap            = RenderTexture.GetTemporary(shadowMapSize, shadowMapSize, 16, RenderTextureFormat.Shadowmap);
        shadowMap.filterMode = FilterMode.Bilinear;
        shadowMap.wrapMode   = TextureWrapMode.Clamp;


        CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth);
        //shadowBuffer.SetRenderTarget(shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);

        shadowBuffer.BeginSample("Render Shadows");
        shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, shadowDistance * shadowDistance));
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        int  tileIndex   = 0;
        bool hardShadows = false;
        bool softShadows = false;

        for (int i = 0; i < cull.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)            //skip this section if the light doesn't have shadows or we've hit the max number of lights
            {
                break;
            }
            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;

            bool validShadows;
            //because we are essentially rendering the scene from the light's pov, this sets up the spoof VP matricies for the light's perspective. Also checks to see whether it was able to generate a sensible matrix
            if (shadowData[i].z > 0f)           //if the light is directional
            {
                validShadows = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                    i, 0, 1, Vector3.right, (int)tileSize,
                    cull.visibleLights[i].light.shadowNearPlane,
                    out viewMatrix, out projectionMatrix, out splitData
                    );
            }
            else             //spotlight
            {
                validShadows = cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
            }

            if (!validShadows)
            {
                shadowData[i].x = 0f;
                continue;
            }


            //this is used for tiling
            float tileOffsetX = tileIndex % split;
            float tileOffsetY = tileIndex / split;
            tileViewport.x  = tileOffsetX * tileSize;
            tileViewport.y  = tileOffsetY * tileSize;
            shadowData[i].z = tileOffsetX * tileScale;
            shadowData[i].w = tileOffsetY * tileScale;

            shadowBuffer.SetViewport(tileViewport);
            //stops the different tiled shadow maps from cross sampling by adding a border around each one
            shadowBuffer.EnableScissorRect(new Rect(tileViewport.x + 4f, tileViewport.y + 4f, tileSize - 8f, tileSize - 8f));

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            shadowBuffer.SetGlobalFloat(shadowBiasId, cull.visibleLights[i].light.shadowBias);

            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();


            var shadowSettings = new ShadowDrawingSettings(cull, i);
            shadowSettings.splitData = splitData;
            context.DrawShadows(ref shadowSettings);

            if (SystemInfo.usesReversedZBuffer)            //some gpus flip clipspace z
            {
                projectionMatrix.m20 = -projectionMatrix.m20;
                projectionMatrix.m21 = -projectionMatrix.m21;
                projectionMatrix.m22 = -projectionMatrix.m22;
                projectionMatrix.m23 = -projectionMatrix.m23;
            }

            //clip space goes from -1 to 1, but texture space goes from 0 to 1, this will imbue that transformation into the matrix
            var scaleOffset = Matrix4x4.identity;
            scaleOffset.m00          = scaleOffset.m11 = scaleOffset.m22 = 0.5f;
            scaleOffset.m03          = scaleOffset.m13 = scaleOffset.m23 = 0.5f;
            worldToShadowMatrices[i] = scaleOffset * (projectionMatrix * viewMatrix);


            tileIndex += 1;          //only advance the tileindex when we actually use a tile
            if (shadowData[i].y <= 0)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }
        }

        shadowBuffer.DisableScissorRect();

        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);
        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);

        //Used for soft shadows
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));

        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
    void RenderShadows(ScriptableRenderContext context)
    {
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        float tileSize     = shadowMapSize / split;
        float tileScale    = 1f / split;
        Rect  tileViewport = new Rect(0f, 0f, tileSize, tileSize);

        shadowMap            = RenderTexture.GetTemporary(shadowMapSize, shadowMapSize, 16, RenderTextureFormat.Shadowmap);
        shadowMap.filterMode = FilterMode.Bilinear;
        shadowMap.wrapMode   = TextureWrapMode.Clamp;

        CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare,
                                  RenderBufferStoreAction.Store, ClearFlag.Depth);
        shadowBuffer.BeginSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        int  tileIndex   = 0;
        bool hardShadows = false;
        bool softShadows = false;

        for (int i = 0; i < _cullingResults.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;
            if (!_cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix,
                                                                               out splitData))
            {
                shadowData[i].x = 0f;
                continue;
            }

            float tileOffsetX = tileIndex % split;
            float tileOffsetY = tileIndex / split;
            tileViewport.x = tileOffsetX * tileSize;
            tileViewport.y = tileOffsetY * tileSize;
            if (split > 1)
            {
                shadowBuffer.SetViewport(tileViewport);
                shadowBuffer.EnableScissorRect(new Rect(tileViewport.x + 4f, tileViewport.y + 4f, tileSize - 8f,
                                                        tileSize - 8f));
            }

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            shadowBuffer.SetGlobalFloat(shadowBiasId, _cullingResults.visibleLights[i].light.shadowBias);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();
            ShadowDrawingSettings shadowDrawingSettings = new ShadowDrawingSettings(_cullingResults, i);
            context.DrawShadows(ref shadowDrawingSettings);

            if (SystemInfo.usesReversedZBuffer)
            {
                projectionMatrix.m20 = -projectionMatrix.m20;
                projectionMatrix.m21 = -projectionMatrix.m21;
                projectionMatrix.m22 = -projectionMatrix.m22;
                projectionMatrix.m23 = -projectionMatrix.m23;
            }

            var scaleOffset = Matrix4x4.identity;
            scaleOffset.m00          = scaleOffset.m11 = scaleOffset.m22 = 0.5f;
            scaleOffset.m03          = scaleOffset.m13 = scaleOffset.m23 = 0.5f;
            worldToShadowMatrices[i] = scaleOffset * (projectionMatrix * viewMatrix);

            if (split > 1)
            {
                var tileMatrix = Matrix4x4.identity;
                tileMatrix.m00           = tileMatrix.m11 = tileScale;
                tileMatrix.m03           = tileOffsetX * tileScale;
                tileMatrix.m13           = tileOffsetY * tileScale;
                worldToShadowMatrices[i] = tileMatrix * worldToShadowMatrices[i];
            }

            tileIndex += 1;
            if (shadowData[i].y <= 0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }
        }

        if (split > 1)
        {
            shadowBuffer.DisableScissorRect();
        }

        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);
        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId,
                                     new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));
        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);
        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
Esempio n. 12
0
        private void RenderShadows(ScriptableRenderContext context)
        {
            // 设置阴影贴图图集大小。
            int split = 4;

            if (shadowTileCount <= 1)
            {
                split = 1;
            }
            else if (shadowTileCount <= 4)
            {
                split = 2;
            }
            else if (shadowTileCount <= 9)
            {
                split = 3;
            }
            float tileSize  = ShadowMapSize / split;
            float tileScale = 1f / split;

            globalShadowData.x = tileScale;

            shadowMap = SetShadowRenderTarget(); // 设置阴影渲染目标。

            shadowBuffer.BeginSample(shadowBufferName);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();
            int  tileIndex   = 0;
            bool hardShadows = false;
            bool softShadows = false;

            for (int i = mainLightExists ? 1 : 0; i < cullingResults.visibleLights.Length; i++)
            {
                if (i == maxVisibleLights)
                {
                    break;
                }
                if (shadowData[i].x <= 0f)
                {
                    continue;
                }
                // 聚光灯的视角投影矩阵。我们可以通过 CullingResults 中的 ComputeSpotShadowMatricesAndCullingPrimitives 方法得到。
                // 该方法的第一个参数是光源序列,视野矩阵 和 投影矩阵 则是在后两个输出参数中。
                // 最后一个参数 阴影剔除数据 我们用不到,但作为输出参数,我们必须提供。
                // 方向光的视角投影矩阵。我们可以通过 CullingResults 中的 ComputeDirectionalShadowMatricesAndCullingPrimitives 方法得到。
                // 该方法的第一个参数是光源序列,接着是级联序列,级联数量,级联分级的三维向量,整型的图块尺寸,阴影近平面值,视野矩阵,投影矩阵 和 阴影剔除数据。
                // 阴影剔除数据中包含了一个有效的剔除球体。该球体包裹了所有需要被渲染进直射光阴影贴图的物体。
                // 这对于方向光来说非常重要,因为方向光不像聚光灯,它会影响所有物体,我们需要有一个剔除球体来限制渲染进阴影贴图的图形数量。
                Matrix4x4       viewMatrix, projectionMatrix;
                ShadowSplitData splitData;
                bool            validShadows;
                if (shadowData[i].z > 0f)
                {
                    validShadows = cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(i, 0, 1, Vector3.right, (int)tileSize,
                                                                                                       cullingResults.visibleLights[i].light.shadowNearPlane,
                                                                                                       out viewMatrix, out projectionMatrix, out splitData);
                }
                else
                {
                    validShadows = cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
                }
                if (!validShadows)
                {
                    shadowData[i].x = 0f;
                    continue;
                }
                if (shadowData[i].y <= 0f)
                {
                    hardShadows = true;
                }
                else
                {
                    softShadows = true;
                }
                // 设置阴影tiles,计算tiles偏移,设置视口以及剪裁,返回偏移值。
                Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);
                shadowData[i].z = tileOffset.x * tileSize;
                shadowData[i].w = tileOffset.y * tileSize;
                // 当我们获得了该矩阵,调用 shadowBuffer 的 SetViewProjectionMatrices 方法,然后执行 CommandBuffer 并清理。
                shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
                // 在渲染深度贴图(ShadowCaster)时,在深度上添加一点偏移,来掩盖阴影的瑕疵(条纹状阴影)。
                shadowBuffer.SetGlobalFloat(shadowBiasId, cullingResults.visibleLights[i].light.shadowBias);
                context.ExecuteCommandBuffer(shadowBuffer);
                shadowBuffer.Clear();

                // 有了正确的矩阵信息,我们现在可以渲染所有投射阴影的物体了。
                // 我们通过调用 DrawShadows 方法来实现。 这个方法需要一个 DrawShadowsSettings 类型的引用参数。
                // 我们用 cullingResults 和 光源序列 作为参数来创建一个该实例。
                var shadowSettings = new ShadowDrawingSettings(cullingResults, i);
                context.DrawShadows(ref shadowSettings);
                // 计算world-to-shadow矩阵。
                CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);

                tileIndex += 1;
            }
            shadowBuffer.DisableScissorRect(); // 我们在渲染阴影后调用 DisableScissorRect 关闭裁剪矩形,不然会影响到后面的常规渲染。
            shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
            shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);
            shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);

            CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
            CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

            float invShadowMapSize = 1f / ShadowMapSize;

            shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, ShadowMapSize, ShadowMapSize));

            shadowBuffer.EndSample(shadowBufferName);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();
        }
Esempio n. 13
0
    void RenderShadows(ScriptableRenderContext context)
    {
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        float tileSize     = shadowMapSize / split;
        float tileScale    = 1f / split;
        Rect  tileViewport = new Rect(0f, 0f, tileSize, tileSize);

        // shadowmap
        shadowMap = SetShadowRenderTarget();

        shadowBuffer.BeginSample("Render Shadows");
        globalShadowData.x = tileScale;
        //shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, shadowDistance*shadowDistance));
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        int tileIndex = 0;

        for (int i = mainLightExists?1:0; i < cull.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            VisibleLight visibleLight = cull.visibleLights[i];

            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;
            bool            validShadows;
            if (shadowData[i].z > 0f)
            {
                // directional
                validShadows = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(i, 0, 1, Vector3.right, (int)tileSize, visibleLight.light.shadowNearPlane,
                                                                                         out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                validShadows = cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
            }
            if (!validShadows)
            {
                shadowData[i].x = 0f;
                continue;
            }

            Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);

            shadowData[i].z = tileOffset.x * tileScale;
            shadowData[i].w = tileOffset.y * tileScale;

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            shadowBuffer.SetGlobalFloat(shadowBiasId, visibleLight.light.shadowBias);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            // draw shadow for light i
            var shadowSettings = new ShadowDrawingSettings(cull, i);
            shadowSettings.splitData = splitData;
            context.DrawShadows(ref shadowSettings);

            // save matrix
            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);

            tileIndex += 1;
        }

        // 꼴숏써監
        shadowBuffer.DisableScissorRect();

        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);
        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));
        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }