Пример #1
0
    bool DoBloom(int sourceId)
    {
        //buffer.BeginSample("Bloom");
        PostFXSettings.BloomSettings bloom = settings.Bloom;
        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;

        if (bloom.maxIterations == 0 || bloom.intensity <= 0f || height < bloom.downscaleLimit || width < bloom.downscaleLimit)
        {
            //Draw(sourceId,BuiltinRenderTextureType.CameraTarget,Pass.Copy);
            //buffer.EndSample("Bloom");
            return(false);
        }
        buffer.BeginSample("Bloom");
        //阀值超过阀值的像素部分才会Bloom
        Vector4 threshold;

        threshold.x  = Mathf.GammaToLinearSpace(bloom.threshold);
        threshold.y  = threshold.x * bloom.thresholdKnee;
        threshold.z  = 2f * threshold.y;
        threshold.w  = 0.25f / (threshold.y + 0.00001f);
        threshold.y -= threshold.x;
        buffer.SetGlobalVector(bloomThresholdId, threshold);
        //看是否支持HDR格式纹理
        RenderTextureFormat format = useHDR?RenderTextureFormat.DefaultHDR:RenderTextureFormat.Default;

        //降采样
        buffer.GetTemporaryRT(bloomPrefilterId, width, height, 0, FilterMode.Bilinear, format);
        Draw(sourceId, bloomPrefilterId, bloom.fadeFireflies ? Pass.BloomPrefilterFireflies: Pass.BloomPrefilter);
        width  /= 2;
        height /= 2;

        int fromId = bloomPrefilterId, toId = bloomPyramidId + 1;

        int i;

        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit * 2 || width < bloom.downscaleLimit * 2) //划分到最小像素 降分辨率
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);
            fromId  = toId;
            toId   += 2;
            width  /= 2;
            height /= 2;
        }
        buffer.ReleaseTemporaryRT(bloomPrefilterId);

        buffer.SetGlobalFloat(bloomBucibicUpsamplingId, bloom.bicubicUpsampling?1f:0f);
        //Draw(fromId,BuiltinRenderTextureType.CameraTarget,Pass.Copy);
        Pass  combinePass, finalPass;
        float finalIntensity;

        if (bloom.mode == PostFXSettings.BloomSettings.Mode.Additive)
        {
            combinePass = finalPass = Pass.BloomAdd;
            buffer.SetGlobalFloat(bloomIntensityId, 1f);
            finalIntensity = bloom.intensity;
        }
        else
        {
            combinePass = Pass.BloomScatter;
            finalPass   = Pass.BloomScatterFinal;
            buffer.SetGlobalFloat(bloomIntensityId, bloom.scatter);
            finalIntensity = Mathf.Min(bloom.intensity, 0.95f);
        }
        //升采样
        if (i > 1) //迭代次数大于1次
        {
            buffer.ReleaseTemporaryRT(fromId - 1);
            toId -= 5;

            for (i -= 1; i > 0; i--)
            {
                buffer.SetGlobalTexture(fxSource2Id, toId + 1); //上去5次?
                Draw(fromId, toId, combinePass);

                buffer.ReleaseTemporaryRT(fromId);
                buffer.ReleaseTemporaryRT(toId + 1);
                fromId = toId;
                toId  -= 2;
            }
        }
        else
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId);
        }
        buffer.SetGlobalFloat(bloomIntensityId, finalIntensity);
        buffer.SetGlobalTexture(fxSource2Id, sourceId);
        //如果有Bloom 渲染到Result RT 上面
        buffer.GetTemporaryRT(bloomResultId, camera.pixelWidth, camera.pixelHeight, 0, FilterMode.Bilinear, format);

        Draw(fromId, bloomResultId, finalPass);
        buffer.ReleaseTemporaryRT(fromId);
        buffer.EndSample("Bloom");
        return(true);
    }
