fishy facepunch
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6de90137b2a18d46b64f75e11af9249
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c5e4a2f5172f424faa88416d0c6d9e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e4a1c6b6e4f9724c81d3a821a8642b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 827772ab50908334dbe1a1d6330de2db
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,9 +0,0 @@
|
||||
namespace Adobe.Substance
|
||||
{
|
||||
public static class PathUtils
|
||||
{
|
||||
public const string SubstanceRootPath = "Assets/Adobe/Substance3DForUnity/";
|
||||
|
||||
public const bool UsingPackageManager = true;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42ae3f27cd9a68f4d870bfd4359d9c2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82fc31b1374aa6240bac67b4a6b6ac33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5abbd1d56696db6478aa75a922351727
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17a6348e48c5de84498a4c2ad3caff6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 603e384ac1d32cc469fcb01910e701ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62d136a2c8fa01b4eb83bb3320de89af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user