You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

164 lines
6.6 KiB

using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEditor.ShaderGraph.Internal;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
namespace UnityEditor.Rendering.HighDefinition
{
[SRPFilter(typeof(HDRenderPipeline))]
[FormerName("UnityEditor.Experimental.Rendering.HDPipeline.EmissionNode")]
[Title("Utility", "High Definition Render Pipeline", "Emission Node")]
class EmissionNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
{
public EmissionNode()
{
name = "Emission Node";
UpdateNodeAfterDeserialization();
}
public override string documentationURL => Documentation.GetPageLink("SGNode-Emission");
[SerializeField]
EmissiveIntensityUnit _intensityUnit;
[EnumControl]
EmissiveIntensityUnit intensityUnit
{
get { return _intensityUnit; }
set
{
_intensityUnit = value;
Dirty(ModificationScope.Node);
}
}
[SerializeField]
bool m_NormalizeColor;
[ToggleControl("Normalize Color")]
ToggleData normalizeColor
{
get { return new ToggleData(m_NormalizeColor); }
set
{
m_NormalizeColor = value.isOn;
Dirty(ModificationScope.Node);
}
}
const int kEmissionOutputSlotId = 0;
const int kEmissionColorInputSlotId = 1;
const int kEmissionIntensityInputSlotId = 2;
const int kEmissionExposureWeightInputSlotId = 3;
const string kEmissionOutputSlotName = "Output";
const string kEmissionColorInputSlotName = "Color";
const string kEmissionExpositionWeightInputSlotName = "Exposure Weight";
const string kEmissionIntensityInputSlotName = "Intensity";
public override bool hasPreview { get { return false; } }
ColorRGBMaterialSlot ldrColorSlot;
Vector1MaterialSlot intensitySlot;
public sealed override void UpdateNodeAfterDeserialization()
{
// Input slots:
ldrColorSlot = new ColorRGBMaterialSlot(kEmissionColorInputSlotId, kEmissionColorInputSlotName, kEmissionColorInputSlotName, SlotType.Input, Color.black, ColorMode.Default);
intensitySlot = new Vector1MaterialSlot(kEmissionIntensityInputSlotId, kEmissionIntensityInputSlotName, kEmissionIntensityInputSlotName, SlotType.Input, 1);
AddSlot(ldrColorSlot);
AddSlot(intensitySlot);
AddSlot(new Vector1MaterialSlot(kEmissionExposureWeightInputSlotId, kEmissionExpositionWeightInputSlotName, kEmissionExpositionWeightInputSlotName, SlotType.Input, 1));
// Output slot:kEmissionOutputSlotName
AddSlot(new ColorRGBMaterialSlot(kEmissionOutputSlotId, kEmissionOutputSlotName, kEmissionOutputSlotName, SlotType.Output, Color.black, ColorMode.HDR));
RemoveSlotsNameNotMatching(new[]
{
kEmissionOutputSlotId, kEmissionColorInputSlotId,
kEmissionIntensityInputSlotId, kEmissionExposureWeightInputSlotId
});
}
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var colorValue = GetSlotValue(kEmissionColorInputSlotId, generationMode);
var intensityValue = GetSlotValue(kEmissionIntensityInputSlotId, generationMode);
var exposureWeightValue = GetSlotValue(kEmissionExposureWeightInputSlotId, generationMode);
var outputValue = GetSlotValue(kEmissionOutputSlotId, generationMode);
if (intensityUnit == EmissiveIntensityUnit.EV100)
intensityValue = "ConvertEvToLuminance(" + intensityValue + ")";
sb.AppendLine(@"$precision3 {0} = {1}({2}.xyz, {3}, {4});",
outputValue,
GetFunctionName(),
colorValue,
intensityValue,
exposureWeightValue
);
}
string GetFunctionName()
{
return "Unity_HDRP_GetEmissionHDRColor_$precision";
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
// We may need ConvertEvToLuminance() so we include CommonLighting.hlsl
registry.RequiresIncludePath("Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl");
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("$precision3 {0}($precision3 ldrColor, {1} luminanceIntensity, {1} exposureWeight)",
GetFunctionName(),
intensitySlot.concreteValueType.ToShaderString());
using (s.BlockScope())
{
if (normalizeColor.isOn)
{
s.AppendLine("ldrColor = ldrColor * rcp(max(Luminance(ldrColor), 1e-6));");
}
s.AppendLine("$precision3 hdrColor = ldrColor * luminanceIntensity;");
s.AppendNewLine();
s.AppendLine("#ifdef SHADERGRAPH_PREVIEW");
s.AppendLine($"$precision inverseExposureMultiplier = 1.0;");
s.AppendLine("#else");
s.AppendLine($"$precision inverseExposureMultiplier = GetInverseCurrentExposureMultiplier();");
s.AppendLine("#endif");
s.AppendNewLine();
s.AppendLine("// Inverse pre-expose using _EmissiveExposureWeight weight");
s.AppendLine("hdrColor = lerp(hdrColor * inverseExposureMultiplier, hdrColor, exposureWeight);");
s.AppendLine("return hdrColor;");
}
});
}
Vector3 GetHDREmissionColor(Vector3 ldrColor, float intensity)
{
float multiplier = intensity;
if (intensityUnit == EmissiveIntensityUnit.EV100)
multiplier = LightUnitUtils.Ev100ToNits(intensity);
return ldrColor * intensity;
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
Vector3 outputColor = GetHDREmissionColor(ldrColorSlot.value, intensitySlot.value);
properties.Add(new PreviewProperty(PropertyType.Vector3)
{
name = GetVariableNameForSlot(kEmissionColorInputSlotId),
vector4Value = outputColor
});
}
}
}