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); }
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); }