Ejemplo n.º 1
0
    private void RenderPointShadows(int index, int split, int tileSize)
    {
        ShadowedOtherLight    light          = shadowedOtherLights[index];
        ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

        float texelSize  = 2f / tileSize;
        float filterSize = texelSize * ((float)this.shadowSettings.other.filter + 1f);
        float bias       = light.normalBias * filterSize * 1.4142136f;
        float tileScale  = 1f / split;
        float fovBias    = Mathf.Atan(1f + bias + filterSize) * Mathf.Rad2Deg * 2f - 90f;

        for (int i = 0; i < 6; ++i)
        {
            cullingResults.ComputePointShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, (CubemapFace)i, fovBias, out Matrix4x4 viewMatrix,
                out Matrix4x4 projectionMatrix, out ShadowSplitData splitData);
            viewMatrix.m11           = -viewMatrix.m11;
            viewMatrix.m12           = -viewMatrix.m12;
            viewMatrix.m13           = -viewMatrix.m13;
            shadowSettings.splitData = splitData;
            int tileIndex = index + i;
            //float texelSize = 2f / (tileSize * projectionMatrix.m00);
            //float filterSize = texelSize * ((float)this.shadowSettings.other.filter + 1f);
            //float bias = light.normalBias * filterSize * 1.4142136f;
            Vector2 offset = SetTileViewport(tileIndex, split, tileSize);
            //float tileScale = 1f / split;
            SetOtherTileData(tileIndex, offset, tileScale, bias);
            otherShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, offset, tileScale);
            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
            ExecuteBuffer();
            context.DrawShadows(ref shadowSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Ejemplo n.º 2
0
	private void RenderPointLightShadow(CullingResults cull, int shadowLightCount, Light[] shadowLights, int[] shadowLightIndices) {
		var pointLightShadowmapDescriptor = new RenderTextureDescriptor(@params.pointLightParams.shadowResolution, @params.pointLightParams.shadowResolution, RenderTextureFormat.RHalf, 16) {
			autoGenerateMips = false,
			bindMS = false,
			dimension = TextureDimension.CubeArray,
			volumeDepth = shadowLightCount * 6,
			enableRandomWrite = false,
			msaaSamples = 1,
			shadowSamplingMode = ShadowSamplingMode.None,
			sRGB = false,
			useMipMap = false,
			vrUsage = VRTextureUsage.None
		};
		
		_currentBuffer.GetTemporaryRT(ShaderManager.POINT_LIGHT_SHADOWMAP_ARRAY, pointLightShadowmapDescriptor, FilterMode.Bilinear);

		for (var i = 0; i < shadowLightCount; i++) {
			if (!cull.GetShadowCasterBounds(shadowLightIndices[i], out var shadowBounds)) continue;
			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]);

			for (var j = 0; j < 6; j++) {
				var shadowSlice = i * 6 + j;
				ResetRenderTarget(PointLightShadowmapArrayId, CubemapFace.Unknown, shadowSlice, true, true, 1, Color.white);
				if (!cull.ComputePointShadowMatricesAndCullingPrimitives(shadowLightIndices[i], (CubemapFace) j, 0, out var viewMatrix, out var projectionMatrix, out var splitData)) {
					ExecuteCurrentBuffer();
					continue;
				}

				shadowSettings.splitData = splitData;
				
				Vector3 position = light.transform.position;
				_currentBuffer.SetGlobalVector(ShaderManager.LIGHT_POS, new Vector4(position.x, position.y, position.z, light.range));
				_currentBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
				ExecuteCurrentBuffer();

				_context.DrawShadows(ref shadowSettings);
			}
		}

		var inverseShadowmapSize = 1f / @params.pointLightParams.shadowResolution;
		
		_currentBuffer.SetGlobalVector(ShaderManager.POINT_LIGHT_SHADOWMAP_SIZE, new Vector4(inverseShadowmapSize, inverseShadowmapSize, @params.pointLightParams.shadowResolution, @params.pointLightParams.shadowResolution));

		if (@params.pointLightParams.softShadow) _currentBuffer.EnableShaderKeyword(ShaderManager.POINT_LIGHT_SOFT_SHADOWS);
		else _currentBuffer.DisableShaderKeyword(ShaderManager.POINT_LIGHT_SOFT_SHADOWS);
		
		ExecuteCurrentBuffer();
	}
