void UpdateRenderingPassValue(HDRenderQueue.RenderQueueType newValue) { HDRenderQueue.RenderQueueType renderingPass; switch (m_Node.surfaceType) { case SurfaceType.Opaque: renderingPass = HDRenderQueue.GetOpaqueEquivalent(newValue); break; case SurfaceType.Transparent: renderingPass = HDRenderQueue.GetTransparentEquivalent(newValue); break; default: throw new ArgumentException("Unknown SurfaceType"); } if (Equals(m_Node.renderingPass, renderingPass)) { return; } m_Node.owner.owner.RegisterCompleteObjectUndo("Rendering Pass Change"); m_Node.renderingPass = renderingPass; }
protected static void ResetMaterialCustomRenderQueue(Material material) { HDRenderQueue.RenderQueueType targetQueueType; switch (material.GetSurfaceType()) { case SurfaceType.Opaque: targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; case SurfaceType.Transparent: targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; default: throw new ArgumentException("Unknown SurfaceType"); } // Decal doesn't have properties to compute the render queue if (material.HasProperty(kTransparentSortPriority) && material.HasProperty(kAlphaCutoffEnabled)) { float sortingPriority = material.GetFloat(kTransparentSortPriority); bool alphaTest = material.GetFloat(kAlphaCutoffEnabled) > 0.5f; bool decalEnable = material.HasProperty(kEnableDecals) && material.GetFloat(kEnableDecals) > 0.0f; material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)sortingPriority, alphaTest, decalEnable); } }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // DecalSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("3b523fb79ded88842bb5195be78e0354")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as DecalMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { // Add tags at the SubShader level int queue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Opaque, masterNode.drawOrder, false); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.Opaque, queue); // Caution: Order of GenerateShaderPass matter. Only generate required pass if (masterNode.affectsAlbedo.isOn || masterNode.affectsNormal.isOn || masterNode.affectsMetal.isOn || masterNode.affectsAO.isOn || masterNode.affectsSmoothness.isOn) { GenerateShaderPass(masterNode, m_PassProjector3RT, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPass(masterNode, m_PassProjector4RT, mode, subShader, sourceAssetDependencyPaths); } if (masterNode.affectsEmission.isOn) { GenerateShaderPass(masterNode, m_PassProjectorEmissive, mode, subShader, sourceAssetDependencyPaths); } if (masterNode.affectsAlbedo.isOn || masterNode.affectsNormal.isOn || masterNode.affectsMetal.isOn || masterNode.affectsAO.isOn || masterNode.affectsSmoothness.isOn) { GenerateShaderPass(masterNode, m_PassMesh3RT, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPass(masterNode, m_PassMesh4RT, mode, subShader, sourceAssetDependencyPaths); } if (masterNode.affectsEmission.isOn) { GenerateShaderPass(masterNode, m_PassMeshEmissive, mode, subShader, sourceAssetDependencyPaths); } if (mode.IsPreview()) { GenerateShaderPass(masterNode, m_PassPreview, mode, subShader, sourceAssetDependencyPaths); } } subShader.Deindent(); subShader.AddShaderChunk("}", true); if (!masterNode.OverrideEnabled) { subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.DecalGUI"""); } string s = subShader.GetShaderString(0); return(s); }
private int GetRenderQueueOffset() { var renderQueueType = GetRenderQueueType(); var materialSortingPriority = GetMaterialSortingPriority(); return(owner is VFXDecalHDRPOutput? HDRenderQueue.Clamps(k_RenderQueue_AllOpaque, ChangeType(renderQueueType, 0, owner.hasAlphaClipping) + materialSortingPriority) : ChangeType(renderQueueType, materialSortingPriority, owner.hasAlphaClipping)); }
void UpgradeHDUnlitMasterNode(HDUnlitMasterNode1 hdUnlitMasterNode, out Dictionary <BlockFieldDescriptor, int> blockMap) { m_MigrateFromOldSG = true; // Set data systemData.surfaceType = (SurfaceType)hdUnlitMasterNode.m_SurfaceType; systemData.blendMode = HDSubShaderUtilities.UpgradeLegacyAlphaModeToBlendMode((int)hdUnlitMasterNode.m_AlphaMode); systemData.renderQueueType = HDRenderQueue.MigrateRenderQueueToHDRP10(hdUnlitMasterNode.m_RenderingPass); // Patch rendering pass in case the master node had an old configuration if (systemData.renderQueueType == HDRenderQueue.RenderQueueType.Background) { systemData.renderQueueType = HDRenderQueue.RenderQueueType.Opaque; } systemData.alphaTest = hdUnlitMasterNode.m_AlphaTest; systemData.sortPriority = hdUnlitMasterNode.m_SortPriority; systemData.doubleSidedMode = hdUnlitMasterNode.m_DoubleSided ? DoubleSidedMode.Enabled : DoubleSidedMode.Disabled; systemData.transparentZWrite = hdUnlitMasterNode.m_ZWrite; systemData.transparentCullMode = hdUnlitMasterNode.m_transparentCullMode; systemData.zTest = hdUnlitMasterNode.m_ZTest; systemData.dotsInstancing = hdUnlitMasterNode.m_DOTSInstancing; builtinData.transparencyFog = hdUnlitMasterNode.m_TransparencyFog; builtinData.distortion = hdUnlitMasterNode.m_Distortion; builtinData.distortionMode = hdUnlitMasterNode.m_DistortionMode; builtinData.distortionDepthTest = hdUnlitMasterNode.m_DistortionDepthTest; builtinData.alphaToMask = hdUnlitMasterNode.m_AlphaToMask; builtinData.addPrecomputedVelocity = hdUnlitMasterNode.m_AddPrecomputedVelocity; unlitData.distortionOnly = hdUnlitMasterNode.m_DistortionOnly; unlitData.enableShadowMatte = hdUnlitMasterNode.m_EnableShadowMatte; target.customEditorGUI = hdUnlitMasterNode.m_OverrideEnabled ? hdUnlitMasterNode.m_ShaderGUIOverride : ""; // Set blockmap blockMap = new Dictionary <BlockFieldDescriptor, int>() { { BlockFields.VertexDescription.Position, 9 }, { BlockFields.VertexDescription.Normal, 13 }, { BlockFields.VertexDescription.Tangent, 14 }, { BlockFields.SurfaceDescription.BaseColor, 0 }, { BlockFields.SurfaceDescription.Alpha, 7 }, { BlockFields.SurfaceDescription.AlphaClipThreshold, 8 }, { BlockFields.SurfaceDescription.Emission, 12 }, }; // Distortion if (systemData.surfaceType == SurfaceType.Transparent && builtinData.distortion) { blockMap.Add(HDBlockFields.SurfaceDescription.Distortion, 10); blockMap.Add(HDBlockFields.SurfaceDescription.DistortionBlur, 11); } // Shadow Matte if (unlitData.enableShadowMatte) { blockMap.Add(HDBlockFields.SurfaceDescription.ShadowTint, 15); } }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // StackLitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("9649efe3e0e8e2941a983bb0f3a034ad")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as StackLitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { // Add tags at the SubShader level var renderingPass = masterNode.surfaceType == SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent; int queue = HDRenderQueue.ChangeType(renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue); // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool distortionActive = transparent && masterNode.distortion.isOn; GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); if (distortionActive) { GenerateShaderPassLit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths); } // Assign define here based on opaque or transparent to save some variant m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent; GenerateShaderPassLit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", true); if (!masterNode.OverrideEnabled) { subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.StackLitGUI"""); } return(subShader.GetShaderString(0)); }
void ChangeSortPriority(ChangeEvent<int> evt) { m_Node.sortPriority = HDRenderQueue.ClampsTransparentRangePriority(evt.newValue); // Force the text to match. m_SortPiorityField.value = m_Node.sortPriority; if (Equals(m_Node.sortPriority, evt.newValue)) return; m_Node.owner.owner.RegisterCompleteObjectUndo("Sort Priority Change"); }
private RenderQueueType GetRenderQueueType() { RenderQueueType renderQueueType; if (owner.isBlendModeOpaque) { renderQueueType = HDRenderQueue.ConvertFromOpaqueRenderQueue(opaqueRenderQueue); } else { renderQueueType = HDRenderQueue.ConvertFromTransparentRenderQueue(transparentRenderQueue); } return(renderQueueType); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HDUnlitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("1c44ec077faa54145a89357de68e5d26")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HDUnlitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { // Add tags at the SubShader level int queue = HDRenderQueue.ChangeType(masterNode.renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDUnlitShader, queue); // For preview only we generate the passes that are enabled bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool distortionActive = transparent && masterNode.distortion.isOn; GenerateShaderPassUnlit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); if (distortionActive) { GenerateShaderPassUnlit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths); } GenerateShaderPassUnlit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", true); subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HDUnlitGUI"""); return(subShader.GetShaderString(0)); }
void AddTags(ShaderGenerator generator, string pipeline, HDRenderTypeTags renderType, PBRMasterNode masterNode) { var type = masterNode.surfaceType == ShaderGraph.SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent; string queue = HDRenderQueue.GetShaderTagValue(HDRenderQueue.ChangeType(type, 0, true)); ShaderStringBuilder builder = new ShaderStringBuilder(); builder.AppendLine("Tags"); using (builder.BlockScope()) { builder.AppendLine("\"RenderPipeline\"=\"{0}\"", pipeline); builder.AppendLine("\"RenderType\"=\"{0}\"", renderType); builder.AppendLine("\"Queue\"=\"{0}\"", queue); } generator.AddShaderChunk(builder.ToString()); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // UnlitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("a32a2cf536cae8e478ca1bbb7b9c493b")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as UnlitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { var renderingPass = masterNode.surfaceType == ShaderGraph.SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent; int queue = HDRenderQueue.ChangeType(renderingPass, 0, true); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDUnlitShader, queue); // generate the necessary shader passes bool opaque = (masterNode.surfaceType == ShaderGraph.SurfaceType.Opaque); GenerateShaderPassUnlit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); if (opaque) { GenerateShaderPassUnlit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); } GenerateShaderPassUnlit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", true); if (!masterNode.OverrideEnabled) { subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.UnlitUI"""); } return(subShader.GetShaderString(0)); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // FabricSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("059cc3132f0336e40886300f3d2d7f12")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as FabricMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; // Add tags at the SubShader level var renderingPass = masterNode.surfaceType == SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent; int queue = HDRenderQueue.ChangeType(renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue); GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); // Assign define here based on opaque or transparent to save some variant m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent; GenerateShaderPassLit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", true); subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.FabricGUI"""); return(subShader.GetShaderString(0)); }
public override string GetRenderQueueStr() { RenderQueueType renderQueueType; string prefix = string.Empty; if (owner.isBlendModeOpaque) { prefix = "Geometry"; renderQueueType = HDRenderQueue.ConvertFromOpaqueRenderQueue(opaqueRenderQueue); } else { prefix = "Transparent"; renderQueueType = HDRenderQueue.ConvertFromTransparentRenderQueue(transparentRenderQueue); } int renderQueue = HDRenderQueue.ChangeType(renderQueueType, 0, owner.useAlphaClipping) - (int)(owner.isBlendModeOpaque ? Priority.Opaque : Priority.Transparent); return(prefix + renderQueue.ToString("+#;-#;+0")); }
protected static void ResetMaterialCustomRenderQueue(Material material) { HDRenderQueue.RenderQueueType targetQueueType; switch (material.GetSurfaceType()) { case SurfaceType.Opaque: targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; case SurfaceType.Transparent: targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; default: throw new ArgumentException("Unknown SurfaceType"); } float sortingPriority = material.GetFloat(kTransparentSortPriority); bool alphaTest = material.GetFloat(kAlphaCutoffEnabled) > 0.5f; material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)sortingPriority, alphaTest); }
public static void ResetMaterialCustomRenderQueue(this Material material) { // using GetOpaqueEquivalent / GetTransparentEquivalent allow to handle the case when we switch surfaceType HDRenderQueue.RenderQueueType targetQueueType; switch (material.GetSurfaceType()) { case SurfaceType.Opaque: targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; case SurfaceType.Transparent: targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; default: throw new ArgumentException("Unknown SurfaceType"); } float sortingPriority = material.HasProperty(kTransparentSortPriority) ? material.GetFloat(kTransparentSortPriority) : 0.0f; bool alphaTest = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f; bool decalEnable = material.HasProperty(kEnableDecals) && material.GetFloat(kEnableDecals) > 0.0f; material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)sortingPriority, alphaTest, decalEnable); }
private int GetRenderQueueOffset() { var renderQueueType = GetRenderQueueType(); return(HDRenderQueue.ChangeType(renderQueueType, GetMaterialOffset(), owner.hasAlphaClipping)); }
public HDUnlitSettingsView(HDUnlitMasterNode node) { m_Node = node; PropertySheet ps = new PropertySheet(); int indentLevel = 0; ps.Add(new PropertyRow(CreateLabel("Surface Type", indentLevel)), (row) => { row.Add(new EnumField(SurfaceType.Opaque), (field) => { field.value = m_Node.surfaceType; field.RegisterValueChangedCallback(ChangeSurfaceType); }); }); ++indentLevel; switch (m_Node.surfaceType) { case SurfaceType.Opaque: ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) => { var valueList = HDSubShaderUtilities.GetRenderingPassList(true, true); row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Opaque, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) => { field.value = HDRenderQueue.GetOpaqueEquivalent(m_Node.renderingPass); field.RegisterValueChangedCallback(ChangeRenderingPass); }); }); break; case SurfaceType.Transparent: ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) => { Enum defaultValue; switch (m_Node.renderingPass) // Migration { default: //when deserializing without issue, we still need to init the default to something even if not used. case HDRenderQueue.RenderQueueType.Transparent: defaultValue = HDRenderQueue.TransparentRenderQueue.Default; break; case HDRenderQueue.RenderQueueType.PreRefraction: defaultValue = HDRenderQueue.TransparentRenderQueue.BeforeRefraction; break; } var valueList = HDSubShaderUtilities.GetRenderingPassList(false, true); row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Transparent, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) => { field.value = HDRenderQueue.GetTransparentEquivalent(m_Node.renderingPass); field.RegisterValueChangedCallback(ChangeRenderingPass); }); }); break; default: throw new ArgumentException("Unknown SurfaceType"); } --indentLevel; if (m_Node.surfaceType == SurfaceType.Transparent) { ++indentLevel; ps.Add(new PropertyRow(CreateLabel("Blending Mode", indentLevel)), (row) => { row.Add(new EnumField(HDUnlitMasterNode.AlphaModeLit.Additive), (field) => { field.value = GetAlphaModeLit(m_Node.alphaMode); field.RegisterValueChangedCallback(ChangeBlendMode); }); }); m_SortPiorityField = new IntegerField(); ps.Add(new PropertyRow(CreateLabel("Sorting Priority", indentLevel)), (row) => { row.Add(m_SortPiorityField, (field) => { field.value = m_Node.sortPriority; field.RegisterValueChangedCallback(ChangeSortPriority); }); }); ps.Add(new PropertyRow(CreateLabel("Receive Fog", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.transparencyFog.isOn; toggle.OnToggleChanged(ChangeTransparencyFog); }); }); ps.Add(new PropertyRow(CreateLabel("Distortion", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.distortion.isOn; toggle.OnToggleChanged(ChangeDistortion); }); }); if (m_Node.distortion.isOn) { ++indentLevel; ps.Add(new PropertyRow(CreateLabel("Mode", indentLevel)), (row) => { row.Add(new EnumField(DistortionMode.Add), (field) => { field.value = m_Node.distortionMode; field.RegisterValueChangedCallback(ChangeDistortionMode); }); }); ps.Add(new PropertyRow(CreateLabel("Distortion Only", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.distortionOnly.isOn; toggle.OnToggleChanged(ChangeDistortionOnly); }); }); ps.Add(new PropertyRow(CreateLabel("Depth Test", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.distortionDepthTest.isOn; toggle.OnToggleChanged(ChangeDistortionDepthTest); }); }); --indentLevel; } --indentLevel; } ps.Add(new PropertyRow(new Label("Double-Sided")), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.doubleSided.isOn; toggle.OnToggleChanged(ChangeDoubleSided); }); }); ps.Add(new PropertyRow(CreateLabel("Alpha Clipping", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.alphaTest.isOn; toggle.OnToggleChanged(ChangeAlphaTest); }); }); Add(ps); }
public HDLitSettingsView(HDLitMasterNode node) : base(node) { m_Node = node; PropertySheet ps = new PropertySheet(); int indentLevel = 0; ps.Add(new PropertyRow(CreateLabel("Surface Type", indentLevel)), (row) => { row.Add(new EnumField(SurfaceType.Opaque), (field) => { field.value = m_Node.surfaceType; field.RegisterValueChangedCallback(ChangeSurfaceType); }); }); ++indentLevel; switch (m_Node.surfaceType) { case SurfaceType.Opaque: ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) => { var valueList = HDSubShaderUtilities.GetRenderingPassList(true, false); row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Opaque, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) => { field.value = HDRenderQueue.GetOpaqueEquivalent(m_Node.renderingPass); field.RegisterValueChangedCallback(ChangeRenderingPass); }); }); break; case SurfaceType.Transparent: ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) => { Enum defaultValue; switch (m_Node.renderingPass) // Migration { default: //when deserializing without issue, we still need to init the default to something even if not used. case HDRenderQueue.RenderQueueType.Transparent: defaultValue = HDRenderQueue.TransparentRenderQueue.Default; break; case HDRenderQueue.RenderQueueType.PreRefraction: defaultValue = HDRenderQueue.TransparentRenderQueue.BeforeRefraction; break; } var valueList = HDSubShaderUtilities.GetRenderingPassList(false, false); row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Transparent, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) => { field.value = HDRenderQueue.GetTransparentEquivalent(m_Node.renderingPass); field.RegisterValueChangedCallback(ChangeRenderingPass); }); }); break; default: throw new ArgumentException("Unknown SurfaceType"); } --indentLevel; if (m_Node.surfaceType == SurfaceType.Transparent) { ++indentLevel; if (!m_Node.HasRefraction()) { ps.Add(new PropertyRow(CreateLabel("Blending Mode", indentLevel)), (row) => { row.Add(new EnumField(HDLitMasterNode.AlphaModeLit.Additive), (field) => { field.value = GetAlphaModeLit(m_Node.alphaMode); field.RegisterValueChangedCallback(ChangeBlendMode); }); }); ++indentLevel; ps.Add(new PropertyRow(CreateLabel("Preserve Specular Lighting", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.blendPreserveSpecular.isOn; toggle.OnToggleChanged(ChangeBlendPreserveSpecular); }); }); --indentLevel; } m_SortPriorityField = new IntegerField(); ps.Add(new PropertyRow(CreateLabel("Sorting Priority", indentLevel)), (row) => { row.Add(m_SortPriorityField, (field) => { field.value = m_Node.sortPriority; field.RegisterValueChangedCallback(ChangeSortPriority); }); }); ps.Add(new PropertyRow(CreateLabel("Receive Fog", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.transparencyFog.isOn; toggle.OnToggleChanged(ChangeTransparencyFog); }); }); ps.Add(new PropertyRow(CreateLabel("Back Then Front Rendering", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.backThenFrontRendering.isOn; toggle.OnToggleChanged(ChangeBackThenFrontRendering); }); }); ps.Add(new PropertyRow(CreateLabel("Transparent Depth Prepass", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.alphaTestDepthPrepass.isOn; toggle.OnToggleChanged(ChangeAlphaTestPrepass); }); }); ps.Add(new PropertyRow(CreateLabel("Transparent Depth Postpass", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.alphaTestDepthPostpass.isOn; toggle.OnToggleChanged(ChangeAlphaTestPostpass); }); }); ps.Add(new PropertyRow(CreateLabel("Transparent Writes Motion Vector", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.transparentWritesMotionVec.isOn; toggle.OnToggleChanged(ChangeTransparentWritesMotionVec); }); }); if (m_Node.renderingPass != HDRenderQueue.RenderQueueType.PreRefraction) { ps.Add(new PropertyRow(CreateLabel("Refraction Model", indentLevel)), (row) => { row.Add(new EnumField(ScreenSpaceRefraction.RefractionModel.None), (field) => { field.value = m_Node.refractionModel; field.RegisterValueChangedCallback(ChangeRefractionModel); }); }); } ps.Add(new PropertyRow(CreateLabel("Distortion", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.distortion.isOn; toggle.OnToggleChanged(ChangeDistortion); }); }); if (m_Node.distortion.isOn) { ++indentLevel; ps.Add(new PropertyRow(CreateLabel("Distortion Blend Mode", indentLevel)), (row) => { row.Add(new EnumField(DistortionMode.Add), (field) => { field.value = m_Node.distortionMode; field.RegisterValueChangedCallback(ChangeDistortionMode); }); }); ps.Add(new PropertyRow(CreateLabel("Distortion Depth Test", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.distortionDepthTest.isOn; toggle.OnToggleChanged(ChangeDistortionDepthTest); }); }); --indentLevel; } ps.Add(new PropertyRow(CreateLabel("Depth Write", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.zWrite.isOn; toggle.OnToggleChanged(ChangeZWrite); }); }); if (m_Node.doubleSidedMode == DoubleSidedMode.Disabled) { ps.Add(new PropertyRow(CreateLabel("Cull Mode", indentLevel)), (row) => { row.Add(new EnumField(m_Node.transparentCullMode), (e) => { e.value = m_Node.transparentCullMode; e.RegisterValueChangedCallback(ChangeTransparentCullMode); }); }); } ps.Add(new PropertyRow(CreateLabel("Depth Test", indentLevel)), (row) => { row.Add(new EnumField(m_Node.zTest), (e) => { e.value = m_Node.zTest; e.RegisterValueChangedCallback(ChangeZTest); }); }); --indentLevel; } ps.Add(new PropertyRow(CreateLabel("Double-Sided", indentLevel)), (row) => { row.Add(new EnumField(DoubleSidedMode.Disabled), (field) => { field.value = m_Node.doubleSidedMode; field.RegisterValueChangedCallback(ChangeDoubleSidedMode); }); }); ps.Add(new PropertyRow(CreateLabel("Fragment Normal Space", indentLevel)), (row) => { row.Add(new EnumField(NormalDropOffSpace.Tangent), (field) => { field.value = m_Node.normalDropOffSpace; field.RegisterValueChangedCallback(ChangeSpaceOfNormalDropOffMode); }); }); ps.Add(new PropertyRow(CreateLabel("Alpha Clipping", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.alphaTest.isOn; toggle.OnToggleChanged(ChangeAlphaTest); }); }); if (m_Node.alphaTest.isOn) { ++indentLevel; ps.Add(new PropertyRow(CreateLabel("Use Shadow Threshold", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.alphaTestShadow.isOn; toggle.OnToggleChanged(ChangeAlphaTestShadow); }); }); --indentLevel; } ps.Add(new PropertyRow(CreateLabel("Material Type", indentLevel)), (row) => { row.Add(new EnumField(HDLitMasterNode.MaterialType.Standard), (field) => { field.value = m_Node.materialType; field.RegisterValueChangedCallback(ChangeMaterialType); }); }); ++indentLevel; if (m_Node.materialType == HDLitMasterNode.MaterialType.SubsurfaceScattering) { ps.Add(new PropertyRow(CreateLabel("Transmission", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.sssTransmission.isOn; toggle.OnToggleChanged(ChangeSSSTransmission); }); }); } if (m_Node.materialType == HDLitMasterNode.MaterialType.SpecularColor) { ps.Add(new PropertyRow(CreateLabel("Energy Conserving Specular", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.energyConservingSpecular.isOn; toggle.OnToggleChanged(ChangeEnergyConservingSpecular); }); }); } --indentLevel; ps.Add(new PropertyRow(CreateLabel("Receive Decals", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.receiveDecals.isOn; toggle.OnToggleChanged(ChangeDecal); }); }); ps.Add(new PropertyRow(CreateLabel("Receive SSR", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.receiveSSR.isOn; toggle.OnToggleChanged(ChangeSSR); }); }); ps.Add(new PropertyRow(CreateLabel("Add Precomputed Velocity", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.addPrecomputedVelocity.isOn; toggle.OnToggleChanged(ChangeAddPrecomputedVelocity); }); }); ps.Add(new PropertyRow(CreateLabel("Geometric Specular AA", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.specularAA.isOn; toggle.OnToggleChanged(ChangeSpecularAA); }); }); ps.Add(new PropertyRow(CreateLabel("Specular Occlusion Mode", indentLevel)), (row) => { row.Add(new EnumField(SpecularOcclusionMode.Off), (field) => { field.value = m_Node.specularOcclusionMode; field.RegisterValueChangedCallback(ChangeSpecularOcclusionMode); }); }); ps.Add(new PropertyRow(CreateLabel("Override Baked GI", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.overrideBakedGI.isOn; toggle.OnToggleChanged(ChangeoverrideBakedGI); }); }); ps.Add(new PropertyRow(CreateLabel("Depth Offset", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.depthOffset.isOn; toggle.OnToggleChanged(ChangeDepthOffset); }); }); ps.Add(new PropertyRow(CreateLabel("DOTS instancing", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.dotsInstancing.isOn; toggle.OnToggleChanged(ChangeDotsInstancing); }); }); ps.Add(new PropertyRow(CreateLabel("Support LOD CrossFade", indentLevel)), (row) => { row.Add(new Toggle(), (toggle) => { toggle.value = m_Node.supportLodCrossFade.isOn; toggle.OnToggleChanged(ChangeSupportLODCrossFade); }); }); Add(ps); Add(GetShaderGUIOverridePropertySheet()); }
void SurfaceTypePopup() { if (surfaceType == null) { return; } Material material = m_MaterialEditor.target as Material; var mode = (SurfaceType)surfaceType.floatValue; var renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue); bool alphaTest = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f; EditorGUI.showMixedValue = surfaceType.hasMixedValue; var newMode = (SurfaceType)EditorGUILayout.Popup(StylesBaseUnlit.surfaceTypeText, (int)mode, StylesBaseUnlit.surfaceTypeNames); if (newMode != mode) //EditorGUI.EndChangeCheck is called even if value remain the same after the popup. Prefer not to use it here { m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type"); surfaceType.floatValue = (float)newMode; HDRenderQueue.RenderQueueType targetQueueType; switch (newMode) { case SurfaceType.Opaque: targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; case SurfaceType.Transparent: targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue)); break; default: throw new ArgumentException("Unknown SurfaceType"); } material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)transparentSortPriority.floatValue, alphaTest); } EditorGUI.showMixedValue = false; bool isMixedRenderQueue = surfaceType.hasMixedValue || m_MaterialEditor.targets.Select(m => HDRenderQueue.GetTypeByRenderQueueValue(((Material)m).renderQueue)).Distinct().Count() > 1; EditorGUI.showMixedValue = isMixedRenderQueue; ++EditorGUI.indentLevel; switch (mode) { case SurfaceType.Opaque: //GetOpaqueEquivalent: prevent issue when switching surface type HDRenderQueue.OpaqueRenderQueue renderQueueOpaqueType = HDRenderQueue.ConvertToOpaqueRenderQueue(HDRenderQueue.GetOpaqueEquivalent(renderQueueType)); var newRenderQueueOpaqueType = (HDRenderQueue.OpaqueRenderQueue)EditorGUILayout.Popup(StylesBaseUnlit.renderingPassText, (int)renderQueueOpaqueType, StylesBaseUnlit.opaqueRenderingPassNames); if (newRenderQueueOpaqueType != renderQueueOpaqueType) //EditorGUI.EndChangeCheck is called even if value remain the same after the popup. Prefer not to use it here { m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Pass"); renderQueueType = HDRenderQueue.ConvertFromOpaqueRenderQueue(newRenderQueueOpaqueType); material.renderQueue = HDRenderQueue.ChangeType(renderQueueType, alphaTest: alphaTest); } break; case SurfaceType.Transparent: //GetTransparentEquivalent: prevent issue when switching surface type HDRenderQueue.TransparentRenderQueue renderQueueTransparentType = HDRenderQueue.ConvertToTransparentRenderQueue(HDRenderQueue.GetTransparentEquivalent(renderQueueType)); var names = StylesBaseUnlit.transparentRenderingPassNames; if (!showPreRefractionPass) { names = names.Skip(1).ToArray(); --renderQueueTransparentType; //keep index sync with displayed value } var newRenderQueueTransparentType = (HDRenderQueue.TransparentRenderQueue)EditorGUILayout.Popup(StylesBaseUnlit.renderingPassText, (int)renderQueueTransparentType, names); if (newRenderQueueTransparentType != renderQueueTransparentType) //EditorGUI.EndChangeCheck is called even if value remain the same after the popup. Prefer not to use it here { if (!showPreRefractionPass) { ++newRenderQueueTransparentType; //keep index sync with displayed value } m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Pass"); renderQueueType = HDRenderQueue.ConvertFromTransparentRenderQueue(newRenderQueueTransparentType); material.renderQueue = HDRenderQueue.ChangeType(renderQueueType, offset: (int)transparentSortPriority.floatValue); } break; default: throw new ArgumentException("Unknown SurfaceType"); } --EditorGUI.indentLevel; EditorGUI.showMixedValue = false; }
public static void SetupBaseUnlitKeywords(this Material material) { bool alphaTestEnable = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f; CoreUtils.SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable); // Setup alpha to mask using the _AlphaToMaskInspectorValue that we configure in the material UI float alphaToMaskEnabled = material.HasProperty("_AlphaToMaskInspectorValue") && material.GetFloat("_AlphaToMaskInspectorValue") > 0.0 ? 1 : 0; material.SetFloat(kAlphaToMask, alphaTestEnable ? alphaToMaskEnabled : 0); bool alphaToMaskEnable = alphaTestEnable && material.HasProperty(kAlphaToMask) && material.GetFloat(kAlphaToMask) > 0.0f; CoreUtils.SetKeyword(material, "_ALPHATOMASK_ON", alphaToMaskEnable); SurfaceType surfaceType = material.GetSurfaceType(); CoreUtils.SetKeyword(material, "_SURFACE_TYPE_TRANSPARENT", surfaceType == SurfaceType.Transparent); bool enableBlendModePreserveSpecularLighting = (surfaceType == SurfaceType.Transparent) && material.HasProperty(kEnableBlendModePreserveSpecularLighting) && material.GetFloat(kEnableBlendModePreserveSpecularLighting) > 0.0f; CoreUtils.SetKeyword(material, "_BLENDMODE_PRESERVE_SPECULAR_LIGHTING", enableBlendModePreserveSpecularLighting); bool transparentWritesMotionVec = (surfaceType == SurfaceType.Transparent) && material.HasProperty(kTransparentWritingMotionVec) && material.GetInt(kTransparentWritingMotionVec) > 0; CoreUtils.SetKeyword(material, "_TRANSPARENT_WRITES_MOTION_VEC", transparentWritesMotionVec); // These need to always been set either with opaque or transparent! So a users can switch to opaque and remove the keyword correctly CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", false); CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", false); CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", false); HDRenderQueue.RenderQueueType renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue); bool needOffScreenBlendFactor = renderQueueType == HDRenderQueue.RenderQueueType.AfterPostprocessTransparent || renderQueueType == HDRenderQueue.RenderQueueType.LowTransparent; // Alpha tested materials always have a prepass where we perform the clip. // Then during Gbuffer pass we don't perform the clip test, so we need to use depth equal in this case. if (alphaTestEnable) { material.SetInt(kZTestGBuffer, (int)UnityEngine.Rendering.CompareFunction.Equal); } else { material.SetInt(kZTestGBuffer, (int)UnityEngine.Rendering.CompareFunction.LessEqual); } // If the material use the kZTestDepthEqualForOpaque it mean it require depth equal test for opaque but transparent are not affected if (material.HasProperty(kZTestDepthEqualForOpaque)) { if (surfaceType == SurfaceType.Opaque) { // When the material is after post process, we need to use LEssEqual because there is no depth prepass for unlit opaque if (HDRenderQueue.k_RenderQueue_AfterPostProcessOpaque.Contains(material.renderQueue)) { material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.LessEqual); } else { material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.Equal); } } else { material.SetInt(kZTestDepthEqualForOpaque, (int)material.GetTransparentZTest()); } } if (surfaceType == SurfaceType.Opaque) { material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : ""); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); // Caution: we need to setup One for src and Zero for Dst for all element as users could switch from transparent to Opaque and keep remaining value. // Unity will disable Blending based on these default value. // Note that for after postprocess we setup 0 in opacity inside the shaders, so we correctly end with 0 in opacity for the compositing pass material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt(kZWrite, 1); } else { material.SetOverrideTag("RenderType", "Transparent"); material.SetInt(kZWrite, material.GetTransparentZWrite() ? 1 : 0); if (material.HasProperty(kBlendMode)) { BlendMode blendMode = material.GetBlendMode(); CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", BlendMode.Alpha == blendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", BlendMode.Additive == blendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", BlendMode.Premultiply == blendMode); // When doing off-screen transparency accumulation, we change blend factors as described here: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html switch (blendMode) { // Alpha // color: src * src_a + dst * (1 - src_a) // src * src_a is done in the shader as it allow to reduce precision issue when using _BLENDMODE_PRESERVE_SPECULAR_LIGHTING (See Material.hlsl) case BlendMode.Alpha: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); if (needOffScreenBlendFactor) { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } else { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } break; // Additive // color: src * src_a + dst // src * src_a is done in the shader case BlendMode.Additive: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); if (needOffScreenBlendFactor) { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.One); } else { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.One); } break; // PremultipliedAlpha // color: src * src_a + dst * (1 - src_a) // src is supposed to have been multiplied by alpha in the texture on artists side. case BlendMode.Premultiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); if (needOffScreenBlendFactor) { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } else { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } break; } } } bool fogEnabled = material.HasProperty(kEnableFogOnTransparent) && material.GetFloat(kEnableFogOnTransparent) > 0.0f && surfaceType == SurfaceType.Transparent; CoreUtils.SetKeyword(material, "_ENABLE_FOG_ON_TRANSPARENT", fogEnabled); if (material.HasProperty(kDistortionEnable) && material.HasProperty(kDistortionBlendMode)) { bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f; if (material.HasProperty(kZTestModeDistortion)) { if (distortionDepthTest) { material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.LessEqual); } else { material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.Always); } } var distortionBlendMode = material.GetInt(kDistortionBlendMode); switch (distortionBlendMode) { default: case 0: // Add material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; case 1: // Multiply material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstAlpha); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; case 2: // Replace material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; } } CullMode doubleSidedOffMode = (surfaceType == SurfaceType.Transparent) ? material.GetTransparentCullMode() : material.GetOpaqueCullMode(); bool isBackFaceEnable = material.HasProperty(kTransparentBackfaceEnable) && material.GetFloat(kTransparentBackfaceEnable) > 0.0f && surfaceType == SurfaceType.Transparent; bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) && material.GetFloat(kDoubleSidedEnable) > 0.0f; // Disable culling if double sided material.SetInt("_CullMode", doubleSidedEnable ? (int)UnityEngine.Rendering.CullMode.Off : (int)doubleSidedOffMode); // We have a separate cullmode (_CullModeForward) for Forward in case we use backface then frontface rendering, need to configure it if (isBackFaceEnable) { material.SetInt("_CullModeForward", (int)UnityEngine.Rendering.CullMode.Back); } else { material.SetInt("_CullModeForward", (int)(doubleSidedEnable ? UnityEngine.Rendering.CullMode.Off : doubleSidedOffMode)); } CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. if (material.HasProperty(kEmissionColor)) { material.SetColor(kEmissionColor, Color.white); // kEmissionColor must always be white to allow our own material to control the GI (this allow to fallback from builtin unity to our system). // as it happen with old material that it isn't the case, we force it. MaterialEditor.FixupEmissiveFlag(material); } // Commented out for now because unfortunately we used the hard coded property names used by the GI system for our own parameters // So we need a way to work around that before we activate this. material.SetupMainTexForAlphaTestGI("_EmissiveColorMap", "_EmissiveColor"); // depth offset for ShaderGraphs (they don't have the displacement mode property) if (!material.HasProperty(kDisplacementMode) && material.HasProperty(kDepthOffsetEnable)) { // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f); CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); } // DoubleSidedGI has to be synced with our double sided toggle var serializedObject = new SerializedObject(material); var doubleSidedGIppt = serializedObject.FindProperty("m_DoubleSidedGI"); doubleSidedGIppt.boolValue = doubleSidedEnable; serializedObject.ApplyModifiedProperties(); }
void UpgradeHDLitMasterNode(HDLitMasterNode1 hdLitMasterNode, out Dictionary <BlockFieldDescriptor, int> blockMap) { // Set data systemData.surfaceType = (SurfaceType)hdLitMasterNode.m_SurfaceType; systemData.blendMode = HDSubShaderUtilities.UpgradeLegacyAlphaModeToBlendMode((int)hdLitMasterNode.m_AlphaMode); systemData.renderQueueType = HDRenderQueue.MigrateRenderQueueToHDRP10(hdLitMasterNode.m_RenderingPass); if (systemData.renderQueueType == HDRenderQueue.RenderQueueType.PreRefraction && !hdLitMasterNode.m_DrawBeforeRefraction) { systemData.renderQueueType = HDRenderQueue.RenderQueueType.Transparent; } // Patch rendering pass in case the master node had an old configuration if (systemData.renderQueueType == HDRenderQueue.RenderQueueType.Background) { systemData.renderQueueType = HDRenderQueue.RenderQueueType.Opaque; } systemData.alphaTest = hdLitMasterNode.m_AlphaTest; systemData.sortPriority = hdLitMasterNode.m_SortPriority; systemData.doubleSidedMode = hdLitMasterNode.m_DoubleSidedMode; systemData.transparentZWrite = hdLitMasterNode.m_ZWrite; systemData.transparentCullMode = hdLitMasterNode.m_transparentCullMode; systemData.zTest = hdLitMasterNode.m_ZTest; systemData.dotsInstancing = hdLitMasterNode.m_DOTSInstancing; systemData.materialNeedsUpdateHash = hdLitMasterNode.m_MaterialNeedsUpdateHash; builtinData.transparentDepthPrepass = hdLitMasterNode.m_AlphaTestDepthPrepass; builtinData.transparentDepthPostpass = hdLitMasterNode.m_AlphaTestDepthPostpass; builtinData.supportLodCrossFade = hdLitMasterNode.m_SupportLodCrossFade; builtinData.transparencyFog = hdLitMasterNode.m_TransparencyFog; builtinData.distortion = hdLitMasterNode.m_Distortion; builtinData.distortionMode = hdLitMasterNode.m_DistortionMode; builtinData.distortionDepthTest = hdLitMasterNode.m_DistortionDepthTest; builtinData.transparentWritesMotionVec = hdLitMasterNode.m_TransparentWritesMotionVec; builtinData.addPrecomputedVelocity = hdLitMasterNode.m_AddPrecomputedVelocity; builtinData.depthOffset = hdLitMasterNode.m_depthOffset; builtinData.alphaToMask = hdLitMasterNode.m_AlphaToMask; builtinData.alphaTestShadow = hdLitMasterNode.m_AlphaTestShadow; builtinData.backThenFrontRendering = hdLitMasterNode.m_BackThenFrontRendering; lightingData.normalDropOffSpace = hdLitMasterNode.m_NormalDropOffSpace; lightingData.blendPreserveSpecular = hdLitMasterNode.m_BlendPreserveSpecular; lightingData.receiveDecals = hdLitMasterNode.m_ReceiveDecals; lightingData.receiveSSR = hdLitMasterNode.m_ReceivesSSR; lightingData.receiveSSRTransparent = hdLitMasterNode.m_ReceivesSSRTransparent; lightingData.specularAA = hdLitMasterNode.m_SpecularAA; lightingData.specularOcclusionMode = hdLitMasterNode.m_SpecularOcclusionMode; lightingData.overrideBakedGI = hdLitMasterNode.m_overrideBakedGI; HDLitData.MaterialType materialType = (HDLitData.MaterialType)hdLitMasterNode.m_MaterialType; litData.clearCoat = UpgradeCoatMask(hdLitMasterNode); litData.energyConservingSpecular = hdLitMasterNode.m_EnergyConservingSpecular; litData.rayTracing = hdLitMasterNode.m_RayTracing; litData.refractionModel = hdLitMasterNode.m_RefractionModel; litData.materialType = materialType; litData.sssTransmission = hdLitMasterNode.m_SSSTransmission; target.customEditorGUI = hdLitMasterNode.m_OverrideEnabled ? hdLitMasterNode.m_ShaderGUIOverride : ""; // Handle mapping of Normal block specifically BlockFieldDescriptor normalBlock; BlockFieldDescriptor tangentBlock; switch (lightingData.normalDropOffSpace) { case NormalDropOffSpace.Object: normalBlock = BlockFields.SurfaceDescription.NormalOS; tangentBlock = HDBlockFields.SurfaceDescription.TangentOS; break; case NormalDropOffSpace.World: normalBlock = BlockFields.SurfaceDescription.NormalWS; tangentBlock = HDBlockFields.SurfaceDescription.TangentWS; break; default: normalBlock = BlockFields.SurfaceDescription.NormalTS; tangentBlock = HDBlockFields.SurfaceDescription.TangentTS; break; } // Convert SlotMask to BlockMap entries var blockMapLookup = new Dictionary <HDLitMasterNode1.SlotMask, BlockFieldDescriptor>() { { HDLitMasterNode1.SlotMask.Albedo, BlockFields.SurfaceDescription.BaseColor }, { HDLitMasterNode1.SlotMask.Normal, normalBlock }, { HDLitMasterNode1.SlotMask.BentNormal, HDBlockFields.SurfaceDescription.BentNormal }, { HDLitMasterNode1.SlotMask.Tangent, tangentBlock }, { HDLitMasterNode1.SlotMask.Anisotropy, HDBlockFields.SurfaceDescription.Anisotropy }, { HDLitMasterNode1.SlotMask.SubsurfaceMask, HDBlockFields.SurfaceDescription.SubsurfaceMask }, { HDLitMasterNode1.SlotMask.Thickness, HDBlockFields.SurfaceDescription.Thickness }, { HDLitMasterNode1.SlotMask.DiffusionProfile, HDBlockFields.SurfaceDescription.DiffusionProfileHash }, { HDLitMasterNode1.SlotMask.IridescenceMask, HDBlockFields.SurfaceDescription.IridescenceMask }, { HDLitMasterNode1.SlotMask.IridescenceLayerThickness, HDBlockFields.SurfaceDescription.IridescenceThickness }, { HDLitMasterNode1.SlotMask.Specular, BlockFields.SurfaceDescription.Specular }, { HDLitMasterNode1.SlotMask.CoatMask, BlockFields.SurfaceDescription.CoatMask }, { HDLitMasterNode1.SlotMask.Metallic, BlockFields.SurfaceDescription.Metallic }, { HDLitMasterNode1.SlotMask.Smoothness, BlockFields.SurfaceDescription.Smoothness }, { HDLitMasterNode1.SlotMask.Occlusion, BlockFields.SurfaceDescription.Occlusion }, { HDLitMasterNode1.SlotMask.SpecularOcclusion, HDBlockFields.SurfaceDescription.SpecularOcclusion }, { HDLitMasterNode1.SlotMask.Emission, BlockFields.SurfaceDescription.Emission }, { HDLitMasterNode1.SlotMask.Alpha, BlockFields.SurfaceDescription.Alpha }, { HDLitMasterNode1.SlotMask.AlphaThreshold, BlockFields.SurfaceDescription.AlphaClipThreshold }, { HDLitMasterNode1.SlotMask.AlphaThresholdDepthPrepass, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass }, { HDLitMasterNode1.SlotMask.AlphaThresholdDepthPostpass, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass }, { HDLitMasterNode1.SlotMask.AlphaThresholdShadow, HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow }, }; // Legacy master node slots have additional slot conditions, test them here bool AdditionalSlotMaskTests(HDLitMasterNode1.SlotMask slotMask) { switch (slotMask) { case HDLitMasterNode1.SlotMask.Thickness: return(litData.sssTransmission || litData.materialType == HDLitData.MaterialType.Translucent); case HDLitMasterNode1.SlotMask.SpecularOcclusion: return(lightingData.specularOcclusionMode == SpecularOcclusionMode.Custom); case HDLitMasterNode1.SlotMask.AlphaThreshold: return(systemData.alphaTest); case HDLitMasterNode1.SlotMask.AlphaThresholdDepthPrepass: return(systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && builtinData.transparentDepthPrepass); case HDLitMasterNode1.SlotMask.AlphaThresholdDepthPostpass: return(systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && builtinData.transparentDepthPostpass); case HDLitMasterNode1.SlotMask.AlphaThresholdShadow: return(systemData.alphaTest && builtinData.alphaTestShadow); default: return(true); } } bool UpgradeCoatMask(HDLitMasterNode1 masterNode) { var coatMaskSlotId = HDLitMasterNode1.CoatMaskSlotId; var node = masterNode as AbstractMaterialNode; var coatMaskSlot = node.FindSlot <Vector1MaterialSlot>(coatMaskSlotId); if (coatMaskSlot == null) { return(false); } coatMaskSlot.owner = node; return(coatMaskSlot.isConnected || coatMaskSlot.value > 0.0f); } // Set blockmap blockMap = new Dictionary <BlockFieldDescriptor, int>(); // First handle vertex blocks. We ran out of SlotMask bits for VertexNormal and VertexTangent // so do all Vertex blocks here to maintain correct block order (Position is not in blockMapLookup) blockMap.Add(BlockFields.VertexDescription.Position, HDLitMasterNode1.PositionSlotId); blockMap.Add(BlockFields.VertexDescription.Normal, HDLitMasterNode1.VertexNormalSlotID); blockMap.Add(BlockFields.VertexDescription.Tangent, HDLitMasterNode1.VertexTangentSlotID); // Now handle the SlotMask cases foreach (HDLitMasterNode1.SlotMask slotMask in Enum.GetValues(typeof(HDLitMasterNode1.SlotMask))) { if (hdLitMasterNode.MaterialTypeUsesSlotMask(slotMask)) { if (!blockMapLookup.TryGetValue(slotMask, out var blockFieldDescriptor)) { continue; } if (!AdditionalSlotMaskTests(slotMask)) { continue; } var slotId = Mathf.Log((int)slotMask, 2); blockMap.Add(blockFieldDescriptor, (int)slotId); } } // Specular AA if (lightingData.specularAA) { blockMap.Add(HDBlockFields.SurfaceDescription.SpecularAAScreenSpaceVariance, HDLitMasterNode1.SpecularAAScreenSpaceVarianceSlotId); blockMap.Add(HDBlockFields.SurfaceDescription.SpecularAAThreshold, HDLitMasterNode1.SpecularAAThresholdSlotId); } // Refraction bool hasRefraction = (systemData.surfaceType == SurfaceType.Transparent && systemData.renderQueueType != HDRenderQueue.RenderQueueType.PreRefraction && litData.refractionModel != ScreenSpaceRefraction.RefractionModel.None); if (hasRefraction) { if (!blockMap.TryGetValue(HDBlockFields.SurfaceDescription.Thickness, out _)) { blockMap.Add(HDBlockFields.SurfaceDescription.Thickness, HDLitMasterNode1.ThicknessSlotId); } blockMap.Add(HDBlockFields.SurfaceDescription.RefractionIndex, HDLitMasterNode1.RefractionIndexSlotId); blockMap.Add(HDBlockFields.SurfaceDescription.RefractionColor, HDLitMasterNode1.RefractionColorSlotId); blockMap.Add(HDBlockFields.SurfaceDescription.RefractionDistance, HDLitMasterNode1.RefractionDistanceSlotId); } // Distortion bool hasDistortion = (systemData.surfaceType == SurfaceType.Transparent && builtinData.distortion); if (hasDistortion) { blockMap.Add(HDBlockFields.SurfaceDescription.Distortion, HDLitMasterNode1.DistortionSlotId); blockMap.Add(HDBlockFields.SurfaceDescription.DistortionBlur, HDLitMasterNode1.DistortionBlurSlotId); } // Override Baked GI if (lightingData.overrideBakedGI) { blockMap.Add(HDBlockFields.SurfaceDescription.BakedGI, HDLitMasterNode1.LightingSlotId); blockMap.Add(HDBlockFields.SurfaceDescription.BakedBackGI, HDLitMasterNode1.BackLightingSlotId); } // Depth Offset (Removed from SlotMask because of missing bits) if (builtinData.depthOffset) { blockMap.Add(HDBlockFields.SurfaceDescription.DepthOffset, HDLitMasterNode1.DepthOffsetSlotId); } }
/// <summary> /// Renders the properties in the block. /// </summary> public override void OnGUI() { if (refractionModel != null) { materialEditor.ShaderProperty(refractionModel, Styles.refractionModelText); var mode = (ScreenSpaceRefraction.RefractionModel)refractionModel.floatValue; switch (mode) { case ScreenSpaceRefraction.RefractionModel.Box: case ScreenSpaceRefraction.RefractionModel.Sphere: { if (ior != null) { materialEditor.ShaderProperty(ior, Styles.refractionIorText); } if (thicknessMap[0] != null) { if (thicknessMap[0].textureValue == null) { materialEditor.TexturePropertySingleLine(Styles.refractionThicknessText, thicknessMap[0], thickness[0]); } else { materialEditor.TexturePropertySingleLine(Styles.refractionThicknessMapText, thicknessMap[0]); // Display the remap of texture values. materialEditor.MinMaxShaderProperty(thicknessRemap[0], 0.0f, 1.0f, Styles.refractionThicknessRemappingText); } } if (transmittanceColorMap != null) { materialEditor.TexturePropertySingleLine(Styles.transmittanceColorText, transmittanceColorMap, transmittanceColor); ++EditorGUI.indentLevel; materialEditor.ShaderProperty(atDistance, Styles.atDistanceText); atDistance.floatValue = Mathf.Max(atDistance.floatValue, 0); --EditorGUI.indentLevel; } } break; case ScreenSpaceRefraction.RefractionModel.Thin: { if (ior != null) { materialEditor.ShaderProperty(ior, Styles.refractionIorText); } if (transmittanceColorMap != null) { materialEditor.TexturePropertySingleLine(Styles.transmittanceColorText, transmittanceColorMap, transmittanceColor); } } break; default: break; } if (refractionModel.floatValue != 0 && blendMode != null) { if (blendMode.floatValue != (int)BlendMode.Alpha) { EditorGUILayout.HelpBox(Styles.refractionBlendModeWarning, MessageType.Warning); } // Check for multi-selection render queue different values if (materials.Length == 1 || materials.All(m => m.renderQueue == materials[0].renderQueue)) { var renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(materials[0].renderQueue); if (renderQueueType == HDRenderQueue.RenderQueueType.PreRefraction) { EditorGUILayout.HelpBox(Styles.refractionRenderingPassWarning, MessageType.Warning); } } } } }
public override void Convert(Material srcMaterial, Material dstMaterial) { dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset; base.Convert(srcMaterial, dstMaterial); // ---------- Mask Map ---------- // Metallic bool hasMetallic = false; Texture metallicMap = TextureCombiner.TextureFromColor(Color.black); if ((srcMaterial.shader.name == Standard) || (srcMaterial.shader.name == Standard_Rough)) { hasMetallic = srcMaterial.GetTexture("_MetallicGlossMap") != null; if (hasMetallic) { metallicMap = TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white); } else { metallicMap = TextureCombiner.TextureFromColor(Color.white); } // Convert _Metallic value from Gamma to Linear, or set to 1 if a map is used float metallicValue = Mathf.Pow(srcMaterial.GetFloat("_Metallic"), 2.2f); dstMaterial.SetFloat("_Metallic", hasMetallic? 1f : metallicValue); } // Occlusion bool hasOcclusion = srcMaterial.GetTexture("_OcclusionMap") != null; Texture occlusionMap = Texture2D.whiteTexture; if (hasOcclusion) { occlusionMap = TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white); } dstMaterial.SetFloat("_AORemapMin", 1f - srcMaterial.GetFloat("_OcclusionStrength")); // Detail Mask bool hasDetailMask = srcMaterial.GetTexture("_DetailMask") != null; Texture detailMaskMap = Texture2D.whiteTexture; if (hasDetailMask) { detailMaskMap = TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white); } // Smoothness bool hasSmoothness = false; Texture2D smoothnessMap = TextureCombiner.TextureFromColor(Color.white); dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_Glossiness")); if (srcMaterial.shader.name == Standard_Rough) { hasSmoothness = srcMaterial.GetTexture("_SpecGlossMap") != null; if (hasSmoothness) { smoothnessMap = (Texture2D)TextureCombiner.GetTextureSafe(srcMaterial, "_SpecGlossMap", Color.grey); } } else { string smoothnessTextureChannel = "_MainTex"; if (srcMaterial.GetFloat("_SmoothnessTextureChannel") == 0) { if (srcMaterial.shader.name == Standard) { smoothnessTextureChannel = "_MetallicGlossMap"; } if (srcMaterial.shader.name == Standard_Spec) { smoothnessTextureChannel = "_SpecGlossMap"; } } smoothnessMap = (Texture2D)srcMaterial.GetTexture(smoothnessTextureChannel); if (smoothnessMap != null) { hasSmoothness = true; dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_GlossMapScale")); if (!TextureCombiner.TextureHasAlpha(smoothnessMap)) { smoothnessMap = TextureCombiner.TextureFromColor(Color.white); } } else { smoothnessMap = TextureCombiner.TextureFromColor(Color.white); } } // Build the mask map if (hasMetallic || hasOcclusion || hasDetailMask || hasSmoothness) { Texture2D maskMap; TextureCombiner maskMapCombiner = new TextureCombiner( metallicMap, 0, // R: Metallic from red occlusionMap, 1, // G: Occlusion from green detailMaskMap, 3, // B: Detail Mask from alpha smoothnessMap, (srcMaterial.shader.name == Standard_Rough) ? -4 : 3 // A: Smoothness Texture from inverse greyscale for roughness setup, or alpha ); string maskMapPath = AssetDatabase.GetAssetPath(srcMaterial); maskMapPath = maskMapPath.Remove(maskMapPath.Length - 4) + "_MaskMap.png"; maskMap = maskMapCombiner.Combine(maskMapPath); dstMaterial.SetTexture("_MaskMap", maskMap); } // Specular Setup Specific if (srcMaterial.shader.name == Standard_Spec) { // if there is a specular map, change the specular color to white if (srcMaterial.GetTexture("_SpecGlossMap") != null) { dstMaterial.SetColor("_SpecularColor", Color.white); } } // ---------- Height Map ---------- bool hasHeightMap = srcMaterial.GetTexture("_ParallaxMap") != null; if (hasHeightMap) // Enable Parallax Occlusion Mapping { dstMaterial.SetFloat("_DisplacementMode", 2); dstMaterial.SetFloat("_HeightPoMAmplitude", srcMaterial.GetFloat("_Parallax") * 2f); } // ---------- Detail Map ---------- bool hasDetailAlbedo = srcMaterial.GetTexture("_DetailAlbedoMap") != null; bool hasDetailNormal = srcMaterial.GetTexture("_DetailNormalMap") != null; if (hasDetailAlbedo || hasDetailNormal) { Texture2D detailMap; TextureCombiner detailCombiner = new TextureCombiner( TextureCombiner.GetTextureSafe(srcMaterial, "_DetailAlbedoMap", Color.grey), 4, // Albedo (overlay) TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 1, // Normal Y TextureCombiner.midGrey, 1, // Smoothness TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 0 // Normal X ); string detailMapPath = AssetDatabase.GetAssetPath(srcMaterial); detailMapPath = detailMapPath.Remove(detailMapPath.Length - 4) + "_DetailMap.png"; detailMap = detailCombiner.Combine(detailMapPath); dstMaterial.SetTexture("_DetailMap", detailMap); } // Blend Mode int previousBlendMode = srcMaterial.GetInt("_Mode"); switch (previousBlendMode) { case 0: // Opaque dstMaterial.SetFloat("_SurfaceType", 0); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 0); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1); dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Opaque, 0, false, true); break; case 1: // Cutout dstMaterial.SetFloat("_SurfaceType", 0); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 1); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1); dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Opaque, 0, true, true); break; case 2: // Fade -> Alpha with depth prepass + Disable preserve specular dstMaterial.SetFloat("_SurfaceType", 1); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 0); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 0); dstMaterial.SetFloat("_TransparentDepthPrepassEnable", 1); dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Transparent, 0, false, true); break; case 3: // Transparent -> Alpha dstMaterial.SetFloat("_SurfaceType", 1); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 0); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1); dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Transparent, 0, false, true); break; } Color hdrEmission = srcMaterial.GetColor("_EmissionColor"); // Get the _EMISSION keyword of the Standard shader if (!srcMaterial.IsKeywordEnabled("_EMISSION")) { hdrEmission = Color.black; } // Emission toggle of Particle Standard Surface if (srcMaterial.HasProperty("_EmissionEnabled")) { if (srcMaterial.GetFloat("_EmissionEnabled") == 0) { hdrEmission = Color.black; } } dstMaterial.SetColor("_EmissiveColor", hdrEmission); HDShaderUtils.ResetMaterialKeywords(dstMaterial); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HairSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("c3f20efb64673e0488a2c8e986a453fa")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HairMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { // Add tags at the SubShader level var renderingPass = masterNode.surfaceType == SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent; int queue = HDRenderQueue.ChangeType(renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue); // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool transparentBackfaceActive = transparent && masterNode.backThenFrontRendering.isOn; bool transparentDepthPrepassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPrepass.isOn; bool transparentDepthPostpassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPostpass.isOn; GenerateShaderPassHair(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); if (transparentBackfaceActive) { GenerateShaderPassHair(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths); } if (transparentDepthPrepassActive) { GenerateShaderPassHair(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths); } // Assign define here based on opaque or transparent to save some variant m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent; GenerateShaderPassHair(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); if (transparentDepthPostpassActive) { GenerateShaderPassHair(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths); } } subShader.Deindent(); subShader.AddShaderChunk("}", true); subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HairGUI"""); return(subShader.GetShaderString(0)); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HDLitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("bac1a9627cfec924fa2ea9c65af8eeca")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HDLitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", false); subShader.AddShaderChunk("{", false); subShader.Indent(); { //Handle data migration here as we need to have a renderingPass already set with accurate data at this point. if (masterNode.renderingPass == HDRenderQueue.RenderQueueType.Unknown) { switch (masterNode.surfaceType) { case SurfaceType.Opaque: masterNode.renderingPass = HDRenderQueue.RenderQueueType.Opaque; break; case SurfaceType.Transparent: #pragma warning disable CS0618 // Type or member is obsolete if (masterNode.m_DrawBeforeRefraction) { masterNode.m_DrawBeforeRefraction = false; #pragma warning restore CS0618 // Type or member is obsolete masterNode.renderingPass = HDRenderQueue.RenderQueueType.PreRefraction; } else { masterNode.renderingPass = HDRenderQueue.RenderQueueType.Transparent; } break; default: throw new System.ArgumentException("Unknown SurfaceType"); } } // Add tags at the SubShader level int queue = HDRenderQueue.ChangeType(masterNode.renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue); // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool distortionActive = transparent && masterNode.distortion.isOn; bool transparentBackfaceActive = transparent && masterNode.backThenFrontRendering.isOn; bool transparentDepthPrepassActive = transparent && masterNode.alphaTestDepthPrepass.isOn; bool transparentDepthPostpassActive = transparent && masterNode.alphaTestDepthPostpass.isOn; GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassDepthOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassGBuffer, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); if (distortionActive) { GenerateShaderPassLit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths); } if (transparentBackfaceActive) { GenerateShaderPassLit(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths); } // Assign define here based on opaque or transparent to save some variant m_PassForward.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent; GenerateShaderPassLit(masterNode, m_PassForward, mode, subShader, sourceAssetDependencyPaths); if (transparentDepthPrepassActive) { GenerateShaderPassLit(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths); } if (transparentDepthPostpassActive) { GenerateShaderPassLit(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths); } } subShader.Deindent(); subShader.AddShaderChunk("}", false); #if ENABLE_RAYTRACING if (mode == GenerationMode.ForReals) { subShader.AddShaderChunk("SubShader", false); subShader.AddShaderChunk("{", false); subShader.Indent(); { GenerateShaderPassLit(masterNode, m_PassRaytracingIndirect, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassRaytracingVisibility, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassRaytracingForward, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", false); } #endif subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HDLitGUI"""); return(subShader.GetShaderString(0)); }
protected virtual void BaseMaterialPropertiesGUI() { SurfaceTypePopup(); if (surfaceTypeValue == SurfaceType.Transparent) { EditorGUI.indentLevel++; if (blendMode != null && showBlendModePopup) { BlendModePopup(); } EditorGUI.indentLevel++; if (enableBlendModePreserveSpecularLighting != null && blendMode != null && showBlendModePopup) { m_MaterialEditor.ShaderProperty(enableBlendModePreserveSpecularLighting, StylesBaseUnlit.enableBlendModePreserveSpecularLightingText); } EditorGUI.indentLevel--; if (transparentSortPriority != null) { EditorGUI.BeginChangeCheck(); m_MaterialEditor.ShaderProperty(transparentSortPriority, StylesBaseUnlit.transparentSortPriorityText); if (EditorGUI.EndChangeCheck()) { transparentSortPriority.floatValue = HDRenderQueue.ClampsTransparentRangePriority((int)transparentSortPriority.floatValue); } } if (enableFogOnTransparent != null) { m_MaterialEditor.ShaderProperty(enableFogOnTransparent, StylesBaseUnlit.enableTransparentFogText); } if (transparentBackfaceEnable != null) { m_MaterialEditor.ShaderProperty(transparentBackfaceEnable, StylesBaseUnlit.transparentBackfaceEnableText); } if (transparentDepthPrepassEnable != null) { m_MaterialEditor.ShaderProperty(transparentDepthPrepassEnable, StylesBaseUnlit.transparentDepthPrepassEnableText); } if (transparentDepthPostpassEnable != null) { m_MaterialEditor.ShaderProperty(transparentDepthPostpassEnable, StylesBaseUnlit.transparentDepthPostpassEnableText); } EditorGUI.indentLevel--; } // This function must finish with double sided option (see LitUI.cs) if (doubleSidedEnable != null) { m_MaterialEditor.ShaderProperty(doubleSidedEnable, StylesBaseUnlit.doubleSidedEnableText); } if (alphaCutoffEnable != null) { m_MaterialEditor.ShaderProperty(alphaCutoffEnable, StylesBaseUnlit.alphaCutoffEnableText); } if (alphaCutoffEnable != null && alphaCutoffEnable.floatValue == 1.0f) { EditorGUI.indentLevel++; m_MaterialEditor.ShaderProperty(alphaCutoff, StylesBaseUnlit.alphaCutoffText); if (useShadowThreshold != null) { m_MaterialEditor.ShaderProperty(useShadowThreshold, StylesBaseUnlit.useShadowThresholdText); } if (alphaCutoffShadow != null && useShadowThreshold != null && useShadowThreshold.floatValue == 1.0f) { EditorGUI.indentLevel++; m_MaterialEditor.ShaderProperty(alphaCutoffShadow, StylesBaseUnlit.alphaCutoffShadowText); EditorGUI.indentLevel--; } // With transparent object and few specific materials like Hair, we need more control on the cutoff to apply // This allow to get a better sorting (with prepass), better shadow (better silhouettes fidelity) etc... if (surfaceTypeValue == SurfaceType.Transparent) { if (transparentDepthPrepassEnable != null && transparentDepthPrepassEnable.floatValue == 1.0f) { m_MaterialEditor.ShaderProperty(alphaCutoffPrepass, StylesBaseUnlit.alphaCutoffPrepassText); } if (transparentDepthPostpassEnable != null && transparentDepthPostpassEnable.floatValue == 1.0f) { m_MaterialEditor.ShaderProperty(alphaCutoffPostpass, StylesBaseUnlit.alphaCutoffPostpassText); } } EditorGUI.indentLevel--; } }