private static void DrawFill(OutlineParameters parameters, RenderTargetIdentifier targetSurfance) { parameters.Buffer.SetRenderTarget(targetSurfance, parameters.DepthTarget); if (parameters.CustomViewport.HasValue) { parameters.Buffer.SetViewport(parameters.CustomViewport.Value); } var singleMask = 1; var frontMask = 2; var backMask = 3; foreach (var outlinable in parameters.OutlinablesToRender) { if ((outlinable.DrawingMode & OutlinableDrawingMode.Normal) == 0) { continue; } if (outlinable.ComplexMaskingEnabled) { parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetBackKeyword(outlinable.ComplexMaskingMode)); } parameters.Buffer.SetGlobalInt(ZTestHash, (int)CompareFunction.Greater); foreach (var target in outlinable.OutlineTargets) { if (target.Renderer == null) { continue; } var renderer = target.Renderer; if (!renderer.gameObject.activeInHierarchy || !renderer.enabled) { continue; } SetupCutout(parameters, target); SetupCull(parameters, target); parameters.Buffer.SetGlobalInt(FillRefHash, backMask); parameters.Buffer.DrawRenderer(renderer, FillMaskMaterial, target.ShiftedSubmeshIndex); } if (outlinable.ComplexMaskingEnabled) { parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetBackKeyword(outlinable.ComplexMaskingMode)); } } foreach (var outlinable in parameters.OutlinablesToRender) { if ((outlinable.DrawingMode & OutlinableDrawingMode.Normal) == 0) { continue; } parameters.Buffer.SetGlobalInt(ZTestHash, (int)CompareFunction.LessEqual); foreach (var target in outlinable.OutlineTargets) { if (target.Renderer == null) { continue; } var renderer = target.Renderer; if (!renderer.gameObject.activeInHierarchy || !renderer.enabled) { continue; } SetupCutout(parameters, target); SetupCull(parameters, target); parameters.Buffer.SetGlobalInt(FillRefHash, frontMask); parameters.Buffer.DrawRenderer(renderer, FillMaskMaterial, target.ShiftedSubmeshIndex); } } foreach (var outlinable in parameters.OutlinablesToRender) { if ((outlinable.DrawingMode & OutlinableDrawingMode.Normal) == 0) { continue; } if (outlinable.RenderStyle == RenderStyle.FrontBack) { if ((outlinable.BackParameters.FillPass.Material == null || !outlinable.BackParameters.Enabled) && (outlinable.FrontParameters.FillPass.Material == null || !outlinable.FrontParameters.Enabled)) { continue; } var frontMaterial = outlinable.FrontParameters.FillPass.Material; parameters.Buffer.SetGlobalInt(FillRefHash, frontMask); if (frontMaterial != null && outlinable.FrontParameters.Enabled) { foreach (var target in outlinable.OutlineTargets) { if (target.Renderer == null) { continue; } var renderer = target.Renderer; if (!renderer.gameObject.activeInHierarchy || !renderer.enabled) { continue; } SetupCutout(parameters, target); SetupCull(parameters, target); parameters.Buffer.DrawRenderer(renderer, frontMaterial, target.ShiftedSubmeshIndex); } } var backMaterial = outlinable.BackParameters.FillPass.Material; parameters.Buffer.SetGlobalInt(FillRefHash, backMask); if (backMaterial != null && outlinable.BackParameters.Enabled) { foreach (var target in outlinable.OutlineTargets) { if (target.Renderer == null) { continue; } var renderer = target.Renderer; if (!renderer.gameObject.activeInHierarchy || !renderer.enabled) { continue; } SetupCutout(parameters, target); SetupCull(parameters, target); parameters.Buffer.DrawRenderer(renderer, backMaterial, target.ShiftedSubmeshIndex); } } } else { if (outlinable.OutlineParameters.FillPass.Material == null) { continue; } if (!outlinable.OutlineParameters.Enabled) { continue; } parameters.Buffer.SetGlobalInt(FillRefHash, singleMask); parameters.Buffer.SetGlobalInt(ZTestHash, (int)CompareFunction.Always); foreach (var target in outlinable.OutlineTargets) { if (target.Renderer == null) { continue; } var renderer = target.Renderer; if (!renderer.gameObject.activeInHierarchy || !renderer.enabled) { continue; } SetupCutout(parameters, target); SetupCull(parameters, target); parameters.Buffer.DrawRenderer(renderer, FillMaskMaterial, target.ShiftedSubmeshIndex); } parameters.Buffer.SetGlobalInt(FillRefHash, singleMask); var fillMaterial = outlinable.OutlineParameters.FillPass.Material; if (FillMaskMaterial != null) { foreach (var target in outlinable.OutlineTargets) { if (target.Renderer == null) { continue; } var renderer = target.Renderer; if (!renderer.gameObject.activeInHierarchy || !renderer.enabled) { continue; } SetupCutout(parameters, target); SetupCull(parameters, target); parameters.Buffer.DrawRenderer(renderer, fillMaterial, target.ShiftedSubmeshIndex); } } } } }
private static int DrawOutlineables(OutlineParameters parameters, CompareFunction function, bool edgeShiftOnly, float shift, Func <Outlinable, bool> shouldRender, Func <Outlinable, Color> colorProvider, Func <Outlinable, Material> materialProvider, RenderStyle styleMask, OutlinableDrawingMode modeMask = OutlinableDrawingMode.Normal) { var drawnCount = 0; parameters.Buffer.SetGlobalInt(ZTestHash, (int)function); foreach (var targetGroup in targets) { var outlinable = targetGroup.Outlinable; if ((int)(outlinable.RenderStyle & styleMask) == 0) { continue; } if ((int)(outlinable.DrawingMode & modeMask) == 0) { continue; } parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetBackKeyword(ComplexMaskingMode.MaskingMode)); parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetBackKeyword(ComplexMaskingMode.ObstaclesMode)); if (function == CompareFunction.NotEqual && outlinable.ComplexMaskingEnabled) { parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetBackKeyword(outlinable.ComplexMaskingMode)); } var color = shouldRender(outlinable) ? colorProvider(outlinable) : Color.clear; parameters.Buffer.SetGlobalColor(ColorHash, color); var target = targetGroup.Target; var postProcessing = !target.CanUseEdgeDilateShift || target.DilateRenderingMode == DilateRenderMode.PostProcessing; if (edgeShiftOnly && postProcessing) { continue; } if (!postProcessing) { var dilateShift = 0.0f; switch (function) { case CompareFunction.Always: dilateShift = target.EdgeDilateAmount; break; case CompareFunction.NotEqual: dilateShift = target.BackEdgeDilateAmount; break; case CompareFunction.LessEqual: dilateShift = target.FrontEdgeDilateAmount; break; } parameters.Buffer.SetGlobalFloat(DilateShiftHash, shift < 0.0f ? dilateShift : shift); } parameters.Buffer.SetGlobalInt(ColorMaskHash, postProcessing ? 255 : 0); SetupCutout(parameters, target); SetupCull(parameters, target); if (postProcessing || edgeShiftOnly) { drawnCount++; } var materialToUse = materialProvider(outlinable); parameters.Buffer.DrawRenderer(target.Renderer, materialToUse, target.ShiftedSubmeshIndex); } return(drawnCount); }