240 lines
9.4 KiB
C#
240 lines
9.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace Adobe.Substance
|
|
{
|
|
public static class RenderingUtils
|
|
{
|
|
public static void ConfigureOutputTextures(SubstanceNativeGraph nativeGraph, SubstanceGraphSO graph, bool runtimeUsage = false)
|
|
{
|
|
if (PluginPipelines.IsDEFAULT() || PluginPipelines.IsURP())
|
|
{
|
|
AssignSmoothnessToAlpha(nativeGraph, graph);
|
|
}
|
|
if (PluginPipelines.IsHDRP())
|
|
{
|
|
CreateHDRPMaskMap(nativeGraph, graph);
|
|
}
|
|
|
|
AssignOpacityToAlpha(nativeGraph, graph);
|
|
CreateOutputVirtualCopies(nativeGraph, graph);
|
|
|
|
if (!runtimeUsage)
|
|
ChangeRBChannel(nativeGraph, graph);
|
|
|
|
//For some reason we have to call it twice. (Bug in the substance engine?)
|
|
UpdateAlphaChannelsAssignment(nativeGraph, graph);
|
|
UpdateAlphaChannelsAssignment(nativeGraph, graph);
|
|
}
|
|
|
|
public static void UpdateAlphaChannelsAssignment(SubstanceNativeGraph nativeGraph, SubstanceGraphSO graph)
|
|
{
|
|
foreach (var output in graph.Output)
|
|
{
|
|
var outputID = output.Index;
|
|
var targetIndex = output.Description.Index;
|
|
var invert = output.InvertAssignedAlpha;
|
|
var outputCopy = output.VirtualOutputIndex;
|
|
|
|
if (output.IsAlphaAssignable && string.IsNullOrEmpty(output.AlphaChannel))
|
|
{
|
|
nativeGraph.ResetAlphaChannelAssignment(outputCopy);
|
|
continue;
|
|
}
|
|
|
|
var alphaTarget = graph.Output.FirstOrDefault(a => a.Description.Label == output.AlphaChannel);
|
|
|
|
if (alphaTarget != null)
|
|
{
|
|
var alphaSourceIndex = alphaTarget.Description.Index;
|
|
nativeGraph.AssignOutputToAlphaChannel(outputCopy, alphaSourceIndex, invert);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void AssignOpacityToAlpha(SubstanceNativeGraph nativeGraph, SubstanceGraphSO graph)
|
|
{
|
|
var opacityOutput = graph.Output.FirstOrDefault(a => a.IsOpacity());
|
|
|
|
if (opacityOutput == null)
|
|
return;
|
|
|
|
var baseColorOutput = graph.Output.FirstOrDefault(a => a.IsBaseColor());
|
|
var diffuseOutput = graph.Output.FirstOrDefault(a => a.IsDiffuse());
|
|
|
|
if (baseColorOutput != null)
|
|
{
|
|
if (string.IsNullOrEmpty(baseColorOutput.AlphaChannel))
|
|
{
|
|
baseColorOutput.AlphaChannel = opacityOutput.Description.Label;
|
|
baseColorOutput.InvertAssignedAlpha = false;
|
|
}
|
|
}
|
|
|
|
if (diffuseOutput != null)
|
|
{
|
|
if (string.IsNullOrEmpty(diffuseOutput.AlphaChannel))
|
|
{
|
|
diffuseOutput.AlphaChannel = opacityOutput.Description.Label;
|
|
diffuseOutput.InvertAssignedAlpha = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void AssignSmoothnessToAlpha(SubstanceNativeGraph nativeGraph, SubstanceGraphSO graph)
|
|
{
|
|
var roughtnessOutput = graph.Output.FirstOrDefault(a => a.IsRoughness());
|
|
var metallicOutput = graph.Output.FirstOrDefault(a => a.IsMetallicness());
|
|
var diffuseOutput = graph.Output.FirstOrDefault(a => a.IsDiffuse());
|
|
var baseColorOutput = graph.Output.FirstOrDefault(a => a.IsBaseColor());
|
|
var specularOutput = graph.Output.FirstOrDefault(a => a.IsSpecular());
|
|
|
|
if (roughtnessOutput != null && (metallicOutput != null || specularOutput != null))
|
|
{
|
|
if (metallicOutput != null)
|
|
{
|
|
if (string.IsNullOrEmpty(metallicOutput.AlphaChannel))
|
|
{
|
|
metallicOutput.AlphaChannel = roughtnessOutput.Description.Label;
|
|
metallicOutput.InvertAssignedAlpha = true;
|
|
}
|
|
}
|
|
|
|
if (specularOutput != null)
|
|
{
|
|
if (string.IsNullOrEmpty(specularOutput.AlphaChannel))
|
|
{
|
|
specularOutput.AlphaChannel = roughtnessOutput.Description.Label;
|
|
specularOutput.InvertAssignedAlpha = true;
|
|
}
|
|
}
|
|
}
|
|
else if (roughtnessOutput != null && baseColorOutput != null)
|
|
{
|
|
if (string.IsNullOrEmpty(baseColorOutput.AlphaChannel))
|
|
{
|
|
baseColorOutput.AlphaChannel = roughtnessOutput.Description.Label;
|
|
baseColorOutput.InvertAssignedAlpha = true;
|
|
}
|
|
}
|
|
else if (roughtnessOutput != null && diffuseOutput != null)
|
|
{
|
|
if (string.IsNullOrEmpty(diffuseOutput.AlphaChannel))
|
|
{
|
|
diffuseOutput.AlphaChannel = roughtnessOutput.Description.Label;
|
|
diffuseOutput.InvertAssignedAlpha = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void CreateOutputVirtualCopies(SubstanceNativeGraph nativeGraph, SubstanceGraphSO graph)
|
|
{
|
|
foreach (var output in graph.Output)
|
|
{
|
|
if (output.IsVirtual)
|
|
continue;
|
|
|
|
var outputIndex = output.Index;
|
|
var newIndex = nativeGraph.CreateOutputCopy(outputIndex);
|
|
output.VirtualOutputIndex = newIndex;
|
|
}
|
|
}
|
|
|
|
private static void CreateHDRPMaskMap(SubstanceNativeGraph nativeGraph, SubstanceGraphSO graph)
|
|
{
|
|
uint flags = 0;
|
|
|
|
//Red = Metallic
|
|
var metallicnessOutput = graph.Output.FirstOrDefault(a => a.IsMetallicness());
|
|
|
|
var outputChannel0Info = SubstanceVirtualOutputChannelInfo.Black;
|
|
var outputChannel1Info = SubstanceVirtualOutputChannelInfo.Black;
|
|
var outputChannel2Info = SubstanceVirtualOutputChannelInfo.Black;
|
|
var outputChannel3Info = SubstanceVirtualOutputChannelInfo.Black;
|
|
|
|
if (metallicnessOutput != null)
|
|
{
|
|
var mettalicnessOutputUID = nativeGraph.GetOutputUID(metallicnessOutput.Index);
|
|
outputChannel0Info = new SubstanceVirtualOutputChannelInfo(mettalicnessOutputUID);
|
|
}
|
|
|
|
//Green = Occlusion
|
|
var occlusionOutput = graph.Output.FirstOrDefault(a => a.IsOcclusion());
|
|
|
|
if (occlusionOutput != null)
|
|
{
|
|
var occlusionOutputUID = nativeGraph.GetOutputUID(occlusionOutput.Index);
|
|
outputChannel1Info = new SubstanceVirtualOutputChannelInfo(occlusionOutputUID);
|
|
}
|
|
else
|
|
{
|
|
flags += 2;
|
|
}
|
|
|
|
//Blue = Detail mask
|
|
var detailOutput = graph.Output.FirstOrDefault(a => a.IsDetail());
|
|
|
|
if (detailOutput != null)
|
|
{
|
|
var detailOutputUID = nativeGraph.GetOutputUID(detailOutput.Index);
|
|
outputChannel2Info = new SubstanceVirtualOutputChannelInfo(detailOutputUID);
|
|
}
|
|
else
|
|
{
|
|
flags += 4;
|
|
}
|
|
|
|
//Alpha = Smoothness (1 - roughness)
|
|
var roughnessOutput = graph.Output.FirstOrDefault(a => a.IsRoughness());
|
|
|
|
if (roughnessOutput != null)
|
|
{
|
|
var roughnessOutputUID = nativeGraph.GetOutputUID(roughnessOutput.Index);
|
|
outputChannel3Info = new SubstanceVirtualOutputChannelInfo(roughnessOutputUID, ShuffleIndex.Red, true);
|
|
}
|
|
|
|
var outputCreateInfo = new SubstanceVirtualOutputCreateInfo(TextureFormat.RGBA32,
|
|
"mask",
|
|
TextureFlip.Vertical,
|
|
outputChannel0Info,
|
|
outputChannel1Info,
|
|
outputChannel2Info,
|
|
outputChannel3Info);
|
|
|
|
var hdrpMaskOutputDescription = nativeGraph.CreateVirtualOutput(outputCreateInfo);
|
|
|
|
var hdrpMaskOutput = graph.Output.FirstOrDefault(a => a.IsHDRPMask());
|
|
|
|
if (hdrpMaskOutput == null)
|
|
{
|
|
hdrpMaskOutput = new SubstanceOutputTexture(hdrpMaskOutputDescription, "_MaskMap")
|
|
{
|
|
IsVirtual = true,
|
|
IsAlphaAssignable = false,
|
|
VirtualOutputIndex = hdrpMaskOutputDescription.Index
|
|
};
|
|
|
|
graph.Output.Add(hdrpMaskOutput);
|
|
}
|
|
else
|
|
{
|
|
hdrpMaskOutput.Description = hdrpMaskOutputDescription;
|
|
}
|
|
|
|
hdrpMaskOutput.Description.Channel = "mask";
|
|
hdrpMaskOutput.Flags = flags;
|
|
}
|
|
|
|
private static void ChangeRBChannel(SubstanceNativeGraph fileHandler, SubstanceGraphSO graph)
|
|
{
|
|
foreach (var output in graph.Output)
|
|
{
|
|
if (MaterialUtils.CheckIfBGRA(output.Description))
|
|
fileHandler.ChangeOutputRBChannels(output.VirtualOutputIndex);
|
|
}
|
|
}
|
|
}
|
|
} |