void DrawCustomToneCurve() { EditorGUILayout.Space(); // Reserve GUI space using (new GUILayout.HorizontalScope()) { GUILayout.Space(EditorGUI.indentLevel * 15f); m_CustomToneCurveRect = GUILayoutUtility.GetRect(128, 80); } if (Event.current.type != EventType.Repaint) { return; } // Prepare curve data float toeStrength = m_ToneCurveToeStrength.value.floatValue; float toeLength = m_ToneCurveToeLength.value.floatValue; float shoulderStrength = m_ToneCurveShoulderStrength.value.floatValue; float shoulderLength = m_ToneCurveShoulderLength.value.floatValue; float shoulderAngle = m_ToneCurveShoulderAngle.value.floatValue; float gamma = m_ToneCurveGamma.value.floatValue; m_HableCurve.Init( toeStrength, toeLength, shoulderStrength, shoulderLength, shoulderAngle, gamma ); float endPoint = m_HableCurve.whitePoint; // Background m_RectVertices[0] = PointInRect(0f, 0f, endPoint); m_RectVertices[1] = PointInRect(endPoint, 0f, endPoint); m_RectVertices[2] = PointInRect(endPoint, k_CustomToneCurveRangeY, endPoint); m_RectVertices[3] = PointInRect(0f, k_CustomToneCurveRangeY, endPoint); Handles.DrawSolidRectangleWithOutline(m_RectVertices, Color.white * 0.1f, Color.white * 0.4f); // Vertical guides if (endPoint < m_CustomToneCurveRect.width / 3) { int steps = Mathf.CeilToInt(endPoint); for (var i = 1; i < steps; i++) { DrawLine(i, 0, i, k_CustomToneCurveRangeY, 0.4f, endPoint); } } // Label Handles.Label(m_CustomToneCurveRect.position + Vector2.right, "Custom Tone Curve", EditorStyles.miniLabel); // Draw the acual curve var vcount = 0; while (vcount < k_CustomToneCurveResolution) { float x = endPoint * vcount / (k_CustomToneCurveResolution - 1); float y = m_HableCurve.Eval(x); if (y < k_CustomToneCurveRangeY) { m_CurveVertices[vcount++] = PointInRect(x, y, endPoint); } else { if (vcount > 1) { // Extend the last segment to the top edge of the rect. var v1 = m_CurveVertices[vcount - 2]; var v2 = m_CurveVertices[vcount - 1]; var clip = (m_CustomToneCurveRect.y - v1.y) / (v2.y - v1.y); m_CurveVertices[vcount - 1] = v1 + (v2 - v1) * clip; } break; } } if (vcount > 1) { Handles.color = Color.white * 0.9f; Handles.DrawAAPolyLine(2f, vcount, m_CurveVertices); } }
public override void OnInspectorGUI() { PropertyField(m_Mode); // Draw a curve for the custom tonemapping mode to make it easier to tweak visually if (m_Mode.value.intValue == (int)TonemappingMode.Custom) { EditorGUILayout.Space(); // Reserve GUI space using (new GUILayout.HorizontalScope()) { GUILayout.Space(EditorGUI.indentLevel * 15f); m_CurveRect = GUILayoutUtility.GetRect(128, 80); } if (Event.current.type == EventType.Repaint) { // Prepare curve data float toeStrength = m_ToeStrength.value.floatValue; float toeLength = m_ToeLength.value.floatValue; float shoulderStrength = m_ShoulderStrength.value.floatValue; float shoulderLength = m_ShoulderLength.value.floatValue; float shoulderAngle = m_ShoulderAngle.value.floatValue; float gamma = m_Gamma.value.floatValue; m_HableCurve.Init( toeStrength, toeLength, shoulderStrength, shoulderLength, shoulderAngle, gamma ); float alpha = GUI.enabled ? 1f : 0.5f; m_Material.SetVector(HDShaderIDs._CustomToneCurve, m_HableCurve.uniforms.curve); m_Material.SetVector(HDShaderIDs._ToeSegmentA, m_HableCurve.uniforms.toeSegmentA); m_Material.SetVector(HDShaderIDs._ToeSegmentB, m_HableCurve.uniforms.toeSegmentB); m_Material.SetVector(HDShaderIDs._MidSegmentA, m_HableCurve.uniforms.midSegmentA); m_Material.SetVector(HDShaderIDs._MidSegmentB, m_HableCurve.uniforms.midSegmentB); m_Material.SetVector(HDShaderIDs._ShoSegmentA, m_HableCurve.uniforms.shoSegmentA); m_Material.SetVector(HDShaderIDs._ShoSegmentB, m_HableCurve.uniforms.shoSegmentB); m_Material.SetVector(HDShaderIDs._Variants, new Vector4(alpha, m_HableCurve.whitePoint, 0f, 0f)); CheckCurveRT((int)m_CurveRect.width, (int)m_CurveRect.height); var oldRt = RenderTexture.active; Graphics.Blit(null, m_CurveTex, m_Material, EditorGUIUtility.isProSkin ? 0 : 1); RenderTexture.active = oldRt; GUI.DrawTexture(m_CurveRect, m_CurveTex); Handles.DrawSolidRectangleWithOutline(m_CurveRect, Color.clear, Color.white * 0.4f); } PropertyField(m_ToeStrength); PropertyField(m_ToeLength); PropertyField(m_ShoulderStrength); PropertyField(m_ShoulderLength); PropertyField(m_ShoulderAngle); PropertyField(m_Gamma); } else if (m_Mode.value.intValue == (int)TonemappingMode.External) { PropertyField(m_LutTexture, EditorGUIUtility.TrTextContent("Lookup Texture")); var lut = m_LutTexture.value.objectReferenceValue; if (lut != null && !((Tonemapping)target).ValidateLUT()) { EditorGUILayout.HelpBox("Invalid lookup texture. It must be a 3D texture or render texture with the same size as set in the HDRP settings.", MessageType.Warning); } PropertyField(m_LutContribution, EditorGUIUtility.TrTextContent("Contribution")); EditorGUILayout.HelpBox("Use \"Edit > Rendering > Render Selected HDRP Camera to Log EXR\" to export a log-encoded frame for external grading.", MessageType.Info); } }
private void RenderHDRPipeline3D(PostProcessRenderContext context) { CheckInternalLogLut(); ComputeShader lut3DBaker = context.resources.computeShaders.lut3DBaker; int kernelIndex = 0; switch (base.settings.tonemapper.value) { case Tonemapper.None: kernelIndex = lut3DBaker.FindKernel("KGenLut3D_NoTonemap"); break; case Tonemapper.Neutral: kernelIndex = lut3DBaker.FindKernel("KGenLut3D_NeutralTonemap"); break; case Tonemapper.ACES: kernelIndex = lut3DBaker.FindKernel("KGenLut3D_AcesTonemap"); break; case Tonemapper.Custom: kernelIndex = lut3DBaker.FindKernel("KGenLut3D_CustomTonemap"); break; } CommandBuffer command = context.command; command.SetComputeTextureParam(lut3DBaker, kernelIndex, "_Output", m_InternalLogLut); command.SetComputeVectorParam(lut3DBaker, "_Size", new Vector4(33f, 0.03125f, 0f, 0f)); Vector3 v = ColorUtilities.ComputeColorBalance(base.settings.temperature.value, base.settings.tint.value); command.SetComputeVectorParam(lut3DBaker, "_ColorBalance", v); command.SetComputeVectorParam(lut3DBaker, "_ColorFilter", base.settings.colorFilter.value); float x = base.settings.hueShift.value / 360f; float y = base.settings.saturation.value / 100f + 1f; float z = base.settings.contrast.value / 100f + 1f; command.SetComputeVectorParam(lut3DBaker, "_HueSatCon", new Vector4(x, y, z, 0f)); Vector4 a = new Vector4(base.settings.mixerRedOutRedIn, base.settings.mixerRedOutGreenIn, base.settings.mixerRedOutBlueIn, 0f); Vector4 a2 = new Vector4(base.settings.mixerGreenOutRedIn, base.settings.mixerGreenOutGreenIn, base.settings.mixerGreenOutBlueIn, 0f); Vector4 a3 = new Vector4(base.settings.mixerBlueOutRedIn, base.settings.mixerBlueOutGreenIn, base.settings.mixerBlueOutBlueIn, 0f); command.SetComputeVectorParam(lut3DBaker, "_ChannelMixerRed", a / 100f); command.SetComputeVectorParam(lut3DBaker, "_ChannelMixerGreen", a2 / 100f); command.SetComputeVectorParam(lut3DBaker, "_ChannelMixerBlue", a3 / 100f); Vector3 vector = ColorUtilities.ColorToLift(base.settings.lift.value * 0.2f); Vector3 vector2 = ColorUtilities.ColorToGain(base.settings.gain.value * 0.8f); Vector3 vector3 = ColorUtilities.ColorToInverseGamma(base.settings.gamma.value * 0.8f); command.SetComputeVectorParam(lut3DBaker, "_Lift", new Vector4(vector.x, vector.y, vector.z, 0f)); command.SetComputeVectorParam(lut3DBaker, "_InvGamma", new Vector4(vector3.x, vector3.y, vector3.z, 0f)); command.SetComputeVectorParam(lut3DBaker, "_Gain", new Vector4(vector2.x, vector2.y, vector2.z, 0f)); command.SetComputeTextureParam(lut3DBaker, kernelIndex, "_Curves", GetCurveTexture(hdr: true)); if (base.settings.tonemapper.value == Tonemapper.Custom) { m_HableCurve.Init(base.settings.toneCurveToeStrength.value, base.settings.toneCurveToeLength.value, base.settings.toneCurveShoulderStrength.value, base.settings.toneCurveShoulderLength.value, base.settings.toneCurveShoulderAngle.value, base.settings.toneCurveGamma.value); command.SetComputeVectorParam(lut3DBaker, "_CustomToneCurve", m_HableCurve.uniforms.curve); command.SetComputeVectorParam(lut3DBaker, "_ToeSegmentA", m_HableCurve.uniforms.toeSegmentA); command.SetComputeVectorParam(lut3DBaker, "_ToeSegmentB", m_HableCurve.uniforms.toeSegmentB); command.SetComputeVectorParam(lut3DBaker, "_MidSegmentA", m_HableCurve.uniforms.midSegmentA); command.SetComputeVectorParam(lut3DBaker, "_MidSegmentB", m_HableCurve.uniforms.midSegmentB); command.SetComputeVectorParam(lut3DBaker, "_ShoSegmentA", m_HableCurve.uniforms.shoSegmentA); command.SetComputeVectorParam(lut3DBaker, "_ShoSegmentB", m_HableCurve.uniforms.shoSegmentB); } context.command.BeginSample("HdrColorGradingLut3D"); int num = Mathf.CeilToInt(8.25f); command.DispatchCompute(lut3DBaker, kernelIndex, num, num, num); context.command.EndSample("HdrColorGradingLut3D"); RenderTexture internalLogLut = m_InternalLogLut; PropertySheet uberSheet = context.uberSheet; uberSheet.EnableKeyword("COLOR_GRADING_HDR_3D"); uberSheet.properties.SetTexture(ShaderIDs.Lut3D, internalLogLut); uberSheet.properties.SetVector(ShaderIDs.Lut3D_Params, new Vector2(1f / (float)internalLogLut.width, (float)internalLogLut.width - 1f)); uberSheet.properties.SetFloat(ShaderIDs.PostExposure, RuntimeUtilities.Exp2(base.settings.postExposure.value)); context.logLut = internalLogLut; }
public override void OnInspectorGUI() { PropertyField(m_Mode); // Draw a curve for the custom tonemapping mode to make it easier to tweak visually if (m_Mode.value.intValue == (int)TonemappingMode.Custom) { EditorGUILayout.Space(); // Reserve GUI space using (new GUILayout.HorizontalScope()) { GUILayout.Space(EditorGUI.indentLevel * 15f); m_CurveRect = GUILayoutUtility.GetRect(128, 80); } if (Event.current.type == EventType.Repaint) { // Prepare curve data float toeStrength = m_ToeStrength.value.floatValue; float toeLength = m_ToeLength.value.floatValue; float shoulderStrength = m_ShoulderStrength.value.floatValue; float shoulderLength = m_ShoulderLength.value.floatValue; float shoulderAngle = m_ShoulderAngle.value.floatValue; float gamma = m_Gamma.value.floatValue; m_HableCurve.Init( toeStrength, toeLength, shoulderStrength, shoulderLength, shoulderAngle, gamma ); float alpha = GUI.enabled ? 1f : 0.5f; m_Material.SetVector(HDShaderIDs._CustomToneCurve, m_HableCurve.uniforms.curve); m_Material.SetVector(HDShaderIDs._ToeSegmentA, m_HableCurve.uniforms.toeSegmentA); m_Material.SetVector(HDShaderIDs._ToeSegmentB, m_HableCurve.uniforms.toeSegmentB); m_Material.SetVector(HDShaderIDs._MidSegmentA, m_HableCurve.uniforms.midSegmentA); m_Material.SetVector(HDShaderIDs._MidSegmentB, m_HableCurve.uniforms.midSegmentB); m_Material.SetVector(HDShaderIDs._ShoSegmentA, m_HableCurve.uniforms.shoSegmentA); m_Material.SetVector(HDShaderIDs._ShoSegmentB, m_HableCurve.uniforms.shoSegmentB); m_Material.SetVector(HDShaderIDs._Variants, new Vector4(alpha, m_HableCurve.whitePoint, 0f, 0f)); CheckCurveRT((int)m_CurveRect.width, (int)m_CurveRect.height); var oldRt = RenderTexture.active; Graphics.Blit(null, m_CurveTex, m_Material, EditorGUIUtility.isProSkin ? 0 : 1); RenderTexture.active = oldRt; GUI.DrawTexture(m_CurveRect, m_CurveTex); Handles.DrawSolidRectangleWithOutline(m_CurveRect, Color.clear, Color.white * 0.4f); } PropertyField(m_ToeStrength); PropertyField(m_ToeLength); PropertyField(m_ShoulderStrength); PropertyField(m_ShoulderLength); PropertyField(m_ShoulderAngle); PropertyField(m_Gamma); } }
public override void OnInspectorGUI() { bool hdrInPlayerSettings = UnityEditor.PlayerSettings.useHDRDisplay; PropertyField(m_Mode); // Draw a curve for the custom tonemapping mode to make it easier to tweak visually if (m_Mode.value.intValue == (int)TonemappingMode.Custom) { EditorGUILayout.Space(); // Reserve GUI space m_CurveRect = GUILayoutUtility.GetRect(128, 80); m_CurveRect.xMin += EditorGUI.indentLevel * 15f; if (Event.current.type == EventType.Repaint) { // Prepare curve data float toeStrength = m_ToeStrength.value.floatValue; float toeLength = m_ToeLength.value.floatValue; float shoulderStrength = m_ShoulderStrength.value.floatValue; float shoulderLength = m_ShoulderLength.value.floatValue; float shoulderAngle = m_ShoulderAngle.value.floatValue; float gamma = m_Gamma.value.floatValue; m_HableCurve.Init( toeStrength, toeLength, shoulderStrength, shoulderLength, shoulderAngle, gamma ); float alpha = GUI.enabled ? 1f : 0.5f; m_Material.SetVector(HDShaderIDs._CustomToneCurve, m_HableCurve.uniforms.curve); m_Material.SetVector(HDShaderIDs._ToeSegmentA, m_HableCurve.uniforms.toeSegmentA); m_Material.SetVector(HDShaderIDs._ToeSegmentB, m_HableCurve.uniforms.toeSegmentB); m_Material.SetVector(HDShaderIDs._MidSegmentA, m_HableCurve.uniforms.midSegmentA); m_Material.SetVector(HDShaderIDs._MidSegmentB, m_HableCurve.uniforms.midSegmentB); m_Material.SetVector(HDShaderIDs._ShoSegmentA, m_HableCurve.uniforms.shoSegmentA); m_Material.SetVector(HDShaderIDs._ShoSegmentB, m_HableCurve.uniforms.shoSegmentB); m_Material.SetVector(HDShaderIDs._Variants, new Vector4(alpha, m_HableCurve.whitePoint, 0f, 0f)); CheckCurveRT((int)m_CurveRect.width, (int)m_CurveRect.height); var oldRt = RenderTexture.active; Graphics.Blit(null, m_CurveTex, m_Material, EditorGUIUtility.isProSkin ? 0 : 1); RenderTexture.active = oldRt; GUI.DrawTexture(m_CurveRect, m_CurveTex); Handles.DrawSolidRectangleWithOutline(m_CurveRect, Color.clear, Color.white * 0.4f); } PropertyField(m_ToeStrength); PropertyField(m_ToeLength); PropertyField(m_ShoulderStrength); PropertyField(m_ShoulderLength); PropertyField(m_ShoulderAngle); PropertyField(m_Gamma); } else if (m_Mode.value.intValue == (int)TonemappingMode.External) { PropertyField(m_LutTexture, EditorGUIUtility.TrTextContent("Lookup Texture")); var lut = m_LutTexture.value.objectReferenceValue; if (lut != null && !((Tonemapping)target).ValidateLUT()) { EditorGUILayout.HelpBox("Invalid lookup texture. It must be a 3D Texture or a Render Texture and have the same size as set in the HDRP settings.", MessageType.Warning); } PropertyField(m_LutContribution, EditorGUIUtility.TrTextContent("Contribution")); EditorGUILayout.HelpBox("Use \"Edit > Rendering > Render Selected HDRP Camera to Log EXR\" to export a log-encoded frame for external grading.", MessageType.Info); } else if (m_Mode.value.intValue == (int)TonemappingMode.ACES) { PropertyField(m_UseFullACES); } if (hdrInPlayerSettings && m_Mode.value.intValue != (int)TonemappingMode.None) { EditorGUILayout.LabelField("HDR Output"); int hdrTonemapMode = m_Mode.value.intValue; if (m_Mode.value.intValue == (int)TonemappingMode.Custom || hdrTonemapMode == (int)TonemappingMode.External) { EditorGUILayout.HelpBox("The selected tonemapping mode is not supported in HDR Output mode. Select a fallback mode.", MessageType.Warning); PropertyField(m_HDRFallbackMode); hdrTonemapMode = (m_HDRFallbackMode.value.intValue == (int)FallbackHDRTonemap.ACES) ? (int)TonemappingMode.ACES : (m_HDRFallbackMode.value.intValue == (int)FallbackHDRTonemap.Neutral) ? (int)TonemappingMode.Neutral : (int)TonemappingMode.None; } if (hdrTonemapMode == (int)TonemappingMode.Neutral) { PropertyField(m_NeutralHDRRangeReductionMode); PropertyField(m_HueShiftAmount); PropertyField(m_HDRDetectPaperWhite); EditorGUI.indentLevel++; using (new EditorGUI.DisabledScope(m_HDRDetectPaperWhite.value.boolValue)) { PropertyField(m_HDRPaperwhite); } EditorGUI.indentLevel--; PropertyField(m_HDRDetectNitLimits); EditorGUI.indentLevel++; using (new EditorGUI.DisabledScope(m_HDRDetectNitLimits.value.boolValue)) { PropertyField(m_HDRMinNits); PropertyField(m_HDRMaxNits); } EditorGUI.indentLevel--; } if (hdrTonemapMode == (int)TonemappingMode.ACES) { PropertyField(m_HDRAcesPreset); PropertyField(m_HDRDetectPaperWhite); EditorGUI.indentLevel++; using (new EditorGUI.DisabledScope(m_HDRDetectPaperWhite.value.boolValue)) { PropertyField(m_HDRPaperwhite); } EditorGUI.indentLevel--; } } }