Пример #2
0
    bool DoBloom(int SourceId)
    {
        PostFXSettings.BloomSettings bloomSettings = settings.Bloom;

        //if the blomm should based on scaled render buffer size
        int width, height;

        if (bloomSettings.ignoreRenderScale)
        {
            width  = camera.pixelWidth / 2;
            height = camera.pixelHeight / 2;
        }
        else
        {
            width  = bufferSize.x / 2;
            height = bufferSize.y / 2;
        }

        if (bloomSettings.maxIterations == 0 || bloomSettings.intensity <= 0f ||
            height < bloomSettings.downscaleLimit || width < bloomSettings.downscaleLimit)
        {
            //Draw(SourceId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            //buffer.EndSample("Bloom");
            return(false);
        }

        buffer.BeginSample("Bloom");
        //compute the constant part of bloom threshold knee
        Vector4 threshold;

        threshold.x  = Mathf.GammaToLinearSpace(bloomSettings.threshold);
        threshold.y  = threshold.x * bloomSettings.thresholdKnee;
        threshold.z  = 2f * threshold.y;
        threshold.w  = 0.25f / (threshold.y + 0.00001f);
        threshold.y -= threshold.x;
        buffer.SetGlobalVector(bloomThreshold, threshold);
        //unform format for easier switch HDR
        RenderTextureFormat format = useHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;

        //We start bloom at half resolution
        buffer.GetTemporaryRT(bloomPrefilterId, width, height, 0, FilterMode.Bilinear, format);
        Draw(SourceId, bloomPrefilterId,
             settings.Bloom.Fade_FireFlies? Pass.BloomPrefilterFireFlies : Pass.BloomPrefilter);
        width  /= 2;
        height /= 2;
        //We are using 2 pass per bloom level
        int fromId = bloomPrefilterId, toId = bloomPyramidId + 1;

        int i;

        for (i = 0; i < bloomSettings.maxIterations; i++)
        {
            if (width < bloomSettings.downscaleLimit * 2 || height < bloomSettings.downscaleLimit * 2)
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);

            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);

            fromId  = toId;
            toId   += 2;
            width  /= 2;
            height /= 2;
        }

        buffer.ReleaseTemporaryRT(bloomPrefilterId);
        //Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
        //release the mid for last level
        buffer.ReleaseTemporaryRT(fromId - 1);
        //set toId to the mid of one level higher
        toId -= 5;

        // combine bloom
        Pass  combinePass, finalPass;
        float finalIntensity;

        if (bloomSettings.mode == PostFXSettings.BloomSettings.Mode.Additive)
        {
            combinePass = finalPass = Pass.BloomAdd;
            buffer.SetGlobalFloat(bloomIntensityId, 1f);
            finalIntensity = bloomSettings.intensity;
        }
        else
        {
            combinePass = Pass.BloomScatter;
            finalPass   = Pass.BloomScatterFinal;
            buffer.SetGlobalFloat(bloomIntensityId, bloomSettings.intensity);
            finalIntensity = Mathf.Min(bloomSettings.intensity, 0.95f);
        }

        buffer.SetGlobalFloat(bloomBicubicUpsamplingId, bloomSettings.bicubicUpsampling ? 1f : 0f);

        if (i > 1)
        {
            //stop at the 1st level, special case for level before last level
            //just in-order to reuse RTs
            for (i -= 1; i > 0; i--)
            {
                buffer.SetGlobalTexture(fxSource2Id, toId + 1);
                Draw(fromId, toId, combinePass);
                buffer.ReleaseTemporaryRT(fromId);
                buffer.ReleaseTemporaryRT(toId + 1);
                fromId = toId;
                toId  -= 2;
            }
        }
        else
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId);
        }

        buffer.SetGlobalFloat(bloomIntensityId, finalIntensity);
        buffer.SetGlobalTexture(fxSource2Id, SourceId);
        buffer.GetTemporaryRT(bloomResultId, bufferSize.x, bufferSize.y, 0,
                              FilterMode.Bilinear, format);
        //Draw the bloom result on a RT for tone mapping
        Draw(fromId, bloomResultId, finalPass);
        buffer.ReleaseTemporaryRT(fromId);

        buffer.EndSample("Bloom");
        return(true);
    }