diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 9fdde1f36a6..e6c294747d6 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed missing DisallowMultipleComponent annotations in HDAdditionalReflectionData and HDAdditionalLightData (case 1365879). - Fixed support for light/shadow dimmers (volumetric or not) in path tracing. - Fixed ambient occlusion strenght incorrectly using GTAOMultiBounce +- Fixed emissive value when switching between HDR and LDR mode. ## [12.0.0] - 2021-01-11 diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceInputsUIBlock.cs b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceInputsUIBlock.cs index cd5b428e3d8..69ee6b73fe0 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceInputsUIBlock.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceInputsUIBlock.cs @@ -281,18 +281,24 @@ protected override void OnGUIOpen() if (useEmissiveIntensity.floatValue == 0.0f) { + if (updateEmissiveColor) + emissiveColorHDR.colorValue = emissiveColor.colorValue; + EditorGUI.BeginChangeCheck(); EmissionUIBlock.DoEmissiveTextureProperty(materialEditor, emissiveColorMap, emissiveColorHDR); - if (EditorGUI.EndChangeCheck() || updateEmissiveColor) + if (EditorGUI.EndChangeCheck()) emissiveColor.colorValue = emissiveColorHDR.colorValue; } else { + if (updateEmissiveColor) + EmissionUIBlock.UpdateEmissiveColorLDRAndIntensityFromEmissiveColor(emissiveColorLDR, emissiveIntensity, emissiveColor); + EditorGUI.BeginChangeCheck(); EmissionUIBlock.DoEmissiveTextureProperty(materialEditor, emissiveColorMap, emissiveColorLDR); EmissionUIBlock.DoEmissiveIntensityGUI(materialEditor, emissiveIntensity, emissiveIntensityUnit); if (EditorGUI.EndChangeCheck() || updateEmissiveColor) - EmissionUIBlock.UpdateEmissiveColorFromIntensityAndEmissiveColorLDR(materialEditor, materials); + EmissionUIBlock.UpdateEmissiveColorFromIntensityAndEmissiveColorLDR(emissiveColorLDR, emissiveIntensity, emissiveColor); } materialEditor.ShaderProperty(emissiveExposureWeight, Styles.emissiveExposureWeightText); diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/EmissionUIBlock.cs b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/EmissionUIBlock.cs index 65b4581012c..c7cd0bdf8d3 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/EmissionUIBlock.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/EmissionUIBlock.cs @@ -108,33 +108,40 @@ public override void LoadMaterialProperties() UVMappingMaskEmissive = FindProperty(kUVMappingMaskEmissive); } - internal static void UpdateEmissiveColorFromIntensityAndEmissiveColorLDR(MaterialEditor materialEditor, Material[] materials) - { - materialEditor.serializedObject.ApplyModifiedProperties(); - foreach (Material target in materials) - { - target.UpdateEmissiveColorFromIntensityAndEmissiveColorLDR(); - } - materialEditor.serializedObject.Update(); - } - internal static void UpdateEmissiveColorFromIntensityAndEmissiveColorLDR(MaterialProperty emissiveColorLDR, MaterialProperty emissiveIntensity, MaterialProperty emissiveColor) => emissiveColor.colorValue = emissiveColorLDR.colorValue.linear * emissiveIntensity.floatValue; - internal static void UpdateEmissiveColorLDRFromIntensityAndEmissiveColor(MaterialEditor materialEditor, Material[] materials) + internal static void UpdateEmissiveColorLDRAndIntensityFromEmissiveColor(MaterialProperty emissiveColorLDR, MaterialProperty emissiveIntensity, MaterialProperty emissiveColor) { - materialEditor.serializedObject.ApplyModifiedProperties(); - foreach (Material target in materials) + // specifies the max byte value to use when decomposing a float color into bytes with exposure + // this is the value used by Photoshop + const byte k_MaxByteForOverexposedColor = 191; + + float intensity = 1f; + Color colorHDR = emissiveColor.colorValue; + Color colorLDR = colorHDR; + + var maxColorComponent = emissiveColor.colorValue.maxColorComponent; + if (maxColorComponent != 0f) { - target.UpdateEmissiveColorLDRFromIntensityAndEmissiveColor(); + int maxColorComponentIndex = 0; + if (colorLDR.r > colorLDR.g) maxColorComponentIndex = colorLDR.r > colorLDR.b ? 0 : 2; + if (colorLDR.g > colorLDR.r) maxColorComponentIndex = colorLDR.g > colorLDR.b ? 1 : 2; + + // calibrate exposure to the max float color component + var scaleFactor = k_MaxByteForOverexposedColor / maxColorComponent; + + // maintain maximal integrity of byte values to prevent off-by-one errors when scaling up a color one component at a time + colorLDR.r = Math.Min(k_MaxByteForOverexposedColor, (byte)Mathf.CeilToInt(scaleFactor * colorHDR.r)) / 255f; + colorLDR.g = Math.Min(k_MaxByteForOverexposedColor, (byte)Mathf.CeilToInt(scaleFactor * colorHDR.g)) / 255f; + colorLDR.b = Math.Min(k_MaxByteForOverexposedColor, (byte)Mathf.CeilToInt(scaleFactor * colorHDR.b)) / 255f; + + intensity = colorHDR[maxColorComponentIndex] / colorLDR[maxColorComponentIndex]; } - materialEditor.serializedObject.Update(); - } - internal static void UpdateEmissiveColorLDRFromIntensityAndEmissiveColor(MaterialProperty emissiveColorLDR, MaterialProperty emissiveIntensity, MaterialProperty emissiveColor) - { - Color emissiveColorLDRLinear = emissiveColor.colorValue / emissiveIntensity.floatValue; - emissiveColorLDR.colorValue = emissiveColorLDRLinear.gamma; + colorLDR.a = 1.0f; + emissiveIntensity.floatValue = intensity; + emissiveColorLDR.colorValue = colorLDR.gamma; } internal static void DoEmissiveIntensityGUI(MaterialEditor materialEditor, MaterialProperty emissiveIntensity, MaterialProperty emissiveIntensityUnit) @@ -205,7 +212,7 @@ protected override void OnGUIOpen() else { if (updateEmissiveColor) - UpdateEmissiveColorLDRFromIntensityAndEmissiveColor(emissiveColorLDR, emissiveIntensity, emissiveColor); + UpdateEmissiveColorLDRAndIntensityFromEmissiveColor(emissiveColorLDR, emissiveIntensity, emissiveColor); EditorGUI.BeginChangeCheck(); DoEmissiveTextureProperty(emissiveColorLDR); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs index daa814b4288..02c10339bae 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs @@ -189,19 +189,5 @@ public static void UpdateEmissiveColorFromIntensityAndEmissiveColorLDR(this Mate material.SetColor(kEmissiveColor, emissiveColorLDRLinear * material.GetFloat(kEmissiveIntensity)); } } - - public static void UpdateEmissiveColorLDRFromIntensityAndEmissiveColor(this Material material) - { - const string kEmissiveColorLDR = "_EmissiveColorLDR"; - const string kEmissiveColor = "_EmissiveColor"; - const string kEmissiveIntensity = "_EmissiveIntensity"; - - if (material.HasProperty(kEmissiveColorLDR) && material.HasProperty(kEmissiveIntensity) && material.HasProperty(kEmissiveColor)) - { - Color emissiveColorLDRLinear = material.GetColor(kEmissiveColor) / material.GetFloat(kEmissiveIntensity); - Color emissiveColorLDR = new Color(Mathf.LinearToGammaSpace(emissiveColorLDRLinear.r), Mathf.LinearToGammaSpace(emissiveColorLDRLinear.g), Mathf.LinearToGammaSpace(emissiveColorLDRLinear.b)); - material.SetColor(kEmissiveColorLDR, emissiveColorLDR); - } - } } }