fishy facepunch

This commit is contained in:
2023-05-31 12:47:21 -04:00
parent 12779859cd
commit 6a28112faa
338 changed files with 2161 additions and 58 deletions

View File

@ -1,139 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
namespace Adobe.Substance
{
/// <summary>
/// Utility class for dynamically import substance plugin.
/// </summary>
internal class DLLHelpers
{
[DllImport("kernel32", SetLastError = true)]
protected static extern IntPtr LoadLibraryW([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true)]
protected static extern IntPtr GetProcAddress(IntPtr hModule, string procname);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("libdl")]
protected static extern IntPtr dlopen(string filename, int flags);
[DllImport("libdl")]
protected static extern IntPtr dlsym(IntPtr handle, string symbol);
[DllImport("libdl")]
protected static extern IntPtr dlerror();
[DllImport("libdl")]
protected static extern int dlclose(IntPtr handle);
internal static IntPtr DllHandle = IntPtr.Zero;
private static object[] mParams = new object[0];
internal static object[] GetParams(int size)
{
Array.Resize<object>(ref mParams, size);
return mParams;
}
internal static void LoadDLL(string dllPath)
{
if (DllHandle == IntPtr.Zero)
{
if (IsWindows())
{
var oldWD = System.IO.Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(Path.GetDirectoryName(dllPath));
DllHandle = LoadLibraryW(dllPath);
if (DllHandle == IntPtr.Zero)
{
var error = Marshal.GetLastWin32Error();
Debug.LogError($"LoadLibraryW error: {error}");
}
Directory.SetCurrentDirectory(oldWD);
}
else if (IsMac() || IsLinux())
{
DllHandle = dlopen(dllPath, 3);
if (DllHandle == IntPtr.Zero)
{
IntPtr errorMessage = dlerror();
Debug.LogError($"dlerror: {Marshal.PtrToStringAnsi(errorMessage)}");
}
}
if (DllHandle == IntPtr.Zero)
throw new ArgumentException($"Fail to load substance engine: {dllPath}");
}
}
internal static void UnloadDLL()
{
if (DllHandle != IntPtr.Zero)
{
if (IsWindows())
{
FreeLibrary(DllHandle);
}
else if (IsMac() || IsLinux())
{
dlclose(DllHandle);
}
DllHandle = IntPtr.Zero;
}
}
internal static Delegate GetFunction(string funcname, Type t)
{
IntPtr ptr = IntPtr.Zero;
if (DllHandle == IntPtr.Zero)
return null;
if (IsWindows())
{
ptr = GetProcAddress(DllHandle, funcname);
}
else if (IsMac() || IsLinux())
{
ptr = dlsym(DllHandle, funcname);
}
if (ptr == IntPtr.Zero)
{
return null;
}
return Marshal.GetDelegateForFunctionPointer(ptr, t);
}
private static bool IsWindows()
{
return (Application.platform == RuntimePlatform.WindowsEditor
|| Application.platform == RuntimePlatform.WindowsPlayer);
}
private static bool IsMac()
{
return (Application.platform == RuntimePlatform.OSXEditor
|| Application.platform == RuntimePlatform.OSXPlayer);
}
private static bool IsLinux()
{
return (Application.platform == RuntimePlatform.LinuxEditor
|| Application.platform == RuntimePlatform.LinuxPlayer);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f6de90137b2a18d46b64f75e11af9249
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,425 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Adobe.Substance
{
/// <summary>
/// Extensions for handling enum type convertion.
/// </summary>
internal static class Extensions
{
/// <summary>
/// Transforms a unity value type enum into an enum used by native code.
/// </summary>
/// <param name="unityType">Unity enum.</param>
/// <returns>Native enum.</returns>
internal static ValueType ToNative(this SubstanceValueType unityType)
{
switch (unityType)
{
case SubstanceValueType.Float:
return ValueType.SBSARIO_VALUE_FLOAT;
case SubstanceValueType.Float2:
return ValueType.SBSARIO_VALUE_FLOAT2;
case SubstanceValueType.Float3:
return ValueType.SBSARIO_VALUE_FLOAT3;
case SubstanceValueType.Float4:
return ValueType.SBSARIO_VALUE_FLOAT4;
case SubstanceValueType.Int:
return ValueType.SBSARIO_VALUE_INT;
case SubstanceValueType.Int2:
return ValueType.SBSARIO_VALUE_INT2;
case SubstanceValueType.Int3:
return ValueType.SBSARIO_VALUE_INT3;
case SubstanceValueType.Int4:
return ValueType.SBSARIO_VALUE_INT4;
case SubstanceValueType.Image:
return ValueType.SBSARIO_VALUE_IMAGE;
case SubstanceValueType.String:
return ValueType.SBSARIO_VALUE_STRING;
case SubstanceValueType.Font:
return ValueType.SBSARIO_VALUE_FONT;
default:
throw new System.InvalidOperationException($"Value type {unityType} can not be converted to native enum.");
}
}
/// <summary>
/// Transforms a native value type enum into an enum used by the unity plugin.
/// </summary>
/// <param name="nativeType">Native enum.</param>
/// <returns>Unity enum.</returns>
internal static SubstanceValueType ToUnity(this ValueType nativeType)
{
switch (nativeType)
{
case ValueType.SBSARIO_VALUE_FLOAT:
return SubstanceValueType.Float;
case ValueType.SBSARIO_VALUE_FLOAT2:
return SubstanceValueType.Float2;
case ValueType.SBSARIO_VALUE_FLOAT3:
return SubstanceValueType.Float3;
case ValueType.SBSARIO_VALUE_FLOAT4:
return SubstanceValueType.Float4;
case ValueType.SBSARIO_VALUE_INT:
return SubstanceValueType.Int;
case ValueType.SBSARIO_VALUE_INT2:
return SubstanceValueType.Int2;
case ValueType.SBSARIO_VALUE_INT3:
return SubstanceValueType.Int3;
case ValueType.SBSARIO_VALUE_INT4:
return SubstanceValueType.Int4;
case ValueType.SBSARIO_VALUE_IMAGE:
return SubstanceValueType.Image;
case ValueType.SBSARIO_VALUE_STRING:
return SubstanceValueType.String;
case ValueType.SBSARIO_VALUE_FONT:
return SubstanceValueType.Font;
default:
throw new System.InvalidOperationException($"Value type {nativeType} can not be converted to unity enum.");
}
}
internal static SubstanceWidgetType ToUnity(this WidgetType nativeType)
{
switch (nativeType)
{
case WidgetType.SBSARIO_WIDGET_NOWIDGET:
return SubstanceWidgetType.NoWidget;
case WidgetType.SBSARIO_WIDGET_SLIDER:
return SubstanceWidgetType.Slider;
case WidgetType.SBSARIO_WIDGET_ANGLE:
return SubstanceWidgetType.Angle;
case WidgetType.SBSARIO_WIDGET_COLOR:
return SubstanceWidgetType.Color;
case WidgetType.SBSARIO_WIDGET_TOGGLEBUTTON:
return SubstanceWidgetType.ToggleButton;
case WidgetType.SBSARIO_WIDGET_COMBOBOX:
return SubstanceWidgetType.ComboBox;
case WidgetType.SBSARIO_WIDGET_IMAGE:
return SubstanceWidgetType.Image;
case WidgetType.SBSARIO_WIDGET_POSITION:
return SubstanceWidgetType.Position;
default:
throw new System.InvalidOperationException($"Value type {nativeType} can not be converted to unity enum.");
}
}
internal static string GetMessage(this ErrorCode code)
{
switch (code)
{
case ErrorCode.SBSARIO_ERROR_OK:
return "No error has occurred";
case ErrorCode.SBSARIO_ERROR_STATE:
return "Call made with an invalid state";
case ErrorCode.SBSARIO_ERROR_INVALID:
return "An invalid argument was given to the api";
case ErrorCode.SBSARIO_ERROR_UNKNOWN:
return "An unspecified error has occurred";
case ErrorCode.SBSARIO_ERROR_FAILURE:
return "The operation failed to complete";
default:
return "No error has occurred";
}
}
public static HVFlip ToSubstance(this TextureFlip flip)
{
switch (flip)
{
case TextureFlip.None:
return HVFlip.SBSARIO_HVFLIP_NO;
case TextureFlip.Horizontal:
return HVFlip.SBSARIO_HVFLIP_HORIZONTAL;
case TextureFlip.Vertical:
return HVFlip.SBSARIO_HVFLIP_VERTICAL;
case TextureFlip.Both:
return HVFlip.SBSARIO_HVFLIP_BOTH;
default:
throw new System.InvalidOperationException($"Unable to convert {flip} to native enum.");
}
}
public static ChannelOrder GetChannelOrder(this TextureFormat unityFormat)
{
switch (unityFormat)
{
case TextureFormat.RGB24:
case TextureFormat.RGBA32:
case TextureFormat.RGBA64:
case TextureFormat.RGB48:
return ChannelOrder.SBSARIO_CHANNEL_ORDER_RGBA;
case TextureFormat.BGRA32:
return ChannelOrder.SBSARIO_CHANNEL_ORDER_BGRA;
default:
return ChannelOrder.SBSARIO_CHANNEL_ORDER_INVALID;
}
}
#region Image Format
public static ImageFormat ToSubstance(this TextureFormat unityFormat)
{
switch (unityFormat)
{
//Byte types.
case TextureFormat.BGRA32:
case TextureFormat.RGBA32:
return ImageFormat.SBSARIO_IMAGE_FORMAT_8B | ImageFormat.SBSARIO_IMAGE_FORMAT_RGBA | ImageFormat.SBSARIO_IMAGE_FORMAT_INT;
case TextureFormat.RGB24:
return ImageFormat.SBSARIO_IMAGE_FORMAT_8B | ImageFormat.SBSARIO_IMAGE_FORMAT_RGB | ImageFormat.SBSARIO_IMAGE_FORMAT_INT;
case TextureFormat.R8:
return ImageFormat.SBSARIO_IMAGE_FORMAT_8B | ImageFormat.SBSARIO_IMAGE_FORMAT_L | ImageFormat.SBSARIO_IMAGE_FORMAT_INT;
//Short types
case TextureFormat.R16:
return ImageFormat.SBSARIO_IMAGE_FORMAT_16B | ImageFormat.SBSARIO_IMAGE_FORMAT_L | ImageFormat.SBSARIO_IMAGE_FORMAT_INT;
case TextureFormat.RGBA64:
return ImageFormat.SBSARIO_IMAGE_FORMAT_16B | ImageFormat.SBSARIO_IMAGE_FORMAT_RGBA | ImageFormat.SBSARIO_IMAGE_FORMAT_INT;
//Float types
case TextureFormat.RGBAFloat:
return ImageFormat.SBSARIO_IMAGE_FORMAT_32B | ImageFormat.SBSARIO_IMAGE_FORMAT_RGBA | ImageFormat.SBSARIO_IMAGE_FORMAT_FLOAT;
case TextureFormat.RFloat:
return ImageFormat.SBSARIO_IMAGE_FORMAT_32B | ImageFormat.SBSARIO_IMAGE_FORMAT_L | ImageFormat.SBSARIO_IMAGE_FORMAT_FLOAT;
//Half types
case TextureFormat.RGBAHalf:
return ImageFormat.SBSARIO_IMAGE_FORMAT_16B | ImageFormat.SBSARIO_IMAGE_FORMAT_RGBA | ImageFormat.SBSARIO_IMAGE_FORMAT_FLOAT;
case TextureFormat.RHalf:
return ImageFormat.SBSARIO_IMAGE_FORMAT_16B | ImageFormat.SBSARIO_IMAGE_FORMAT_L | ImageFormat.SBSARIO_IMAGE_FORMAT_FLOAT;
default:
throw new ArgumentException($"Texture format {unityFormat} not supported.");
}
}
/// <summary>
/// Convert Substance Texture Format to Unity Texture Format
/// </summary>
internal static TextureFormat ToUnityFormat(this ImageFormat imageFormat)
{
var channelCount = ChannelCount(imageFormat);
var bytesPerChannel = GetBytesPerChannel(imageFormat);
if (imageFormat.HasMask(ImageFormat.SBSARIO_IMAGE_FORMAT_FLOAT))
{
if (channelCount == 1)
{
if (bytesPerChannel == 2)
{
return TextureFormat.RHalf;
}
else if (bytesPerChannel == 4)
{
return TextureFormat.RFloat;
}
}
else if (channelCount == 2)
{
if (bytesPerChannel == 2)
{
return TextureFormat.RGHalf;
}
else if (bytesPerChannel == 4)
{
return TextureFormat.RGFloat;
}
}
else if (channelCount == 4)
{
if (bytesPerChannel == 2)
{
return TextureFormat.RGBAHalf;
}
else if (bytesPerChannel == 4)
{
return TextureFormat.RGBAFloat;
}
}
}
else
{
if (channelCount == 1)
{
if (bytesPerChannel == 1)
{
return TextureFormat.R8;
}
else if (bytesPerChannel == 2)
{
return TextureFormat.R16;
}
}
else if (channelCount == 2)
{
if (bytesPerChannel == 1)
{
return TextureFormat.RG16;
}
else if (bytesPerChannel == 2)
{
return TextureFormat.RG32;
}
}
else if (channelCount == 3)
{
if (bytesPerChannel == 1)
{
return TextureFormat.RGB24;
}
else if (bytesPerChannel == 2)
{
return TextureFormat.RGB48;
}
}
else if (channelCount == 4)
{
if (bytesPerChannel == 1)
{
return TextureFormat.RGBA32;
}
else if (bytesPerChannel == 2)
{
return TextureFormat.RGBA64;
}
}
}
Debug.LogError($"Not supported image format with channel count = {channelCount} and bytes per channel = {bytesPerChannel}");
throw new FormatException();
}
internal static int GetSizeWithMipMaps(this NativeDataImage imageData)
{
int width = (int)imageData.width;
int height = (int)imageData.height;
int mipCount = (int)imageData.mipmaps;
ImageFormat imageFormat = imageData.image_format;
var bytesPerPixel = GetBytesPerChannel(imageFormat) * ChannelCount(imageFormat);
if (width == 0 || height == 0)
return 0;
int size = 0;
for (int i = 0; i < mipCount; i++)
{
size += width * height * bytesPerPixel;
width >>= 1;
height >>= 1;
if (width < 1) width = 1;
if (height < 1) height = 1;
}
return size;
}
internal static int GetSize(this NativeDataImage imageData)
{
int width = (int)imageData.width;
int height = (int)imageData.height;
ImageFormat imageFormat = imageData.image_format;
if (width <= 0 || height <= 0)
return 0;
var bytesPerPixel = GetBytesPerChannel(imageFormat) * ChannelCount(imageFormat);
return width * height * bytesPerPixel;
}
internal static int GetBytesPerChannel(this ImageFormat imageFormat)
{
switch (imageFormat & ImageFormat.SBSARIO_IMAGE_FORMAT_BITDEPTH_MASK)
{
case ImageFormat.SBSARIO_IMAGE_FORMAT_32B:
return 4;
case ImageFormat.SBSARIO_IMAGE_FORMAT_16B:
return 2;
case ImageFormat.SBSARIO_IMAGE_FORMAT_8B:
return 1;
default:
return 1;
}
}
internal static int ChannelCount(this ImageFormat imageFormat)
{
switch (imageFormat & ImageFormat.SBSARIO_IMAGE_FORMAT_CHANNELS_MASK)
{
case ImageFormat.SBSARIO_IMAGE_FORMAT_RGBA:
case ImageFormat.SBSARIO_IMAGE_FORMAT_RGBX:
return 4;
case ImageFormat.SBSARIO_IMAGE_FORMAT_RGB:
return 3;
case ImageFormat.SBSARIO_IMAGE_FORMAT_L:
return 1;
default:
return 4;
}
}
private static bool HasMask(this ImageFormat imageFormat, ImageFormat mask)
{
return ((imageFormat & mask) != 0);
}
#endregion Image Format
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9c5e4a2f5172f424faa88416d0c6d9e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,26 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Adobe.Substance
{
public static class Globals
{
public static Texture2D CreateColoredTexture(int pWidth, int pHeight, Color pColor)
{
Texture2D t;
Color[] pix = new Color[pWidth * pHeight];
for (int i = 0; i < pix.Length; i++)
{
pix[i] = pColor;
}
t = new Texture2D(pWidth, pHeight);
t.SetPixels(pix);
t.Apply();
return t;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0e4a1c6b6e4f9724c81d3a821a8642b9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,396 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Adobe.Substance
{
public static class MaterialUtils
{
/// <summary>
/// Default shader for the HDRP pipeline.
/// </summary>
private const string HDRPShaderName = "HDRP/Lit";
/// <summary>
/// Default shader for the URP pipeline.
/// </summary>
private const string URPShaderName = "Universal Render Pipeline/Lit";
/// <summary>
/// Default shader for the Standard unity render pipeline.
/// </summary>
private const string StandardShaderName = "Standard";
/// <summary>
/// Table for converting substance output names to textures inputs in HDRP shaders.
/// </summary>
private static readonly IReadOnlyDictionary<string, string> HDRPOutputTable = new Dictionary<string, string>()
{
{ "basecolor", "_BaseColorMap"},
{ "diffuse", "_BaseColorMap" },
{ "mask", "_MaskMap" },
{ "normal", "_NormalMap" },
{ "height", "_HeightMap" },
{ "emissive", "_EmissiveColorMap" },
{ "specular", "_SpecularColorMap" },
{ "detailMask", "_DetailMask" },
{ "opacity", "_OpacityMap" },
{ "glossiness", "_GlossinessMap" },
{ "ambientocclusion", "_OcclusionMap" },
{ "metallic", "_MetallicGlossMap" },
{ "roughness", "_RoughnessMap" }
};
/// <summary>
/// Table for converting substance output names to textures inputs in URP shaders.
/// </summary>
private static readonly IReadOnlyDictionary<string, string> URPOutputTable = new Dictionary<string, string>()
{
{ "basecolor" , "_BaseMap" },
{ "diffuse", "_BaseMap" },
{ "normal" , "_BumpMap" },
{ "height" ,"_ParallaxMap" },
{ "emissive" , "_EmissionMap" },
{ "specular" , "_SpecGlossMap" },
{ "ambientocclusion" , "_OcclusionMap" },
{ "metallic" , "_MetallicGlossMap" },
{ "mask" , "_MaskMap" },
{ "detailMask" , "_DetailMask" },
{ "opacity" ,"_OpacityMap" },
{ "glossiness" ,"_GlossinessMap" },
{ "roughness" ,"_RoughnessMap" }
};
/// <summary>
/// Table for converting substance output names to textures inputs in unity Standard pipeline shaders.
/// </summary>
private static readonly IReadOnlyDictionary<string, string> StandardOutputTable = new Dictionary<string, string>()
{
{ "basecolor", "_MainTex" },
{ "diffuse", "_MainTex" },
{ "normal" , "_BumpMap" },
{ "height" ,"_ParallaxMap" },
{ "emissive" ,"_EmissionMap" },
{ "specular" ,"_SpecGlossMap" },
{ "specularlevel" ,"_SpecularLevelMap" },
{ "opacity", "_OpacityMap" },
{ "glossiness" ,"_GlossinessMap" },
{ "ambientocclusion" ,"_OcclusionMap" },
{ "detailmask" ,"_DetailMask" },
{ "metallic" ,"_MetallicGlossMap" },
{ "roughness" ,"_RoughnessMap" }
};
private static IReadOnlyDictionary<string, string> GetTextureMappingDictionary()
{
if (PluginPipelines.IsHDRP())
return HDRPOutputTable;
if (PluginPipelines.IsURP())
return URPOutputTable; // for now
return StandardOutputTable;
}
public static void AssignOutputTexturesToMaterial(SubstanceGraphSO graph)
{
foreach (var output in graph.Output)
{
if (output.OutputTexture == null)
continue;
Texture2D texture = output.OutputTexture;
var shaderTextureName = output.MaterialTextureTarget;
EnableShaderKeywords(graph.OutputMaterial, shaderTextureName);
graph.OutputMaterial.SetTexture(shaderTextureName, texture);
}
var smoothnessChannel = GetSmoothnessChannelAssignment(graph);
graph.OutputMaterial.SetInt("_SmoothnessTextureChannel", smoothnessChannel);
graph.OutputMaterial.SetFloat("_Glossiness", 1.0f);
graph.OutputMaterial.SetFloat("_Smoothness", 1.0f);
graph.OutputMaterial.SetFloat("_OcclusionStrength", 1.0f);
var opacityOutput = graph.Output.FirstOrDefault(a => a.IsOpacity());
}
public static string GetUnityTextureName(SubstanceOutputDescription description)
{
var dictionary = GetTextureMappingDictionary();
if (dictionary.TryGetValue(description.Channel.ToLower(), out string result))
return result;
return string.Empty;
}
private static void EnableShaderKeywords(Material material, string shaderTextureName)
{
if (shaderTextureName == "_BumpMap")
{
material.EnableKeyword("_NORMALMAP");
}
else if (shaderTextureName == "_EmissionMap")
{
// Enables emission for the material, and make the material use
// realtime emission.
material.EnableKeyword("_EMISSION");
material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
// Update the emission color and intensity of the material.
material.SetColor("_EmissionColor", Color.white);
// Inform Unity's GI system to recalculate GI based on the new emission map.
DynamicGI.UpdateEnvironment();
}
else if (shaderTextureName == "_ParallaxMap")
{
material.EnableKeyword("_PARALLAXMAP");
}
else if (shaderTextureName == "_MetallicGlossMap")
{
if (PluginPipelines.IsURP())
material.EnableKeyword("_METALLICSPECGLOSSMAP");
else
material.EnableKeyword("_METALLICGLOSSMAP");
}
}
/// <summary>
/// Returns 1 if smoothness is assigned to _MainTex alpha channel and 0 if it is assigned to metallic map alpha channel.
/// </summary>
/// <param name="graph">Target substance graph.</param>
/// <returns>0 or 1 depending on the smoothness channel assignment. </returns>
private static int GetSmoothnessChannelAssignment(SubstanceGraphSO graph)
{
var baseColorOutput = graph.Output.FirstOrDefault(a => a.IsBaseColor());
//Check if smoothness is assigned to baseColor.
if (baseColorOutput != null)
if (baseColorOutput.AlphaChannel == "roughness" || baseColorOutput.AlphaChannel == "glossiness")
return 1;
//Check if smoothness is assigned to diffuse.
var diffuseOutput = graph.Output.FirstOrDefault(a => a.IsDiffuse());
if (diffuseOutput != null)
if (diffuseOutput.AlphaChannel == "roughness" || diffuseOutput.AlphaChannel == "glossiness")
return 1;
//Assumes it is assinged to metallic map.
return 0;
}
public static bool CheckIfStandardOutput(SubstanceOutputDescription description)
{
if (PluginPipelines.IsHDRP())
{
return CheckIfHRPStandardOutput(description);
}
else if (PluginPipelines.IsURP())
{
return CheckIfURPStandardOutput(description);
}
//Unity Standard render pipeline.
return CheckIfStandardPipelineOutput(description);
}
private static bool CheckIfURPStandardOutput(SubstanceOutputDescription description)
{
if (description == null)
return false;
if (string.IsNullOrEmpty(description.Channel))
return false;
if (string.Equals(description.Channel, "baseColor", StringComparison.OrdinalIgnoreCase)
|| string.Equals(description.Channel, "diffuse", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (!URPOutputTable.TryGetValue(description.Channel, out string shaderValue))
return false;
var material = new Material(GetStandardShader());
return material.HasProperty(shaderValue);
}
private static bool CheckIfHRPStandardOutput(SubstanceOutputDescription description)
{
if (description == null)
return false;
if (string.IsNullOrEmpty(description.Channel))
return false;
switch (description.Channel)
{
case "baseColor":
return true;
case "normal":
return true;
case "mask":
return true;
case "height":
return true;
case "emissive":
return true;
default:
return false;
}
}
private static bool CheckIfStandardPipelineOutput(SubstanceOutputDescription description)
{
if (description == null)
return false;
if (string.IsNullOrEmpty(description.Channel))
return false;
var channel = description.Channel.ToLower();
if ("basecolor" == channel)
return true;
if (!StandardOutputTable.TryGetValue(channel, out string shaderValue))
return false;
var material = new Material(GetStandardShader());
return material.HasProperty(shaderValue);
}
public static Shader GetStandardShader()
{
if (PluginPipelines.IsHDRP())
return Shader.Find(HDRPShaderName);
else if (PluginPipelines.IsURP())
return Shader.Find(URPShaderName);
return Shader.Find(StandardShaderName);
}
public static bool CheckIfBGRA(SubstanceOutputDescription description)
{
if (Application.platform == RuntimePlatform.WindowsEditor
|| Application.platform == RuntimePlatform.WindowsPlayer)
{
return false;
}
if (Application.platform == RuntimePlatform.OSXEditor
|| Application.platform == RuntimePlatform.OSXPlayer)
{
return false;
}
switch (description.Channel)
{
case "baseColor":
case "diffuse":
case "emissive":
case "normal":
return true;
default:
return false;
}
}
#region PhysicalSize
public static void ApplyPhysicalSize(Material material, Vector3 physicalSize, bool enablePhysicalSize)
{
if (PluginPipelines.IsHDRP())
ApplyPhysicalSizeHDRP(material, physicalSize, enablePhysicalSize);
}
public static Vector3 GetPhysicalSizePositionOffset(Material material)
{
if (PluginPipelines.IsHDRP())
return GetPhysicalSizePositionOffsetHDRP(material);
return new Vector3(0, 0, 0);
}
public static void SetPhysicalSizePositionOffset(Material material, Vector3 offset)
{
if (PluginPipelines.IsHDRP())
SetPhysicalSizePositionOffsetHDRP(material, offset);
}
private static void ApplyPhysicalSizeHDRP(Material material, Vector3 physicalSize, bool enablePhysicalSize)
{
if (enablePhysicalSize)
{
material.SetFloat("_UVBase", 5);
material.SetFloat("_UVEmissive", 5);
material.SetFloat("_TexWorldScale", 100);
material.EnableKeyword("_MAPPING_PLANAR");
material.EnableKeyword("_EMISSIVE_MAPPING_TRIPLANAR");
material.mainTextureScale = new Vector2(1f / physicalSize.x, 1f / physicalSize.y);
}
else
{
material.SetFloat("_UVBase", 0);
material.SetFloat("_UVEmissive", 0);
material.SetFloat("_TexWorldScale", 1);
material.DisableKeyword("_MAPPING_PLANAR");
material.DisableKeyword("_EMISSIVE_MAPPING_TRIPLANAR");
material.mainTextureScale = new Vector2(1, 1);
}
}
public static Vector3 GetPhysicalSizePositionOffsetHDRP(Material material)
{
return material.GetTextureOffset("_BaseColorMap");
}
public static void SetPhysicalSizePositionOffsetHDRP(Material material, Vector3 offset)
{
material.SetTextureOffset("_BaseColorMap", offset);
material.SetTextureOffset("_EmissiveColorMap", offset);
}
#endregion PhysicalSize
#region Live output assignment
public static void UpdateTextureTarget(Material material, Texture2D texture, string oldstring, string newString)
{
material.SetTexture(oldstring, null);
if (!string.IsNullOrEmpty(newString))
material.SetTexture(newString, texture);
}
public static void EnableEmissionIfAssigned(Material material)
{
var emissionTextureName = GetTextureMappingDictionary()["emissive"];
if (material.GetTexture(emissionTextureName) != null)
{
material.EnableKeyword("_EMISSION");
material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
material.SetColor("_EmissionColor", Color.white);
}
else
{
material.DisableKeyword("_EMISSION");
material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.SetColor("_EmissionColor", Color.black);
}
}
#endregion Live output assignment
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 827772ab50908334dbe1a1d6330de2db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,9 +0,0 @@
namespace Adobe.Substance
{
public static class PathUtils
{
public const string SubstanceRootPath = "Assets/Adobe/Substance3DForUnity/";
public const bool UsingPackageManager = true;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 42ae3f27cd9a68f4d870bfd4359d9c2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,129 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using System;
using System.IO;
namespace Adobe.Substance
{
/// <summary>
/// Utility functions for platform specific setup.
/// </summary>
public static class PlatformUtils
{
public static bool IsCPU()
{
if (Application.platform == RuntimePlatform.OSXPlayer ||
#if UNITY_2021_3_OR_NEWER
Application.platform == RuntimePlatform.OSXServer ||
#endif
Application.platform == RuntimePlatform.OSXEditor)
{
return false;
}
else if (Application.platform == RuntimePlatform.LinuxPlayer ||
#if UNITY_2021_3_OR_NEWER
Application.platform == RuntimePlatform.LinuxServer ||
#endif
Application.platform == RuntimePlatform.LinuxEditor)
{
return false;
}
else if (Application.platform == RuntimePlatform.WindowsPlayer ||
#if UNITY_2021_3_OR_NEWER
Application.platform == RuntimePlatform.WindowsServer ||
#endif
Application.platform == RuntimePlatform.WindowsEditor)
{
return false;
}
return true;
}
/// <summary>
/// Get full path to the appropriate substance engine based on the current graphics API.
/// </summary>
/// <returns>Path to the substance engine.</returns>
public static string GetEnginePath()
{
var engineName = GetEngineName();
return GetPluginLibraryPath(engineName);
}
/// <summary>
/// Get the path to the substance plugin (Only used when plugin is dynamically loaded).
/// </summary>
/// <returns>Path to the unity plugin.</returns>
public static string GetPluginPath()
{
var pluginName = GetPluginName();
return GetPluginLibraryPath(pluginName);
}
private static string GetPluginLibraryPath(string libraryName)
{
#if UNITY_EDITOR
var path = $"{PathUtils.SubstanceRootPath}/Runtime/Plugins/{libraryName}";
return Path.GetFullPath(path);
#elif UNITY_STANDALONE_WIN
return Path.Combine(Path.Combine(Path.Combine(Application.dataPath, "Plugins"), "x86_64"), libraryName);
#elif UNITY_EDITOR_OSX
return Path.Combine(Path.Combine(Application.dataPath, "PlugIns"), libraryName);
#else
return Path.Combine(Path.Combine(Application.dataPath, "Plugins"), libraryName);
#endif
}
/// <summary>
/// Get engine library name.
/// </summary>
/// <returns>Substance engien name.</returns>
private static string GetEngineName()
{
if (Application.platform == RuntimePlatform.LinuxEditor
|| Application.platform == RuntimePlatform.LinuxPlayer)
{
return "libsubstance_ogl3_blend.so";
}
else if (Application.platform == RuntimePlatform.OSXEditor
|| Application.platform == RuntimePlatform.OSXPlayer)
{
return "libsubstance_mtl_blend.dylib";
}
else if (Application.platform == RuntimePlatform.WindowsEditor
|| Application.platform == RuntimePlatform.WindowsPlayer)
{
return "substance_d3d11pc_blend.dll";
}
else
{
return string.Empty;
}
}
private static string GetPluginName()
{
switch (Application.platform)
{
case RuntimePlatform.OSXEditor:
case RuntimePlatform.OSXPlayer:
return "libsbsario.dylib";
case RuntimePlatform.LinuxPlayer:
case RuntimePlatform.LinuxEditor:
return "libsbsario.so";
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
return "sbsario.dll";
default:
return string.Empty;
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 82fc31b1374aa6240bac67b4a6b6ac33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,240 +0,0 @@
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);
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5abbd1d56696db6478aa75a922351727
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,46 +0,0 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace Adobe.Substance
{
/// <summary>
/// Provides utility extensions to copy data from substance to unity textures.
/// </summary>
internal static class TextureExtensions
{
internal static byte[] Color32ArrayToByteArray(Color32[] colors)
{
if (colors == null || colors.Length == 0)
return null;
int length = Marshal.SizeOf(typeof(Color32)) * colors.Length;
byte[] bytes = new byte[length];
GCHandle handle = default(GCHandle);
try
{
handle = GCHandle.Alloc(colors, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();
Marshal.Copy(ptr, bytes, 0, length);
}
finally
{
if (handle != default(GCHandle))
handle.Free();
}
return bytes;
}
internal static Color32[] FlipY(Color32[] input, int width, int height)
{
Color32[] output = new Color32[input.Length];
for (int y = 0, i = 0, o = output.Length - width; y < height; y++, i += width, o -= width)
Array.Copy(input, i, output, o, width);
return output;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 17a6348e48c5de84498a4c2ad3caff6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,95 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Adobe.Substance
{
public static class TextureOutputExtensions
{
public static bool IsDiffuse(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "diffuse");
}
public static bool IsNormalMap(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "normal");
}
public static bool IsBaseColor(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "basecolor");
}
public static bool IsRoughness(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "roughness");
}
public static bool IsOpacity(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "opacity");
}
public static bool IsHightMap(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "height");
}
public static bool IsMetallicness(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "metallic");
}
public static bool IsSpecular(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "specular");
}
public static bool IsOcclusion(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "ambientocclusion");
}
public static bool IsEmissive(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "emissive");
}
public static bool IsDetail(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "detailmask");
}
public static bool IsHDRPMask(this SubstanceOutputTexture output)
{
return CheckChannelName(output, "mask");
}
private static bool CheckChannelName(SubstanceOutputTexture output, string channelName)
{
var label = output.Description.Channel;
return string.Equals(label, channelName, System.StringComparison.OrdinalIgnoreCase);
}
public static bool IsStandardOutput(this SubstanceOutputTexture output, Material material)
{
if (string.IsNullOrEmpty(output.MaterialTextureTarget))
return false;
if (material == null)
return output.IsStandardOutput();
#if UNITY_2021_1_OR_NEWER
return material.HasTexture(output.MaterialTextureTarget);
#else
return material.HasProperty(output.MaterialTextureTarget);
#endif
}
public static bool IsStandardOutput(this SubstanceOutputTexture output)
{
return MaterialUtils.CheckIfStandardOutput(output.Description);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 603e384ac1d32cc469fcb01910e701ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,9 +0,0 @@
namespace Adobe.Substance
{
public static class Version
{
public const string PluginVersion = "3.6.0-5-gfab1c7f";
public const string EngineVersion = "8.2.0 0138644d";
public const int ImporterVersion = 360;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 62d136a2c8fa01b4eb83bb3320de89af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: