BloomRect[] CalculateBloomRenderTextureArrangement( out int dstWidth, out int dstHeight, int width, int height, int padding, int levelCount) { var rects = new List <BloomRect>(); bool right = height > width; int x = padding; int y = padding; int maxX = 0; int maxY = 0; while (levelCount > 0 && width > 0 && height > 0) { var rect = new BloomRect(); rect.x = x; rect.y = y; rect.width = width; rect.height = height; rect.uvTransformShaderPropertyId = Shader.PropertyToID("_BloomUvTransform" + rects.Count); rect.weightShaderPropertyId = Shader.PropertyToID("_BloomWeight" + rects.Count); rects.Add(rect); maxX = Mathf.Max(maxX, x + width + padding); maxY = Mathf.Max(maxY, y + height + padding); if (right != false) { x += width + padding; } else { y += height + padding; } right = !right; width /= 2; height /= 2; if (width < 0 || height < 0) { break; } levelCount--; } dstWidth = maxX; dstHeight = maxY; return(rects.ToArray()); }
void UpdateCombineMesh() { BloomRect toRect = bloomRects[bloomRects.Length - combinePassCount]; float x0 = (float)toRect.x / (float)combineDescriptor.width; float x1 = (float)(toRect.x + toRect.width) / (float)combineDescriptor.width; float y0 = (float)toRect.y / (float)combineDescriptor.height; float y1 = (float)(toRect.y + toRect.height) / (float)combineDescriptor.height; combineMesh.Clear(); combineMesh.SetVertices( new Vector3[] { new Vector3(x0, y0, 0), new Vector3(x0, y1, 0), new Vector3(x1, y1, 0), new Vector3(x1, y0, 0) }); combineMesh.SetIndices( new int[] { 0, 1, 2, 3 }, MeshTopology.Quads, 0); combineMesh.UploadMeshData(false); }
bool UpdateResources(int updateFlags) { bool rebuild = false; if ((updateFlags & BloomProperties.kChangeThresholds) != 0) { if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) != false || SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat) != false || SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB111110Float) != false) { if (material.IsKeywordEnabled(kShaderKeywordLDR) != false) { material.DisableKeyword(kShaderKeywordLDR); } material.SetFloat(kShaderPropertyThresholds, Properties.Thresholds); } else { if (material.IsKeywordEnabled(kShaderKeywordLDR) == false) { material.EnableKeyword(kShaderKeywordLDR); } var colorTransform = new Vector4(); if (Properties.Thresholds >= 1.0f) { colorTransform.x = 0.0f; colorTransform.y = 0.0f; } else { colorTransform.x = 1.0f / (1.0f - Properties.Thresholds); colorTransform.y = -Properties.Thresholds / (1.0f - Properties.Thresholds); } material.SetVector(kShaderPropertyColorTransform, colorTransform); } } if ((updateFlags & BloomProperties.kChangeSigmaInPixel) != 0) { material.SetFloat(kShaderPropertyInvertOffsetScale01, CalculateGaussianSamples(Properties.SigmaInPixel)); updateFlags |= BloomProperties.kChangeGaussianBlurMesh; } if ((updateFlags & BloomProperties.kVerifyCombinePassCount) != 0) { combinePassCount = (bloomRects.Length + Properties.DownSampleLevel) - Properties.CombineStartLevel; combinePassCount = Mathf.Clamp(combinePassCount, 0, bloomRects.Length); bloomRectCount = bloomRects.Length - combinePassCount; bloomRectCount = Mathf.Clamp(bloomRectCount, 0, bloomRects.Length - 1); if (cacheCombinePassCount != combinePassCount) { /* Combine */ if ((combinePassCount & 0x4) != 0) { if (material.IsKeywordEnabled(kShaderKeywordCombineSample4) == false) { material.EnableKeyword(kShaderKeywordCombineSample4); } } else if (material.IsKeywordEnabled(kShaderKeywordCombineSample4) != false) { material.DisableKeyword(kShaderKeywordCombineSample4); } if ((combinePassCount & 0x2) != 0) { if (material.IsKeywordEnabled(kShaderKeywordCombineSample2) == false) { material.EnableKeyword(kShaderKeywordCombineSample2); } } else if (material.IsKeywordEnabled(kShaderKeywordCombineSample2) != false) { material.DisableKeyword(kShaderKeywordCombineSample2); } if ((combinePassCount & 0x1) != 0) { if (material.IsKeywordEnabled(kShaderKeywordCombineSample1) == false) { material.EnableKeyword(kShaderKeywordCombineSample1); } } else if (material.IsKeywordEnabled(kShaderKeywordCombineSample1) != false) { material.DisableKeyword(kShaderKeywordCombineSample1); } /* Composition */ if (combinePassCount > 0) { if (material.IsKeywordEnabled(kShaderKeywordCompositionCombined) == false) { material.EnableKeyword(kShaderKeywordCompositionCombined); } } else if (material.IsKeywordEnabled(kShaderKeywordCompositionCombined) != false) { material.DisableKeyword(kShaderKeywordCompositionCombined); } cacheCombinePassCount = combinePassCount; updateFlags |= BloomProperties.kChangeCombinePassCount; } if (cacheBloomRectCount != bloomRectCount) { /* Composition */ if ((bloomRectCount & 0x4) != 0) { if (material.IsKeywordEnabled(kShaderKeywordCompositionSample4) == false) { material.EnableKeyword(kShaderKeywordCompositionSample4); } } else if (material.IsKeywordEnabled(kShaderKeywordCompositionSample4) != false) { material.DisableKeyword(kShaderKeywordCompositionSample4); } if ((bloomRectCount & 0x2) != 0) { if (material.IsKeywordEnabled(kShaderKeywordCompositionSample2) == false) { material.EnableKeyword(kShaderKeywordCompositionSample2); } } else if (material.IsKeywordEnabled(kShaderKeywordCompositionSample2) != false) { material.DisableKeyword(kShaderKeywordCompositionSample2); } if ((bloomRectCount & 0x1) != 0) { if (material.IsKeywordEnabled(kShaderKeywordCompositionSample1) == false) { material.EnableKeyword(kShaderKeywordCompositionSample1); } } else if (material.IsKeywordEnabled(kShaderKeywordCompositionSample1) != false) { material.DisableKeyword(kShaderKeywordCompositionSample1); } cacheBloomRectCount = bloomRectCount; updateFlags |= BloomProperties.kChangeBloomRectCount; } } if ((updateFlags & BloomProperties.kVerifyCombineComposition) != 0) { /* Combine */ BloomRect toRect = bloomRects[bloomRectCount]; float combinedStrengthSum = 0.0f; float combinedStrength = 1.0f; for (int i0 = 0; i0 < combinePassCount; ++i0) { combinedStrengthSum += combinedStrength; combinedStrength *= Properties.IntensityMultiplier; } float normalizeFactor = 1.0f / combinedStrengthSum; combinedStrength = 1.0f; for (int i0 = 0; i0 < combinePassCount; ++i0) { int fromLevel = bloomRectCount + i0; var fromRect = bloomRects[fromLevel]; material.SetFloat( kShaderPropertyWeights[i0], combinedStrength * normalizeFactor); Vector4 uvTransform; uvTransform.x = (float)fromRect.width / (float)toRect.width; uvTransform.y = (float)fromRect.height / (float)toRect.height; uvTransform.z = ((float)fromRect.x - ((float)toRect.x * uvTransform.x)) / (float)blurDescriptor.width; uvTransform.w = ((float)fromRect.y - ((float)toRect.y * uvTransform.y)) / (float)blurDescriptor.height; material.SetVector(kShaderPropertyUvTransforms[i0], uvTransform); combinedStrength *= Properties.IntensityMultiplier; } /* Composition */ float compositeStrengthSum = 0.0f; float compositeStrength = 1.0f; for (int i0 = 0; i0 < bloomRects.Length; ++i0) { compositeStrengthSum += compositeStrength; compositeStrength *= Properties.IntensityMultiplier; } compositeStrength = Properties.Intensity / compositeStrengthSum; for (int i0 = 0; i0 < bloomRectCount; ++i0) { var rect = bloomRects[i0]; material.SetFloat(rect.weightShaderPropertyId, compositeStrength); material.SetVector( rect.uvTransformShaderPropertyId, new Vector4( (float)rect.width / (float)blurDescriptor.width, (float)rect.height / (float)blurDescriptor.height, (float)rect.x / (float)blurDescriptor.width, (float)rect.y / (float)blurDescriptor.height)); compositeStrength *= Properties.IntensityMultiplier; } if (combinePassCount > 0) { var rect = bloomRects[bloomRectCount]; float weight = compositeStrength * combinedStrengthSum; material.SetFloat(kShaderPropertyBloomWeightCombined, weight); material.SetVector(kShaderPropertyBloomUvTransformCombined, new Vector4( (float)rect.width / (float)blurDescriptor.width, (float)rect.height / (float)blurDescriptor.height, (float)rect.x / (float)blurDescriptor.width, (float)rect.y / (float)blurDescriptor.height)); } } if ((updateFlags & BloomProperties.kChangeBrightnessExtractionMesh) != 0) { UpdateBrightnessExtractionMesh(); rebuild = true; } if ((updateFlags & BloomProperties.kChangeGaussianBlurMesh) != 0) { UpdateGaussianBlurHorizontalMesh(); UpdateGaussianBlurVerticalMesh(); rebuild = true; } if ((updateFlags & BloomProperties.kChangeCombineMesh) != 0) { if (combinePassCount > 0) { UpdateCombineMesh(); rebuild = true; } } return(rebuild); }