Esempio n. 1
0
    /// <summary>
    /// 渲染点光源阴影
    /// </summary>
    /// <param name="index"></param>
    /// <param name="split"></param>
    /// <param name="tileSize"></param>
    void RenderPointShadows(int index, int split, int tileSize)
    {
        ShadowOtherLight light = shadowedOtherLights[index];
        var shadowSettings     = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);
        //Normal Bias
        float texelSize  = 2f / tileSize;
        float filterSize = texelSize * ((float)settings.other.filter + 1f);
        float bias       = light.normalBias * filterSize * 1.4142136f;
        float tileScale  = 1 / 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;
            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 shadowSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Esempio n. 2
0
    /// <summary>
    /// 渲染聚光灯阴影
    /// </summary>
    /// <param name="index"></param>
    /// <param name="split"></param>
    /// <param name="tileSize"></param>
    void RenderSpotShadows(int index, int split, int tileSize)
    {
        ShadowOtherLight light = shadowedOtherLights[index];
        var shadowSettings     = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

        cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(light.visibleLightIndex, out Matrix4x4 viewMatrix,
                                                                     out Matrix4x4 projectionMatrix, out ShadowSplitData splitData);
        shadowSettings.splitData = splitData;
        //Normal Bias
        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  = 1 / 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. 3
0
    /// <summary>
    /// 用于其他灯光阴影
    /// </summary>
    /// <param name="light"></param>
    /// <param name="visibleLightIndex"></param>
    /// <returns></returns>
    public Vector4 ReserveOtherShadows(Light light, int visibleLightIndex)
    {
        //判断无阴影 或者强度是0 立即返回
        if (light.shadows == LightShadows.None || light.shadowStrength <= 0f)
        {
            return(new Vector4(0f, 0f, 0f, -1f));
        }
        float maskChannel = -1f;

        LightBakingOutput lightBaking = light.bakingOutput;

        if (lightBaking.lightmapBakeType == LightmapBakeType.Mixed && lightBaking.mixedLightingMode == MixedLightingMode.Shadowmask)
        {
            useShadowMask = true;
            maskChannel   = lightBaking.occlusionMaskChannel;
        }
        //是否是点光源 疑问:为什么点光源 需要6个Tile
        bool isPoint       = light.type == LightType.Point;
        int  newLightCount = shadowedOtherLightCount + (isPoint ? 6 : 1);

        if (newLightCount >= maxShadowedOtherLightCount || !cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b))
        {
            return(new Vector4(-light.shadowStrength, 0f, 0f, maskChannel));
        }
        shadowedOtherLights[shadowedOtherLightCount] = new ShadowOtherLight
        {
            visibleLightIndex = visibleLightIndex,
            slopeScaleBias    = light.shadowBias,
            normalBias        = light.shadowNormalBias,
            isPoint           = isPoint
        };
        Vector4 data = new Vector4(light.shadowStrength, shadowedOtherLightCount++, isPoint ? 1f: 0f, lightBaking.occlusionMaskChannel);

        shadowedOtherLightCount = newLightCount;
        //返回Mix灯光 ShadowMask
        return(data);
    }