Ejemplo n.º 3
0
    void RenderPointShadows(int index, int split, int tileSize)
    {
        ShadowedOtherLight light = shadowedOtherLights[index];

        //6 face FOV is fixed to 90 degree
        float texelSize  = 2f / (tileSize);
        float filterSize = texelSize * ((float)shadowSettings.other.filter + 1f);
        float bias       = light.normalBias * filterSize * 1.414f;
        float tileScale  = 1f / split;

        //create a shadowdrawsetting based on the light index
        var shadowDSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex)
        {
            useRenderingLayerMaskTest = true
        };                                   //make shadow effcted by rendering layer mask

        //FOV bias to extend fov for a bit to get rid of seams
        float fovBias = Mathf.Atan(1f + bias + filterSize) * Mathf.Rad2Deg * 2f - 90f;

        for (int i = 0; i < 6; i++)
        {
            //get matrcies
            cullingResults.ComputePointShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, (CubemapFace)i, fovBias, out Matrix4x4 viewMatrix,
                out Matrix4x4 projectionMatrix, out ShadowSplitData splitData);

            //negate the unity reverse unity render shadow unside down(Stop light leak)
            viewMatrix.m11 = -viewMatrix.m11;
            viewMatrix.m12 = -viewMatrix.m12;
            viewMatrix.m13 = -viewMatrix.m13;

            shadowDSettings.splitData = splitData;

            int tileIndex = index + i;
            //m00 for projectiona matrix is the projection scale?

            Vector2 offset = SetTileViewport(tileIndex, split, tileSize);
            SetOtherTileData(tileIndex, offset, tileScale, bias);

            otherShadowMatrices[tileIndex] = ConvertToAtlasMatrix(
                projectionMatrix * viewMatrix,
                offset, tileScale
                );

            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
            ExecuteBuffer();
            context.DrawShadows(ref shadowDSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Ejemplo n.º 4
0
    private void RenderPointShadows(int index, int split, int tileSize)
    {
        ShadowedDirectionalLight light = shadowedDirectionalLights[index];
        var shadowSettings             = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

        int     cascadeCount  = settings.directional.cascadeCount;
        int     tileOffset    = index * cascadeCount;
        Vector3 ratios        = settings.directional.CascadeRatios;
        float   cullingFactor =
            Mathf.Max(0f, 0.8f - settings.directional.cascadeFade);

        for (int j = 5; j >= 0; j--)
        {
            for (int i = 0; i < cascadeCount; i++)
            {
                cullingResults.ComputePointShadowMatricesAndCullingPrimitives(light.visibleLightIndex, (CubemapFace)j,
                                                                              light.nearPlaneOffset,
                                                                              out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData);

                splitData.shadowCascadeBlendCullingFactor = cullingFactor;
                shadowSettings.splitData = splitData;

                if (index == 0)
                {
                    SetCascadeData(i, splitData.cullingSphere, tileSize);
                }

                int tileIndex = tileOffset + i;
                dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(
                    projectionMatrix * viewMatrix,
                    SetTileViewport(tileIndex, split, tileSize), split
                    );

                buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
                buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
                ExecuteBuffer();
                context.DrawShadows(ref shadowSettings);
                buffer.SetGlobalDepthBias(0f, 0f);
            }
        }
    }
Ejemplo n.º 5
0
        public static bool ExtractPointLightMatrix(ref CullingResults cullResults, ref ShadowData shadowData, int shadowLightIndex, CubemapFace cubemapFace, float fovBias, out Matrix4x4 shadowMatrix, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData splitData)
        {
            bool success = cullResults.ComputePointShadowMatricesAndCullingPrimitives(shadowLightIndex, cubemapFace, fovBias, out viewMatrix, out projMatrix, out splitData); // returns false if input parameters are incorrect (rare)

            // In native API CullingResults.ComputeSpotShadowMatricesAndCullingPrimitives there is code that inverts the 3rd component of shadow-casting spot light's "world-to-local" matrix (it was so since its original addition to the code base):
            // https://github.cds.internal.unity3d.com/unity/unity/commit/34813e063526c4be0ef0448dfaae3a911dd8be58#diff-cf0b417fc6bd8ee2356770797e628cd4R331
            // (the same transformation has also always been used in the Built-In Render Pipeline)
            //
            // However native API CullingResults.ComputePointShadowMatricesAndCullingPrimitives does not contain this transformation.
            // As a result, the view matrices returned for a point light shadow face, and for a spot light with same direction as that face, have opposite 3rd component.
            //
            // This causes normalBias to be incorrectly applied to shadow caster vertices during the point light shadow pass.
            // To counter this effect, we invert the point light shadow view matrix component here:
            {
                viewMatrix.m10 = -viewMatrix.m10;
                viewMatrix.m11 = -viewMatrix.m11;
                viewMatrix.m12 = -viewMatrix.m12;
                viewMatrix.m13 = -viewMatrix.m13;
            }

            shadowMatrix = GetShadowTransform(projMatrix, viewMatrix);
            return(success);
        }
Ejemplo n.º 6
0
    void RenderOnePointShadows(int shadowedLightIdx, int atlasSplitFactor, int atlasTileSize)
    {
        ShadowedLight         shadowedLight     = _shadowedPointLights[shadowedLightIdx];;
        ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, shadowedLight.visibleIndex);

        for (int faceIdx = 0; faceIdx < 6; faceIdx++)
        {
            _cullResults.ComputePointShadowMatricesAndCullingPrimitives(shadowedLight.visibleIndex,
                                                                        (CubemapFace)faceIdx,
                                                                        0,
                                                                        out Matrix4x4 viewMatrix,
                                                                        out Matrix4x4 projMatrix,
                                                                        out ShadowSplitData shadowSplitData);
            viewMatrix.m11 *= -1;   // unity render point light shadow upside down
            viewMatrix.m12 *= -1;
            viewMatrix.m13 *= -1;
            _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);

            Rect tileViewPort = Rect.zero;
            int  tileIdx      = shadowedLightIdx * 6 + faceIdx;
            tileViewPort.x     = tileIdx % atlasSplitFactor * atlasTileSize;
            tileViewPort.y     = tileIdx / atlasSplitFactor * atlasTileSize;
            tileViewPort.width = tileViewPort.height = atlasTileSize;
            _cmdBuffer.SetViewport(tileViewPort);
            _cmdBuffer.SetGlobalDepthBias(0, shadowedLight.light.shadowBias);
            ExecuteCommandBuffer();

            int     atlasSize         = atlasSplitFactor * atlasTileSize;
            Vector4 normalizeViewPort = Vector4.zero;
            float   texelSize         = 1f / atlasSize;
            _pointShadowMatrixs[tileIdx] = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, tileViewPort, atlasSize);

            shadowDrawSetting.splitData = shadowSplitData;
            _srContext.DrawShadows(ref shadowDrawSetting);
            _cmdBuffer.SetGlobalDepthBias(0, 0);
        }
    }