예제 #1
0
    void RenderOneSpotShadows(int shadowedLightIdx, int atlasSplitFactor, int atlasTileSize)
    {
        ShadowedLight shadowedLight = _shadowedSpotLights[shadowedLightIdx];

        _cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowedLight.visibleIndex, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData);
        _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);

        Rect tileViewPort = Rect.zero;
        int  tileIdx      = shadowedLightIdx;

        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;

        normalizeViewPort.x               = tileViewPort.x / atlasSize + texelSize;
        normalizeViewPort.y               = tileViewPort.y / atlasSize + texelSize;
        normalizeViewPort.z               = tileViewPort.width / atlasSize - texelSize;
        normalizeViewPort.w               = tileViewPort.height / atlasSize - texelSize;
        _spotShadowMatrixs[tileIdx]       = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, tileViewPort, atlasSize);
        _spotShadowTileViewPorts[tileIdx] = normalizeViewPort;

        ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, shadowedLight.visibleIndex);

        shadowDrawSetting.splitData = shadowSplitData;
        _srContext.DrawShadows(ref shadowDrawSetting);
        _cmdBuffer.SetGlobalDepthBias(0, 0);
    }
예제 #2
0
    void RenderOneDirectionalShadow(int lightIdx, int tileSplitFactor)
    {
        ShadowedLight shadowedLight      = _shadowedDirLights[lightIdx];
        int           cascadeSplitFactor = _shadowSetting.directional.cascadeCount > 1 ? 2 : 1;
        int           tileSize           = (int)_shadowSetting.directional.atlasSize / tileSplitFactor;
        int           cascadeSize        = (int)_shadowSetting.directional.atlasSize / (tileSplitFactor * cascadeSplitFactor);
        int           visibleIndex       = shadowedLight.visibleIndex;

        _shadowMapSizes.x = cascadeSize;

        _cmdBuffer.SetGlobalDepthBias(0, shadowedLight.light.shadowBias);
        for (int cascadeIdx = 0; cascadeIdx < _shadowSetting.directional.cascadeCount; cascadeIdx++)
        {
            _cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(visibleIndex,
                                                                              cascadeIdx,
                                                                              _shadowSetting.directional.cascadeCount,
                                                                              _shadowSetting.directional.cascadeSplitRatio,
                                                                              cascadeSize,
                                                                              shadowedLight.light.shadowNearPlane,
                                                                              out Matrix4x4 viewMatrix,
                                                                              out Matrix4x4 projMatrix,
                                                                              out ShadowSplitData shadowSplitData);
            _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);

            Vector2 tileOffset     = new Vector2(lightIdx % 2, lightIdx / 2);
            Vector2 cascadeOffset  = new Vector2(cascadeIdx % 2, cascadeIdx / 2);
            Rect    viewPortOffset = new Rect(tileOffset.x * tileSize + cascadeOffset.x * cascadeSize, tileOffset.y * tileSize + cascadeOffset.y * cascadeSize, cascadeSize, cascadeSize);
            _cmdBuffer.SetViewport(viewPortOffset);
            ExecuteCommandBuffer();

            _dirShadowMatrixs[lightIdx * MAX_NUM_DIRECTIONAL_CASCADES + cascadeIdx] = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, viewPortOffset, (int)_shadowSetting.directional.atlasSize);
            if (lightIdx == 0)   // all directional light share the same cascade culling spheres
            {
                _dirCascadeCullingSpheres[cascadeIdx] = shadowSplitData.cullingSphere;
            }

            ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, visibleIndex)
            {
                splitData = shadowSplitData
            };
            _srContext.DrawShadows(ref shadowDrawSetting);
        }
        _cmdBuffer.SetGlobalDepthBias(0, 0);
    }
예제 #3
0
    public Vector4 GetDirectionalShadowData(int visibleLightIndex)
    {
        Vector4 shadowData = new Vector4(-1, 0, 0, -1);
        Light   dirLight   = _cullResults.visibleLights[visibleLightIndex].light;

        if (dirLight.type != LightType.Directional)
        {
            return(shadowData);
        }

        if (dirLight.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed && dirLight.bakingOutput.mixedLightingMode == MixedLightingMode.Shadowmask)
        {
            shadowData.y             = dirLight.shadowStrength; // when mixed light who' s shadow has baked to shadow mask did't cast shadow at run time, we want to use shadow in shadow mask
            shadowData.w             = dirLight.bakingOutput.occlusionMaskChannel;
            _mixedLightUseShadowMask = true;
        }

        if (_shadowedDirLightCount >= MAX_NUM_DIRECTIONAL_SHADOWS ||
            dirLight.shadows == LightShadows.None ||
            dirLight.shadowStrength <= 0 ||
            !_cullResults.GetShadowCasterBounds(visibleLightIndex, out Bounds bounds))
        {
            return(shadowData);
        }

        _shadowedDirLights[_shadowedDirLightCount] = new ShadowedLight()
        {
            visibleIndex = visibleLightIndex, light = dirLight
        };
        shadowData.x = _shadowedDirLightCount * MAX_NUM_DIRECTIONAL_CASCADES;
        shadowData.y = dirLight.shadowStrength;
        shadowData.z = dirLight.shadowNormalBias * 2f - 1f;

        _shadowedDirLightCount++;

        return(shadowData);
    }
예제 #4
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);
        }
    }
예제 #5
0
    public Vector4 GetSpotLightShadowData(int visibleLightIndex)
    {
        Vector4 shadowData = new Vector4(-1, 0, 0, -1);
        Light   spotLight  = _cullResults.visibleLights[visibleLightIndex].light;

        if (spotLight.type != LightType.Spot)
        {
            return(shadowData);
        }

        if (spotLight.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed && spotLight.bakingOutput.mixedLightingMode == MixedLightingMode.Shadowmask)
        {
            shadowData.y             = spotLight.shadowStrength;
            shadowData.w             = spotLight.bakingOutput.occlusionMaskChannel;
            _mixedLightUseShadowMask = true;
        }

        if (_shadowedSpotLightCount >= MAX_NUM_SPOT_SHADOWS ||
            spotLight.shadows == LightShadows.None ||
            spotLight.shadowStrength <= 0 ||
            !_cullResults.GetShadowCasterBounds(visibleLightIndex, out Bounds bounds))
        {
            return(shadowData);
        }

        _shadowedSpotLights[_shadowedSpotLightCount] = new ShadowedLight()
        {
            visibleIndex = visibleLightIndex, light = spotLight
        };
        shadowData.x = _shadowedSpotLightCount;
        shadowData.y = spotLight.shadowStrength;
        shadowData.z = spotLight.shadowNormalBias * 2f - 1f;

        _shadowedSpotLightCount++;

        return(shadowData);
    }