Initial commit

This commit is contained in:
msk
2022-01-22 20:13:49 -08:00
parent f9d23e5bcf
commit 687473573d
878 changed files with 70957 additions and 0 deletions
@@ -0,0 +1,23 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEngine;
public class MinValueAttribute : PropertyAttribute {
public float Min;
public MinValueAttribute(float min) {
Min = min;
}
}
public class MaxValueAttribute : PropertyAttribute {
public float Max;
public MaxValueAttribute(float min) {
Max = min;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 48d3cf2ec372bd34fa4b3bd9f05b6132
timeCreated: 1445390687
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+27
View File
@@ -0,0 +1,27 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEngine;
public static class AlloyUtils {
public const string Name = "Alloy";
public const string Version = "3.6.4";
public const float SectionColorMax = 20.0f;
public const string Path = Name + "/";
public const string MenuItem = "Window/" + Path;
public const string ComponentMenu = Path + Name + " ";
public static string AssetsPath {
get { return Application.dataPath + "/" + Path; }
}
//public static float IntensityToLumens(float intensity) {
// return Mathf.Floor(Mathf.GammaToLinearSpace(intensity) * 100.0f);
//}
//public static float LumensToIntensity(float lumens) {
// return Mathf.LinearToGammaSpace(lumens / 100.0f);
//}
}
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c9500e8a2783ced4aa7f8c3488e304b5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+6
View File
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 608acff29777b4548909fea9555edd26
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
@@ -0,0 +1,178 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
// We don't need this for MeatKit because it gets imported with the game assembly.
/*
#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using UnityEngine;
using UnityEngine.Serialization;
[ExecuteInEditMode]
[RequireComponent(typeof(Light))]
[AddComponentMenu(AlloyUtils.ComponentMenu + "Area Light")]
public class AlloyAreaLight : MonoBehaviour {
// Minimum non-zero value for light size, so we can use sign for specular toggle.
const float c_minimumLightSize = 0.00001f;
// Minimum light intensity to prevent divide by zero (because Epsilon causes infinity).
const float c_minimumLightIntensity = 0.01f;
[HideInInspector]
public Texture2D DefaultSpotLightCookie;
[FormerlySerializedAs("m_size")]
[SerializeField]
float m_radius;
[SerializeField]
float m_length;
[SerializeField]
bool m_hasSpecularHightlight = true;
Light m_light;
Color m_lastColor;
float m_lastIntensity;
float m_lastRange;
Light Light {
get {
// Ensures that we have the light component, even if light is disabled.
if (m_light == null)
m_light = GetComponent<Light>();
return m_light;
}
}
public float Radius {
get { return m_radius; }
set {
if (m_radius != value) {
m_radius = value;
UpdateBinding();
}
}
}
public float Length {
get { return m_length; }
set {
if (m_length != value) {
m_length = value;
UpdateBinding();
}
}
}
public bool HasSpecularHighlight {
get { return m_hasSpecularHightlight; }
set {
if (m_hasSpecularHightlight != value) {
m_hasSpecularHightlight = value;
UpdateBinding();
}
}
}
void Reset() {
m_hasSpecularHightlight = true;
m_radius = 0.0f;
m_length = 0.0f;
m_lastColor = Color.black;
m_lastIntensity = 0.0f;
m_lastRange = 0.0f;
UpdateBinding();
}
// Must run after all other light scripts and animation clips.
void LateUpdate() {
var l = Light;
// Poll the Light component, since we can't extend it.
if (l.color != m_lastColor
|| l.intensity != m_lastIntensity
|| l.range != m_lastRange) {
UpdateBinding();
}
}
public void UpdateBinding() {
var l = Light;
var color = l.color;
var intensity = l.intensity;
var range = l.range;
#if UNITY_EDITOR
EnsureCookie();
#endif
if (l.type == LightType.Directional) {
m_radius = Mathf.Clamp01(m_radius);
color.a = 10.0f * m_radius; // Cancel 0.1 * n in the shader.
}
else {
// Radius packed into fractional component of number.
var maxRadius = range;
m_radius = Mathf.Clamp(m_radius, 0.0f, maxRadius);
color.a = Mathf.Min(0.999f, m_radius / maxRadius);
if (l.type == LightType.Point) {
// Length packed into integer component of number.
var maxLength = 2.0f * range;
m_length = Mathf.Clamp(m_length, 0.0f, maxLength);
color.a += Mathf.Ceil(1000.0f * Mathf.Min(1.0f, m_length / maxLength));
}
}
// Specular highlight toggle in sign component of number.
color.a = Mathf.Max(c_minimumLightSize, color.a); // Must be non-zero!
color.a *= (m_hasSpecularHightlight ? 1.0f : -1.0f);
// Cancel Unity's implicit intensity multiply.
color.a /= Mathf.Max(intensity, c_minimumLightIntensity);
l.color = color;
m_lastColor = color;
m_lastIntensity = intensity;
m_lastRange = range;
}
#if UNITY_EDITOR
public void EnsureCookie() {
var l = Light;
if (l.type == LightType.Spot && l.cookie == null) {
l.cookie = DefaultSpotLightCookie;
EditorUtility.SetDirty(this);
} else if (l.type == LightType.Point && l.cookie == DefaultSpotLightCookie) {
l.cookie = null;
EditorUtility.SetDirty(this);
}
}
#endif
// DEPRECATED BEGIN
[Obsolete("Please use Unity Light component's \"color\" field.")]
public Color Color {
get { return Light.color; }
set { Light.color = value; }
}
[Obsolete("Please use Unity Light component's \"intensity\" field.")]
public float Intensity {
get { return Light.intensity; }
set { Light.intensity = value; }
}
[Obsolete("No longer used. Please remove all references to it.")]
public bool IsAnimated { get; set; }
// DEPRECATED END
}
*/
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: e13ed666bcef6874386610d2ef878488
timeCreated: 1468958632
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences:
- DefaultSpotLightCookie: {fileID: 2800000, guid: d21bb2c11f0e5a2498a9ecc9cccfab62,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: bc738ca46cba47944874e267a234d9a9
folderAsset: yes
timeCreated: 1468957796
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,79 @@
fileFormatVersion: 2
guid: d21bb2c11f0e5a2498a9ecc9cccfab62
timeCreated: 1442345799
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 1
linearTexture: 0
correctGamma: 0
fadeOut: 0
borderMipMap: 1
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: 1
aniso: 0
mipBias: 0
wrapMode: 1
nPOTScale: 1
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 5
buildTargetSettings:
- buildTarget: iPhone
maxTextureSize: 128
textureFormat: 33
compressionQuality: 50
allowsAlphaSplitting: 0
- buildTarget: Android
maxTextureSize: 128
textureFormat: 13
compressionQuality: 50
allowsAlphaSplitting: 0
- buildTarget: BlackBerry
maxTextureSize: 128
textureFormat: 13
compressionQuality: 50
allowsAlphaSplitting: 0
- buildTarget: WP8
maxTextureSize: 128
textureFormat: 12
compressionQuality: 50
allowsAlphaSplitting: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 0e3681edec2f2044bbbc59c604b43ec3
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
@@ -0,0 +1,190 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEngine;
using UnityEditor;
#if H3VR_IMPORTED
[CustomEditor(typeof(AlloyAreaLight))]
[CanEditMultipleObjects]
public class AlloyAreaLightEditor : Editor {
public override void OnInspectorGUI() {
serializedObject.Update();
var hasSpecularHightlight = serializedObject.FindProperty("m_hasSpecularHightlight");
var maxRange = float.MaxValue;
var isSpecularAreaLight = false;
var isPointLight = false;
// Light Type.
foreach (AlloyAreaLight area in targets) {
var light = area.GetComponent<Light>();
if (light.type == LightType.Directional) {
maxRange = 1.0f;
}
else {
maxRange = Mathf.Min(light.range, maxRange);
}
isPointLight = light.type == LightType.Point;
if (isPointLight
|| light.type == LightType.Spot
|| light.type == LightType.Directional) {
isSpecularAreaLight = true;
}
}
// Specular Highlight.
if (isSpecularAreaLight) {
hasSpecularHightlight.boolValue = EditorGUILayout.Toggle("Specular Highlight", hasSpecularHightlight.boolValue);
isSpecularAreaLight = isSpecularAreaLight && hasSpecularHightlight.boolValue;
}
// Radius.
if (isSpecularAreaLight) {
EditorGUILayout.Slider(serializedObject.FindProperty("m_radius"), 0.0f, maxRange);
} else {
var radius = serializedObject.FindProperty("m_radius");
if (radius.floatValue != 0.0f) {
GUI.changed = true;
radius.floatValue = 0.0f;
}
}
// Length.
if (isSpecularAreaLight && isPointLight) {
EditorGUILayout.Slider(serializedObject.FindProperty("m_length"), 0.0f, maxRange * 2.0f);
} else {
var length = serializedObject.FindProperty("m_length");
if (length.floatValue != 0.0f) {
GUI.changed = true;
length.floatValue = 0.0f;
}
}
serializedObject.ApplyModifiedProperties();
if (GUI.changed) {
foreach (AlloyAreaLight area in targets) {
area.UpdateBinding();
}
}
}
internal static void DrawTwoShadedWireDisc(Vector3 position, Vector3 axis, float radius) {
Color color1 = Handles.color;
Color color2 = color1;
color1.a *= 0.2f;
Handles.color = color1;
Handles.DrawWireDisc(position, axis, radius);
Handles.color = color2;
}
internal static void DrawTwoShadedWireDisc(Vector3 position, Vector3 axis, Vector3 from, float degrees, float radius) {
Handles.DrawWireArc(position, axis, from, degrees, radius);
Color cur = Handles.color;
Color set = cur;
set.a *= 0.2f;
Handles.color = set;
Handles.DrawWireArc(position, axis, from, degrees - 360f, radius);
Handles.color = cur;
}
static Vector3[] s_directionArray = {
Vector3.right,
Vector3.up,
Vector3.forward,
-Vector3.right,
-Vector3.up,
-Vector3.forward
};
static void DoRadiusHandle(Vector3 position, float radius, float length) {
Vector3 dif = position - Camera.current.transform.position;
float sqrMagnitude = dif.sqrMagnitude;
float radiusSqr = radius * radius;
float radiusDiv = radiusSqr * radiusSqr / sqrMagnitude;
//float ratio = radiusDiv / radiusSqr;
float total = Mathf.Sqrt(radiusSqr - radiusDiv);
Handles.DrawWireDisc(position - radiusSqr * dif / sqrMagnitude, dif, total);
for (int j = 0; j < 3; j++) {
float angle = Vector3.Angle(dif, s_directionArray[j]);
angle = 90f - Mathf.Min(angle, 180f - angle);
float tanAngle = Mathf.Tan(angle * Mathf.Deg2Rad);
float viewSize = Mathf.Sqrt(radiusDiv + tanAngle * tanAngle * radiusDiv) / radius;
if (viewSize < 1f) {
float finalArcAngle = Mathf.Asin(viewSize) * Mathf.Rad2Deg;
Vector3 vector2 = Vector3.Cross(s_directionArray[j], dif).normalized;
vector2 = Quaternion.AngleAxis(finalArcAngle, s_directionArray[j]) * vector2;
DrawTwoShadedWireDisc(position, s_directionArray[j], vector2, (90f - finalArcAngle) * 2f, radius);
}
else {
DrawTwoShadedWireDisc(position, s_directionArray[j], radius);
}
}
}
float DrawCapsuleGizmo(Transform transform, float radius, float length) {
var fwd = Vector3.forward * radius;
var side = Vector3.up * radius;
var halfLength = 0.5f * length;
// Exclude light transform scale, and pre-rotate capsule to follow the Y-axis.
Handles.matrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0.0f, 0.0f, 90.0f), Vector3.one);
Handles.DrawWireArc(-halfLength * Vector3.right, Vector3.forward, Vector3.up, 180.0f, radius);
Handles.DrawWireArc(-halfLength * Vector3.right, Vector3.up, -Vector3.forward, 180.0f, radius);
Handles.DrawWireArc(halfLength * Vector3.right, Vector3.forward, -Vector3.up, 180.0f, radius);
Handles.DrawWireArc(halfLength * Vector3.right, Vector3.up, Vector3.forward, 180.0f, radius);
Handles.DrawWireDisc(-halfLength * Vector3.right, Vector3.right, radius);
Handles.DrawWireDisc(halfLength * Vector3.right, Vector3.right, radius);
Handles.DrawLine(-halfLength * Vector3.right + fwd, halfLength * Vector3.right + fwd);
Handles.DrawLine(-halfLength * Vector3.right - fwd, halfLength * Vector3.right - fwd);
Handles.DrawLine(-halfLength * Vector3.right + side, halfLength * Vector3.right + side);
Handles.DrawLine(-halfLength * Vector3.right - side, halfLength * Vector3.right - side);
if (!Event.current.alt && !Event.current.shift) {
radius = Handles.RadiusHandle(Quaternion.identity, -halfLength * Vector3.right, radius, true);
radius = Handles.RadiusHandle(Quaternion.identity, halfLength * Vector3.right, radius, true);
}
Handles.matrix = Matrix4x4.identity;
return radius;
}
void OnSceneGUI() {
var area = target as AlloyAreaLight;
var light = area.GetComponent<Light>();
if (light.type == LightType.Point
|| light.type == LightType.Spot) {
area.Radius = DrawCapsuleGizmo(area.transform, area.Radius, area.Length);
}
//DoRadiusHandle(area.transform.position, area.Size, 1.0f);
if (GUI.changed) {
Undo.RecordObject(area, "Adjust area light");
}
}
}
#endif
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 895b6d1a02c68594f89e4586bdfff530
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,51 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEditor;
using UnityEngine;
public static class AlloyLightCreator {
#if H3VR_IMPORTED
const string c_lightMenuPath = "GameObject/Light/";
const string c_undoMessage = "Created ";
const string c_directionalLight = "Alloy Directional Light";
const string c_pointLight = "Alloy Point Light";
const string c_spotLight = "Alloy Spotlight";
[MenuItem(c_lightMenuPath + c_directionalLight)]
static void CreateDirectionalLight() {
BuildLight(c_directionalLight, LightType.Directional);
}
[MenuItem(c_lightMenuPath + c_pointLight)]
static void CreateSphereAreaLight() {
BuildLight(c_pointLight, LightType.Point);
}
[MenuItem(c_lightMenuPath + c_spotLight)]
static void CreateSpotSphereAreaLight() {
BuildLight(c_spotLight, LightType.Spot);
}
static void BuildLight(string name, LightType type) {
var go = new GameObject();
var lastSceneView = SceneView.lastActiveSceneView;
Undo.RegisterCreatedObjectUndo(go, c_undoMessage + name);
go.name = name;
var light = go.AddComponent<Light>();
light.type = type;
go.AddComponent<AlloyAreaLight>();
if (lastSceneView != null)
go.transform.position = lastSceneView.pivot;
else
go.transform.position = Vector3.zero;
Selection.activeGameObject = go;
}
#endif
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f5d3ae613b034fe4599db89f5c75351a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,67 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.Linq;
using System.Reflection;
using MeatKit;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Light))]
[CanEditMultipleObjects]
public class AlloyLightEditor : Editor {
#if H3VR_IMPORTED
Editor m_editor;
Action m_onSceneGUIReflected;
Type GetTypeGlobal(string typeName) {
return AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypesSafe()).FirstOrDefault(t => t.Name == typeName);
}
void OnEnable() {
m_editor = CreateEditor(targets, GetTypeGlobal("LightEditor"));
Undo.undoRedoPerformed += RebindAreaLights;
RebindAreaLights();
m_onSceneGUIReflected = (Action)Delegate.CreateDelegate(typeof(Action), m_editor, "OnSceneGUI", false, true);
}
void OnSceneGUI() {
m_onSceneGUIReflected();
}
void OnDisable() {
Undo.undoRedoPerformed -= RebindAreaLights;
//Calls on destroy on light editor
DestroyImmediate(m_editor);
}
public override void OnInspectorGUI() {
m_editor.OnInspectorGUI();
bool anyMissing = targets.Any(l => ((Light)l).GetComponent<Light>().type != LightType.Area
&& ((Light)l).GetComponent<AlloyAreaLight>() == null);
if (anyMissing) {
if (GUILayout.Button("Convert to Alloy area light", EditorStyles.toolbarButton)) {
foreach (Light light in targets) {
Undo.AddComponent<AlloyAreaLight>(light.gameObject);
}
}
}
if (GUI.changed) {
RebindAreaLights();
}
}
void RebindAreaLights() {
var lights = targets.Select(l => ((Light)l).GetComponent<AlloyAreaLight>()).Where(a => a != null);
foreach (AlloyAreaLight ar in lights) {
ar.UpdateBinding();
}
}
#endif
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f83832185bd1caa4d9aab41ddfbc423d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+6
View File
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 301e9fbda97de0d41a1f555dc127b9c9
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
@@ -0,0 +1,61 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEngine;
using System.Collections.Generic;
using UnityEditor;
public static class AlloyEditor {
public static void DrawAddTabGUI(List<AlloyTabAdd> tabsToAdd) {
if (tabsToAdd.Count <= 0) {
return;
}
GUI.color = new Color(0.8f, 0.8f, 0.8f, 0.8f);
GUILayout.Label("");
var rect = GUILayoutUtility.GetLastRect();
rect.x -= 35.0f;
rect.width += 10.0f;
GUI.color = Color.clear;
bool add = GUI.Button(rect, new GUIContent(""), "Box");
GUI.color = new Color(0.8f, 0.8f, 0.8f, 0.8f);
Rect subRect = rect;
foreach (var tab in tabsToAdd) {
GUI.color = tab.Color;
GUI.Box(subRect, "", "ShurikenModuleTitle");
subRect.x += rect.width / tabsToAdd.Count;
subRect.width -= rect.width / tabsToAdd.Count;
}
GUI.color = new Color(0.8f, 0.8f, 0.8f, 0.8f);
var delRect = rect;
delRect.xMin = rect.xMax;
delRect.xMax += 40.0f;
if (GUI.Button(delRect, "", "ShurikenModuleTitle") || add) {
var menu = new GenericMenu();
foreach (var tab in tabsToAdd) {
menu.AddItem(new GUIContent(tab.Name), false, tab.Enable);
}
menu.ShowAsContext();
}
delRect.x += 10.0f;
GUI.Label(delRect, "+");
rect.x += EditorGUIUtility.currentViewWidth / 2.0f - 30.0f;
// Ensures tab text is always white, even when using light skin in pro.
GUI.color = EditorGUIUtility.isProSkin ? new Color(0.7f, 0.7f, 0.7f) : new Color(0.9f, 0.9f, 0.9f);
GUI.Label(rect, "Add tab", EditorStyles.whiteLabel);
GUI.color = Color.white;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dd3f45d6cfc037e43baa01683c2ead46
timeCreated: 1447518555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEditor;
using UnityEngine;
public static class AlloyMenuGroups {
[MenuItem(AlloyUtils.MenuItem + "Documentation", false, 100)]
static void Documentation() {
Application.OpenURL("https://alloy.rustltd.com/documentation");
}
[MenuItem(AlloyUtils.MenuItem + "Samples", false, 100)]
static void Samples() {
Application.OpenURL("https://www.assetstore.unity3d.com/en/#!/content/43687");
}
[MenuItem(AlloyUtils.MenuItem + "Contact", false, 100)]
static void Contact() {
Application.OpenURL("https://alloy.rustltd.com/contact");
}
[MenuItem(AlloyUtils.MenuItem + "About", false, 100)]
static void About() {
Application.OpenURL("https://alloy.rustltd.com/");
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 85976895d5de5ee4f914e54f4aae9905
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,289 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.Collections.Generic;
using System.Linq;
using System.IO;
using UnityEditor;
using UnityEngine;
public static class AlloyMigrationTools {
#if H3VR_IMPORTED
private const string keywordReportFilename = "/Alloy/Scripts/Material Report.txt";
[MenuItem(AlloyUtils.MenuItem + "Material Report", false, 11)]
private static void MaterialReport() {
var fileName = Application.dataPath + keywordReportFilename;
var sr = File.CreateText(fileName);
var materials = GetSceneMaterialsWithKeywords().OrderBy(m => m.name);
var keywordList = materials
.SelectMany(m => m.shaderKeywords)
.Where(k => !string.IsNullOrEmpty(k))
.Distinct()
.OrderBy(k => k);
var keywordCount = keywordList.Count();
var materialShaderNames = new List<string>();
sr.WriteLine(" ");
sr.WriteLine("-----------------------------------------------------------------------");
sr.WriteLine(" Keywords: " + keywordCount);
sr.WriteLine("-----------------------------------------------------------------------");
foreach (var keyword in keywordList) {
sr.WriteLine("\"" + keyword + "\",");
}
sr.WriteLine(" ");
sr.WriteLine("-----------------------------------------------------------------------");
sr.WriteLine(" Keywords -> Materials: " + keywordCount);
sr.WriteLine("-----------------------------------------------------------------------");
foreach (var keyword in keywordList) {
sr.WriteLine("\"" + keyword + "\",");
foreach (var material in materials) {
var shaderKeywords = material.shaderKeywords;
if (shaderKeywords.Contains(keyword)) {
sr.WriteLine(" " + material.name);
}
}
sr.WriteLine(" ");
}
sr.WriteLine("-----------------------------------------------------------------------");
sr.WriteLine(" Materials -> Keywords: " + materials.Count());
sr.WriteLine("-----------------------------------------------------------------------");
foreach (var material in materials) {
var shaderKeywords = material.shaderKeywords.OrderBy(k => k);
sr.WriteLine(material.name);
foreach (var keyword in shaderKeywords) {
if (!string.IsNullOrEmpty(keyword)) {
sr.WriteLine(" \"" + keyword + "\",");
}
}
sr.WriteLine(" ");
materialShaderNames.Add(material.shader.name);
}
var shaderNames = materialShaderNames.Distinct().OrderBy(s => s);
sr.WriteLine("-----------------------------------------------------------------------");
sr.WriteLine(" Shaders -> Materials: " + shaderNames.Count());
sr.WriteLine("-----------------------------------------------------------------------");
foreach (var shaderName in shaderNames) {
var shaderMaterials = materials.Where(m => m.shader.name == shaderName).Select(m => m.name);
sr.WriteLine("\"" + shaderName + "\"");
foreach (var materialName in shaderMaterials) {
if (!string.IsNullOrEmpty(materialName)) {
sr.WriteLine(" " + materialName);
}
}
sr.WriteLine(" ");
}
sr.Close();
System.Diagnostics.Process.Start(fileName);
}
// [MenuItem(AlloyUtils.MenuItem + "Material Migrator", false, 11)]
// private static void MaterialMigrator() {
// var window = ScriptableObject.CreateInstance<AlloyMaterialMigratorPopup>();
// var dimensions = new Vector2(350, 100);
//
// window.position = new Rect(Screen.width / 2, Screen.height / 2, 0, 0);
// window.minSize = dimensions;
// window.maxSize = dimensions;
// window.ShowUtility();
// }
[MenuItem(AlloyUtils.MenuItem + "Light Converter", false, 11)]
private static void LightConverter() {
var lights = Resources.FindObjectsOfTypeAll<Light>();
var lightsLength = lights.Length;
for (int i = 0; i < lightsLength; i++) {
var light = lights[i];
EditorUtility.DisplayProgressBar(
"Converting lights...",
string.Format("Light {0} / {1}.", i + 1, lightsLength),
i / (lightsLength - 1.0f));
// Skip Unity baked Area Lights & Prefabs.
if (light.type != LightType.Area
&& !EditorUtility.IsPersistent(light)) {
var area = light.GetComponent<AlloyAreaLight>();
if (area == null) {
Undo.RecordObject(light.gameObject, "Convert to Alloy area lights.");
area = Undo.AddComponent<AlloyAreaLight>(light.gameObject);
}
Undo.RecordObject(light, "Set default light cookie");
area.UpdateBinding();
}
}
EditorUtility.ClearProgressBar();
}
private static IEnumerable<Material> GetSceneMaterialsWithKeywords() {
return Resources.FindObjectsOfTypeAll<Material>().Where(m => m.shaderKeywords.Length > 0);
}
}
public class AlloyMaterialMigratorPopup : EditorWindow {
private const string messageFilename = "/Alloy/Scripts/Editor/MaterialMigratorWarning.txt";
private static string[] keywordsToRemove = new string[] {
"_AO2MAPUV_UV0",
"_AO2MAPUV_UV1",
"_BLENDMAPUV_UV0",
"_BLENDMAPUV_UV1",
"_BUMPMODE_BUMP",
"_BUMPMODE_PARALLAX", // Set by stupid KeywordEnum.
"_BUMPMODE_SPOM",
"_CARFLAKEMAPUV_UV0",
"_CARFLAKEMAPUV_UV1",
"_DECAL_OFF",
"_DECALMODE_NONE",
"_DECALTEXUV_UV0",
"_DECALTEXUV_UV1",
"_DETAIL_ON", // Replaced with _DETAIL_MULX2
"_DETAILALBEDOMAPUV_UV0",
"_DETAILALBEDOMAPUV_UV1",
"_DETAILMASKSSOURCE_TEXTURE", // From when I was trying that Masks channel picker idea. >_<
"_DETAILMASKSOURCE_TEXTURE", // Discarded first attempt at name.
"_DETAILMASKSOURCE_TEXTUREALPHA", // Set by stupid KeywordEnum.
"_DETAILMASKSOURCE_VERTEXCOLORALPHA", // Replaced with _NORMALMAP
"_DETAILMODE_MUL",
"_DETAILMODE_MULX2",
"_DIRECTIONALBLENDMODE_OBJECT", // Set by stupid KeywordEnum.
"_DISSOLVETEXUV_UV0",
"_DISSOLVETEXUV_UV1",
"_EMISSION_ON",
"_ENVIRONMENTMAPMODE_RSRM",
"_ENVIRONMENTMAPMODE_SKYSHOP",
"_ENVIRONMENTMAPMODE_SKYSHOPSH",
"_INCANDESCENCEMAPUV_UV0",
"_INCANDESCENCEMAPUV_UV1",
"_INCANDESCENCEMAPUV2_UV0",
"_INCANDESCENCEMAPUV2_UV1",
"_MAINTEXTURESMODE_FULL",
"_MAINTEXTURESMODE_LITE",
"_MAINTEXTURESROUGHNESSSOURCE_BASECOLORALPHA", // Discarded first attempt at name.
"_MAINTEXTURESROUGHNESSSOURCE_MATERIALALPHA", // Discarded first attempt at name.
"_MAINROUGHNESSSOURCE_BASECOLORALPHA", // Replaced with _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
"_MAINROUGHNESSSOURCE_PACKEDMAPALPHA", // Set by stupid KeywordEnum.
"_ORIENTEDROUGHNESSSOURCE_BASECOLORALPHA", // Replaced with _SPECGLOSSMAP
"_ORIENTEDROUGHNESSSOURCE_PACKEDMAPALPHA", // Set by stupid KeywordEnum.
"_ORIENTEDTEXTURESMODE_FULL",
"_ORIENTEDTEXTURESMODE_LITE",
"_ORIENTEDTEXTURESROUGHNESSSOURCE_BASECOLORALPHA", // Discarded first attempt at name.
"_ORIENTEDTEXTURESROUGHNESSSOURCE_MATERIALALPHA", // Discarded first attempt at name.
"_PARALLAX_ON", // Replaced with _PARALLAXMAP
"_RIMTEXUV_UV0",
"_RIMTEXUV_UV1",
"_RIMTEXUV2_UV0",
"_RIMTEXUV2_UV1",
"_SECONDARYROUGHNESSSOURCE_BASECOLORALPHA", // Replaced with _METALLICGLOSSMAP
"_SECONDARYROUGHNESSSOURCE_PACKEDMAPALPHA", // Set by stupid KeywordEnum.
"_SECONDARYTEXTURESMODE_FULL",
"_SECONDARYTEXTURESMODE_LITE",
"_TESSELLATIONMODE_COMBINED", // Dropped this mode in favor of using two other modes keywords together.
"_TRANSITIONTEXUV_UV0",
"_TRANSITIONTEXUV_UV1",
"_TRIPLANARMODE_OBJECT", // Set by stupid KeywordEnum.
"_UVSEC_UV0", // Standard shader sets this.
"_UVSEC_UV1", // Standard shader sets this.
};
void OnGUI() {
var message = File.ReadAllText(Application.dataPath + messageFilename);
titleContent = new GUIContent("Migrate Materials?");
EditorGUILayout.LabelField(message, EditorStyles.wordWrappedLabel);
GUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Confirm")) {
Close();
MigrateMaterials();
}
if (GUILayout.Button("Cancel")) {
Close();
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
void MigrateMaterials() {
try {
var materialGuids = AssetDatabase.FindAssets("t:material");
var length = materialGuids.Length;
for (int i = 0; i < length; i++) {
var material = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(materialGuids[i]), typeof(Material)) as Material;
var toRemove = material.shaderKeywords.Intersect(keywordsToRemove);
var shaderName = material.shader.name;
EditorUtility.DisplayProgressBar(
"Migrating Materials...",
string.Format("({0} / {1}) {2}", i, length, material.name),
i / (float)(length - 1));
if (shaderName.Contains("Alloy")) {
if (material.HasProperty("_HasBumpMap")
&& Mathf.Approximately(material.GetFloat("_HasBumpMap"), 1.0f)) {
material.EnableKeyword("EFFECT_BUMP");
}
foreach (var keyword in toRemove) {
if (!string.IsNullOrEmpty(keyword)) {
material.DisableKeyword(keyword);
// Migrate to Unity keywords.
switch (keyword) {
case "_DETAIL_ON":
material.EnableKeyword("_DETAIL_MULX2");
break;
case "_DETAILMASKSOURCE_VERTEXCOLORALPHA":
material.EnableKeyword("_NORMALMAP");
break;
case "_MAINROUGHNESSSOURCE_BASECOLORALPHA":
material.EnableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
break;
case "_PARALLAX_ON":
material.EnableKeyword("_PARALLAXMAP");
break;
}
}
}
EditorUtility.SetDirty(material);
AssetDatabase.SaveAssets();
material = null;
EditorUtility.UnloadUnusedAssetsImmediate();
}
}
}
finally {
EditorUtility.ClearProgressBar();
}
}
#endif
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 222acbd1878d5b3459b1f2946805fba9
timeCreated: 1425000426
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(MinValueAttribute))]
public class MinValueDrawer : PropertyDrawer {
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
EditorGUI.BeginChangeCheck();
float newVal = EditorGUI.FloatField(position, label, property.floatValue);
if (EditorGUI.EndChangeCheck()) {
newVal = Mathf.Max((attribute as MinValueAttribute).Min, newVal);
property.floatValue = newVal;
}
EditorGUI.EndProperty();
}
}
[CustomPropertyDrawer(typeof(MaxValueAttribute))]
public class MaxValueDrawer : PropertyDrawer {
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
EditorGUI.BeginChangeCheck();
float newVal = EditorGUI.FloatField(position, label, property.floatValue);
if (EditorGUI.EndChangeCheck()) {
newVal = Mathf.Min((attribute as MaxValueAttribute).Max, newVal);
property.floatValue = newVal;
}
EditorGUI.EndProperty();
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cd608910999af3a4e960e52f543102ed
timeCreated: 1445390480
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,54 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.IO;
using UnityEngine;
using UnityEditor;
[InitializeOnLoad]
static class AlloyRequiredActions {
static AlloyRequiredActions() {
// Check if popup hasn't appeared for this version.
if (File.Exists(AlloyRequiredActionsPopup.MessageFilePath)
&& EditorPrefs.GetString(AlloyRequiredActionsPopup.SettingsKey) != AlloyUtils.Version) {
var window = ScriptableObject.CreateInstance<AlloyRequiredActionsPopup>();
var dimensions = new Vector2(350, 200);
window.position = new Rect(Screen.width / 2, Screen.height / 2, 0, 0);
window.minSize = dimensions;
window.maxSize = dimensions;
window.ShowUtility();
}
}
}
public class AlloyRequiredActionsPopup : EditorWindow {
public const string SettingsKey = "AlloyRequiredActionsPopupShown";
public static string MessageFilePath {
get { return AlloyUtils.AssetsPath + "REQUIRED ACTIONS.txt"; }
}
void OnGUI() {
var message = File.ReadAllText(MessageFilePath);
titleContent = new GUIContent(string.Format("Required Actions for Alloy {0}...", AlloyUtils.Version));
EditorGUILayout.LabelField(message, EditorStyles.wordWrappedLabel);
GUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Okay")) {
Close();
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
// Make sure it doesn't reappear again for this version.
EditorPrefs.SetString(SettingsKey, AlloyUtils.Version);
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c605d19298efffc45afeb01a1a5086fa
timeCreated: 1473702994
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
We STRONGLY recommend that you save and back up your work before proceeding.
Do you wish to continue?
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e579897034a773341b981f6cb2ab54c6
timeCreated: 1474115145
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d774905ce3293694e97161cbf47d6542
folderAsset: yes
timeCreated: 1439503600
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,288 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
[ImageEffectAllowedInSceneView]
[RequireComponent(typeof (Camera))]
[AddComponentMenu(AlloyUtils.ComponentMenu + "Effects Manager")]
public class AlloyEffectsManager : MonoBehaviour {
// Arbitrary range multiplier.
private const float c_blurWdith = 0.15f;
private const float c_blurDepthDifferenceMultiplier = 100.0f;
private const string c_copyTransmissionBufferName = "AlloyCopyTransmission";
private const string c_blurNormalsBufferName = "AlloyBlurNormals";
private const CameraEvent c_copyTransmissionEvent = CameraEvent.AfterGBuffer;
private const CameraEvent c_blurNormalsEvent = CameraEvent.BeforeLighting;
[Serializable]
public struct SkinSettingsData {
public bool Enabled;
public Texture2D Lut;
[Range(0.0f, 1.0f)]
public float Weight;
[Range(0.01f, 1.0f)]
public float MaskCutoff;
[Range(0.0f, 1.0f)]
public float Bias;
[Range(0.0f, 1.0f)]
public float Scale;
[Range(0.0f, 1.0f)]
public float BumpBlur;
public Vector3 Absorption;
public Vector3 AoColorBleed;
}
[Serializable]
public struct TransmissionSettingsData {
public bool Enabled;
[Range(0.0f, 1.0f)]
public float Weight;
[Range(0.0f, 1.0f)]
public float ShadowWeight;
[Range(0.0f, 1.0f)]
[Tooltip("Amount that the transmission is distorted by surface normals.")]
public float BumpDistortion;
[MinValue(1.0f)]
public float Falloff;
}
public SkinSettingsData SkinSettings = new SkinSettingsData() {
Enabled = true,
Weight = 1.0f,
MaskCutoff = 0.1f,
Bias = 0.0f,
Scale = 1.0f,
BumpBlur = 0.7f,
Absorption = new Vector3(-8.0f, -40.0f, -64.0f),
AoColorBleed = new Vector3(0.4f, 0.15f, 0.13f),
};
public TransmissionSettingsData TransmissionSettings = new TransmissionSettingsData {
Enabled = true,
Weight = 1.0f,
ShadowWeight = 0.5f,
BumpDistortion = 0.05f,
Falloff = 1.0f
};
// LUT
[HideInInspector] public Texture2D SkinLut;
// Shaders
[HideInInspector] public Shader TransmissionBlitShader;
[HideInInspector] public Shader BlurNormalsShader;
// Private
private Material m_deferredTransmissionBlitMaterial;
private Material m_deferredBlurredNormalsMaterial;
private Camera m_camera;
private bool m_isTransmissionEnabled;
private bool m_isScatteringEnabled;
private CommandBuffer m_copyTransmission;
private CommandBuffer m_renderBlurredNormals;
#if UNITY_EDITOR
private int lastWidth = 0;
private int lastHeight = 0;
#endif
private void Awake() {
m_camera = GetComponent<Camera>();
}
private void Reset() {
ResetCommandBuffers();
}
#if UNITY_EDITOR
private void Update() {
if (lastWidth != m_camera.pixelWidth
|| lastHeight != m_camera.pixelHeight) {
ResetCommandBuffers();
}
}
#endif
private void OnEnable() {
ResetCommandBuffers();
}
private void OnDisable() {
DestroyCommandBuffers();
}
private void OnDestroy() {
DestroyCommandBuffers();
}
public void Refresh() {
bool scatteringEnabled = SkinSettings.Enabled;
bool transmissionEnabled = TransmissionSettings.Enabled || scatteringEnabled;
if (m_isTransmissionEnabled == transmissionEnabled
&& m_isScatteringEnabled == scatteringEnabled) {
RefreshProperties();
}
else {
ResetCommandBuffers();
}
}
// Per camera properties.
private void RefreshProperties() {
if (m_isTransmissionEnabled || m_isScatteringEnabled) {
float transmissionWeight = m_isTransmissionEnabled ? Mathf.GammaToLinearSpace(TransmissionSettings.Weight) : 0.0f;
Shader.SetGlobalVector("_DeferredTransmissionParams",
new Vector4(transmissionWeight, TransmissionSettings.Falloff, TransmissionSettings.BumpDistortion, TransmissionSettings.ShadowWeight));
if (m_isScatteringEnabled) {
// Blur shaders.
float distanceToProjectionWindow = 1.0f / Mathf.Tan(0.5f * Mathf.Deg2Rad * m_camera.fieldOfView);
float blurStepScale = c_blurWdith * distanceToProjectionWindow;
float blurDepthDifferenceScale = c_blurDepthDifferenceMultiplier * distanceToProjectionWindow;
Shader.SetGlobalVector("_DeferredBlurredNormalsParams", new Vector2(blurStepScale, blurDepthDifferenceScale));
// Material shaders.
var absorption = SkinSettings.Absorption;
var aoColorBleed = SkinSettings.AoColorBleed;
Shader.SetGlobalTexture("_DeferredSkinLut", SkinSettings.Lut);
Shader.SetGlobalVector("_DeferredSkinParams", new Vector3(SkinSettings.Weight, 1.0f / SkinSettings.MaskCutoff, SkinSettings.BumpBlur));
Shader.SetGlobalVector("_DeferredSkinTransmissionAbsorption", new Vector4(absorption.x, absorption.y, absorption.z, SkinSettings.Bias));
Shader.SetGlobalVector("_DeferredSkinColorBleedAoWeights", new Vector4(aoColorBleed.x, aoColorBleed.y, aoColorBleed.z, SkinSettings.Scale));
}
}
}
private void ResetCommandBuffers() {
m_isScatteringEnabled = SkinSettings.Enabled;
m_isTransmissionEnabled = TransmissionSettings.Enabled || m_isScatteringEnabled;
if (SkinSettings.Lut == null) {
SkinSettings.Lut = SkinLut;
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
DestroyCommandBuffers();
if ((m_isTransmissionEnabled || m_isScatteringEnabled)
&& m_camera != null
&& TransmissionBlitShader != null) {
int outputRT = Shader.PropertyToID("_DeferredPlusBuffer");
#if UNITY_EDITOR
// Reference for when screen size changes.
lastWidth = m_camera.pixelWidth;
lastHeight = m_camera.pixelHeight;
#endif
m_deferredTransmissionBlitMaterial = new Material(TransmissionBlitShader);
m_deferredTransmissionBlitMaterial.hideFlags = HideFlags.HideAndDontSave;
// Copy Gbuffer emission buffer so we can get at the alpha channel for transmission.
m_copyTransmission = new CommandBuffer();
m_copyTransmission.name = c_copyTransmissionBufferName;
if (!m_isScatteringEnabled) {
// Copy transmission from emission buffer alpha.
m_copyTransmission.GetTemporaryRT(outputRT, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
m_copyTransmission.Blit(BuiltinRenderTextureType.CameraTarget, outputRT, m_deferredTransmissionBlitMaterial);
m_copyTransmission.ReleaseTemporaryRT(outputRT);
}
else if (BlurNormalsShader != null) {
int halfWidth = m_camera.pixelWidth / 2;
int halfHeight = m_camera.pixelHeight / 2;
int pingRT = Shader.PropertyToID("_DeferredBlurredNormalPingBuffer");
int pongRT = Shader.PropertyToID("_DeferredBlurredNormalPongBuffer");
// Bind emission buffer to be copied in blurred normal upsample pass.
m_copyTransmission.SetGlobalTexture("_DeferredTransmissionBuffer", BuiltinRenderTextureType.CameraTarget);
// Blur normals and copy transmission.
m_deferredBlurredNormalsMaterial = new Material(BlurNormalsShader);
m_deferredBlurredNormalsMaterial.hideFlags = HideFlags.HideAndDontSave;
m_renderBlurredNormals = new CommandBuffer();
m_renderBlurredNormals.name = c_blurNormalsBufferName;
// RGBA8 target has sufficient precision for normals that are smooth and diffuse-only.
m_renderBlurredNormals.GetTemporaryRT(outputRT, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
m_renderBlurredNormals.GetTemporaryRT(pingRT, halfWidth, halfHeight, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_renderBlurredNormals.GetTemporaryRT(pongRT, halfWidth, halfHeight, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
// Downsample, Blur X, Blur Y, Upsample.
m_renderBlurredNormals.Blit(BuiltinRenderTextureType.GBuffer2, pingRT, m_deferredBlurredNormalsMaterial, 0);
m_renderBlurredNormals.Blit(pingRT, pongRT, m_deferredBlurredNormalsMaterial, 1);
m_renderBlurredNormals.Blit(pongRT, pingRT, m_deferredBlurredNormalsMaterial, 2);
m_renderBlurredNormals.Blit(pingRT, outputRT, m_deferredBlurredNormalsMaterial, 3);
// Cleanup.
m_renderBlurredNormals.ReleaseTemporaryRT(outputRT);
m_renderBlurredNormals.ReleaseTemporaryRT(pingRT);
m_renderBlurredNormals.ReleaseTemporaryRT(pongRT);
// Need depth texture for depth-aware upsample.
m_camera.depthTextureMode |= DepthTextureMode.Depth;
m_camera.AddCommandBuffer(c_blurNormalsEvent, m_renderBlurredNormals);
}
m_camera.AddCommandBuffer(c_copyTransmissionEvent, m_copyTransmission);
}
RefreshProperties();
#if UNITY_EDITOR
EditorUtility.SetDirty(m_camera);
#endif
}
private void DestroyCommandBuffers() {
if (m_copyTransmission != null) {
m_camera.RemoveCommandBuffer(c_copyTransmissionEvent, m_copyTransmission);
}
if (m_renderBlurredNormals != null) {
m_camera.RemoveCommandBuffer(c_blurNormalsEvent, m_renderBlurredNormals);
}
if (m_deferredTransmissionBlitMaterial != null) {
DestroyImmediate(m_deferredTransmissionBlitMaterial);
}
if (m_deferredBlurredNormalsMaterial != null) {
DestroyImmediate(m_deferredBlurredNormalsMaterial);
}
m_copyTransmission = null;
m_renderBlurredNormals = null;
m_deferredTransmissionBlitMaterial = null;
m_deferredBlurredNormalsMaterial = null;
}
}
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: bf5b97b13ec5bae41ac96a39caf39874
timeCreated: 1487764061
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences:
- SkinLut: {fileID: 2800000, guid: d13510bb2be49aa40a66a0101efb6a36, type: 3}
- TransmissionBlitShader: {fileID: 4800000, guid: 4bbeef29a84b4ed498f2d4a7d9fcefc4,
type: 3}
- BlurNormalsShader: {fileID: 4800000, guid: 5b34ef975c671984fb9c93adc7042982, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c7a3813b9ad39d847b4acc42619b3256
folderAsset: yes
timeCreated: 1445386286
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.Linq;
using MeatKit;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Camera))]
[CanEditMultipleObjects]
public class AlloyCameraEditor : Editor {
Editor m_editor;
Type GetTypeGlobal(string typeName) {
return AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypesSafe()).FirstOrDefault(t => t.Name == typeName);
}
void OnEnable() {
m_editor = CreateEditor(targets, GetTypeGlobal("CameraEditor"));
}
void OnDisable() {
DestroyImmediate(m_editor);
}
public override void OnInspectorGUI() {
m_editor.OnInspectorGUI();
bool anyMissing = targets.Any(c => ((Camera)c).GetComponent<AlloyEffectsManager>() == null);
if (anyMissing) {
if (GUILayout.Button("Convert to Alloy Effects Manager", EditorStyles.toolbarButton)) {
foreach (Camera camera in targets) {
Undo.AddComponent<AlloyEffectsManager>(camera.gameObject);
}
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dc5a924e062584c4b994b26019b1b30c
timeCreated: 1491670701
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,142 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.Collections.Generic;
using System.Linq;
using Alloy;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
[CustomEditor(typeof(AlloyEffectsManager))]
public class AlloyEffectsManagerEditor : Editor {
private const string c_skinTabName = "SkinTab";
private const string c_transmissionTabName = "TransmissionTab";
private static Color s_scatterColor = new Color(0.49f, 0.36f, 0.16f);
private static Color s_transmissionColor = new Color(0.49f, 0.46f, 0.16f);
private AlloyTabGroup m_tabGroup;
private AnimBool m_skinGroup;
private AnimBool m_transmissionGroup;
private List<AlloyTabAdd> m_tabAdd = new List<AlloyTabAdd>();
private GenericMenu m_menu;
private void OnEnable() {
m_tabGroup = AlloyTabGroup.GetTabGroup();
m_skinGroup = new AnimBool(m_tabGroup.IsOpen(c_skinTabName));
m_transmissionGroup = new AnimBool(m_tabGroup.IsOpen(c_transmissionTabName));
}
public override void OnInspectorGUI() {
serializedObject.Update();
m_tabAdd.Clear();
var skinEnabled = serializedObject.FindProperty("SkinSettings.Enabled");
if (skinEnabled.boolValue && !skinEnabled.hasMultipleDifferentValues) {
bool removed;
m_skinGroup.target = m_tabGroup.TabArea("Skin Scattering", s_scatterColor, true, out removed,
c_skinTabName);
if (EditorGUILayout.BeginFadeGroup(m_skinGroup.faded)) {
var prop = serializedObject.FindProperty("SkinSettings");
prop.Next(true); //skip flag
prop.Next(true); //skip enabled
DrawRemainingProp(prop);
}
EditorGUILayout.EndFadeGroup();
if (removed) {
skinEnabled.boolValue = false;
}
}
else {
m_tabAdd.Add(new AlloyTabAdd {
Color = s_scatterColor,
Name = "Skin Scattering",
Enable = EnableSkin
});
}
var transEnabled = serializedObject.FindProperty("TransmissionSettings.Enabled");
if (transEnabled.boolValue && !transEnabled.hasMultipleDifferentValues) {
bool removed;
m_transmissionGroup.target = m_tabGroup.TabArea("Transmission", s_transmissionColor, true, out removed,
c_transmissionTabName);
if (EditorGUILayout.BeginFadeGroup(m_transmissionGroup.faded)) {
var prop = serializedObject.FindProperty("TransmissionSettings");
prop.Next(true); //skip flag
prop.Next(true);//skip enabled
DrawRemainingProp(prop);
}
EditorGUILayout.EndFadeGroup();
if (removed) {
transEnabled.boolValue = false;
}
}
else {
m_tabAdd.Add(new AlloyTabAdd {
Color = s_transmissionColor,
Name = "Transmission",
Enable = EnableTransmission
});
}
if (m_skinGroup.isAnimating || m_transmissionGroup.isAnimating) {
Repaint();
}
AlloyEditor.DrawAddTabGUI(m_tabAdd);
serializedObject.ApplyModifiedProperties();
if (GUI.changed) {
var deferredRendererPlus = serializedObject.targetObject as AlloyEffectsManager;
if (deferredRendererPlus != null) {
deferredRendererPlus.Refresh();
}
}
}
private void EnableTransmission() {
foreach (AlloyEffectsManager rend in targets) {
rend.TransmissionSettings.Enabled = true;
EditorUtility.SetDirty(rend);
rend.Refresh();
}
m_transmissionGroup.value = false;
m_transmissionGroup.target = true;
m_tabGroup.SetOpen(c_transmissionTabName, true);
}
private void EnableSkin() {
foreach (AlloyEffectsManager rend in targets) {
rend.SkinSettings.Enabled = true;
EditorUtility.SetDirty(rend);
rend.Refresh();
}
m_skinGroup.value = false;
m_skinGroup.target = true;
m_tabGroup.SetOpen(c_skinTabName, true);
}
private static void DrawRemainingProp(SerializedProperty prop) {
int depth = prop.depth;
while (true) {
bool child = EditorGUILayout.PropertyField(prop, true);
if (!prop.Next(child) || prop.depth < depth)
break;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4d4b26109848fff4daa6b5974417de47
timeCreated: 1445386295
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 979804faf9172f54dbdbf0974928665d
folderAsset: yes
timeCreated: 1439605207
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,232 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
Shader "Hidden/Alloy/Blur Normals" {
Properties {
_MainTex ("Render Input", 2D) = "white" {}
}
SubShader {
ZTest Always Cull Off ZWrite Off Fog { Mode Off }
CGINCLUDE
#pragma target 3.0
#pragma exclude_renderers gles
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "UnityDeferredLibrary.cginc"
// Screen-space diffusion
// cf http://www.iryoku.com/screen-space-subsurface-scattering
// cf http://uaasoftware.com/xi/PDSS/diffuseShader.fx
// blurWidth = 0.15
// blurDepthDifferenceMultiplier = 100
// distanceToProjectionWindow = 1 / tan(radians(FoV) / 2);
// blurStepScale = blurWidth * distanceToProjectionWindow
// blurDepthDifferenceScale = blurDepthDifferenceMultiplier * distanceToProjectionWindow
/// Number of downsampling texture taps.
#define A_NUM_DOWNSAMPLE_TAPS 4
/// Downsampling texture coordinate offset directions.
static const float2 A_DOWNSAMPLE_OFFSETS[A_NUM_DOWNSAMPLE_TAPS] = {
float2(0.0f, 0.0f),
float2(1.0f, 0.0f),
float2(0.0f, 1.0f),
float2(1.0f, 1.0f)
};
/// Number of blur texture taps.
#define A_NUM_BLUR_TAPS 7
/// Gaussian Distribution blur texture coordinate offsets.
static const float A_BLUR_OFFSETS[A_NUM_BLUR_TAPS] = {
0.0f, -3.0f, -2.0f, -1.0f, 1.0f, 2.0f, 3.0f
};
/// Gaussian Distribution blur sample weights.
static const half A_BLUR_WEIGHTS[A_NUM_BLUR_TAPS] = {
0.199471h, 0.0647588h, 0.120985h, 0.176033h, 0.176033h, 0.120985h, 0.0647588h
};
/// Number of upsampling texture taps.
#define A_NUM_UPSAMPLE_TAPS 4
/// Upsampling texture coordinate offset directions.
static const float2 A_UPSAMPLE_OFFSETS[A_NUM_UPSAMPLE_TAPS] = {
float2(0.0f, 1.0f),
float2(1.0f, 0.0f),
float2(-1.0f, 0.0f),
float2(0.0f, -1.0f)
};
/// (X: blurStepScale, Y: blurDepthDifferenceScale).
float2 _DeferredBlurredNormalsParams;
// G-Buffer LAB (transmission in alpha).
sampler2D _DeferredTransmissionBuffer;
/// Pass source texture.
sampler2D _MainTex;
/// Pass source texture (X: Tiling X, Y: Tiling Y, Z: Offset X, W: Offset Y).
float4 _MainTex_ST;
/// Pass source texture (X: 1 / width, Y: 1 / height, Z: width, W: height).
float4 _MainTex_TexelSize;
/// Normal buffer.
sampler2D _CameraGBufferTexture2;
/// Interpolates offet normals to center normals at edge discontinuities.
/// @param normalDepth Offset sample (XYZ: Normals, W: Depth).
/// @param normalDepthM Center sample (XYZ: Normals, W: Depth).
/// @return Edge-corrected normal.
half3 aEdgeCorrectNormal(
half4 normalDepth,
half4 normalDepthM)
{
// Cheaper than a 5-way blend, which requires inverts and an accumulator.
half alpha = saturate(_DeferredBlurredNormalsParams.y * abs(normalDepth.w - normalDepthM.w));
return lerp(normalDepth.xyz, normalDepthM.xyz, alpha);
}
/// Downsamples the G-Buffer normals and depth to 1/2 resolution.
/// @param IN Vertex input.
/// @return Downsampled image (XYZ: Normals, W: Nearest Depth).
half4 aDownsample(
v2f_img IN)
{
half depth = 1.0h;
half3 normal = 0.0h;
UNITY_UNROLL
for (int i = 1; i < A_NUM_DOWNSAMPLE_TAPS; i++) {
float2 coord = UnityStereoScreenSpaceUVAdjust(A_DOWNSAMPLE_OFFSETS[i] * _MainTex_TexelSize.xy + IN.uv, _MainTex_ST);
float4 sampleUv = float4(coord, 0.0f, 0.0f);
// Pre-combine sample weight with normal scale-bias unpack.
// 0.25 * (normal * 2 - 1) = normal * 0.5 - 0.25
normal += tex2Dlod(_MainTex, sampleUv).xyz * 0.5h - 0.25h;
// Use projection depth directly to avoid linearizing cost per sample.
depth = min(depth, SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampleUv));
}
// Export unpacked normals and linear depth for subsequent passes.
return half4(normal, LinearEyeDepth(depth));
}
/// Blur the source image along the specified axis.
/// @param IN Vertex input.
/// @param axis Axis on which to blur.
/// @return (XYZ: Blurred Normals, W: Sharp Depth).
half4 aBlurAxis(
v2f_img IN,
float2 axis)
{
// Gaussian Blur.
half4 normalDepthM = tex2Dlod(_MainTex, float4(UnityStereoScreenSpaceUVAdjust(IN.uv, _MainTex_ST), 0.0f, 0.0f));
float scale = _DeferredBlurredNormalsParams.x / normalDepthM.w;
float2 finalStep = scale * axis * _MainTex_TexelSize.xy;
half3 output = A_BLUR_WEIGHTS[0] * normalDepthM.xyz;
UNITY_UNROLL
for (int i = 1; i < A_NUM_BLUR_TAPS; i++) {
float2 coord = UnityStereoScreenSpaceUVAdjust(A_BLUR_OFFSETS[i] * finalStep + IN.uv, _MainTex_ST);
half4 normalDepth = tex2Dlod(_MainTex, float4(coord, 0.0f, 0.0f));
// Lerp back to middle sample when blur sample crosses an edge.
output += A_BLUR_WEIGHTS[i] * aEdgeCorrectNormal(normalDepth, normalDepthM);
}
// Transfer original depth for subsequent passes.
return half4(output, normalDepthM.w);
}
/// Upsamples the blurred normals.
/// @param IN Vertex input.
/// @return Upsampled, packed blurred normals.
half4 aUpsample(
v2f_img IN)
{
// Cross Bilateral Upsample filter.
half4 normalDepthM;
half4 output = 0.0h;
float4 sampleUv = float4(UnityStereoScreenSpaceUVAdjust(IN.uv, _MainTex_ST), 0.0f, 0.0f);
normalDepthM.xyz = tex2Dlod(_CameraGBufferTexture2, sampleUv).xyz * 2.0f - 1.0f;
normalDepthM.w = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampleUv));
UNITY_UNROLL
for (int i = 0; i < A_NUM_UPSAMPLE_TAPS; i++) {
float2 coord = UnityStereoScreenSpaceUVAdjust(A_UPSAMPLE_OFFSETS[i] * _MainTex_TexelSize.xy + IN.uv, _MainTex_ST);
half4 normalDepth = tex2Dlod(_MainTex, float4(coord, 0.0f, 0.0f));
output.xyz += 0.25h * aEdgeCorrectNormal(normalDepth, normalDepthM);
}
// Pack normals and transmission for RGBA8 storage.
output.xyz = normalize(output.xyz) * 0.5h + 0.5h;
output.w = tex2Dlod(_DeferredTransmissionBuffer, sampleUv).a;
return output;
}
ENDCG
Pass {
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers gles
#pragma vertex vert_img
#pragma fragment frag
half4 frag(v2f_img IN) : SV_Target {
return aDownsample(IN);
}
ENDCG
}
Pass {
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers gles
#pragma vertex vert_img
#pragma fragment frag
half4 frag(v2f_img IN) : SV_Target {
return aBlurAxis(IN, float2(1.0f, 0.0f));
}
ENDCG
}
Pass {
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers gles
#pragma vertex vert_img
#pragma fragment frag
half4 frag(v2f_img IN) : SV_Target {
return aBlurAxis(IN, float2(0.0f, 1.0f));
}
ENDCG
}
Pass {
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers gles
#pragma vertex vert_img
#pragma fragment frag
half4 frag(v2f_img IN) : SV_Target {
return aUpsample(IN);
}
ENDCG
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5b34ef975c671984fb9c93adc7042982
timeCreated: 1439655606
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
Shader "Hidden/Alloy/Transmission Blit" {
Properties {
_MainTex ("Render Input", 2D) = "white" {}
}
SubShader {
ZTest Always
Cull Off
ZWrite Off
Fog { Mode Off }
Pass {
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers gles
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
float4 frag(v2f_img IN) : SV_Target {
return tex2Dlod(_MainTex, float4(UnityStereoScreenSpaceUVAdjust(IN.uv, _MainTex_ST), 0.0f, 0.0f));
}
ENDCG
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 4bbeef29a84b4ed498f2d4a7d9fcefc4
timeCreated: 1439605218
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: a09bc1e2550271c4b80f0d54972ba858
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: cdcd98ae1d577384abf903171eb390e1
folderAsset: yes
DefaultImporter:
userData:
@@ -0,0 +1,214 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using Alloy;
using UnityEditor;
using PropType = UnityEditor.MaterialProperty.PropType;
static class AlloySceneDrawer {
static Dictionary<AlloyInspectorBase, MaterialEditor> s_inspectorKeeper = new Dictionary<AlloyInspectorBase, MaterialEditor>();
static List<AlloyInspectorBase> s_removekeys = new List<AlloyInspectorBase>();
static AlloySceneDrawer() {
EditorApplication.update += Update;
}
static void Update() {
var keys = s_inspectorKeeper.Keys;
s_removekeys.Clear();
foreach (var key in keys) {
if (s_inspectorKeeper[key] != null) {
continue;
}
key.OnAlloyShaderDisable();
s_removekeys.Add(key);
}
foreach (var key in s_removekeys) {
s_inspectorKeeper.Remove(key);
}
}
public static void Register(AlloyInspectorBase inspector, MaterialEditor keeper) {
if (!s_inspectorKeeper.ContainsKey(inspector)) {
s_inspectorKeeper.Add(inspector, keeper);
}
}
}
public class AlloyInspectorBase : ShaderGUI {
public MaterialEditor MatEditor;
protected AlloyTabGroup TabGroup;
public Object[] Targets { get { return MatEditor.targets; } }
public Material Target { get { return (Material) MatEditor.target; } }
bool m_inited;
bool m_isValid = true;
protected int MatInst {
get {
if (Selection.objects.Length == 1 && Selection.activeGameObject != null) {
var sharedMaterials = Selection.activeGameObject.GetComponent<Renderer>().sharedMaterials;
if (sharedMaterials != null) {
return ArrayUtility.IndexOf(sharedMaterials, Target);
}
}
return 0;
}
}
void OnEnable(MaterialProperty[] properties) {
if (HasMutlipleShaders()) {
return;
}
TabGroup = AlloyTabGroup.GetTabGroup();
if (Targets.Length > 1) {
if (MaterialsAreMismatched()) {
foreach (var target in Targets) {
var so = new SerializedObject(target);
so.Update();
var textures = so.FindProperty("m_SavedProperties.m_TexEnvs");
ClearMaterialArray(PropType.Texture, textures, properties);
var floats = so.FindProperty("m_SavedProperties.m_Floats");
ClearMaterialArray(PropType.Float, floats, properties);
var colors = so.FindProperty("m_SavedProperties.m_Colors");
ClearMaterialArray(PropType.Color, colors, properties);
so.ApplyModifiedProperties();
so.Dispose();
}
m_isValid = false;
return;
}
}
SceneView.onSceneGUIDelegate += OnAlloySceneGUI;
OnAlloyShaderEnable();
}
bool HasMutlipleShaders() {
if (MatEditor.targets.Length > 1) {
return Targets.Any(o => {
var objMat = o as Material;
return objMat != null && (Target != null && objMat.shader != Target.shader);
});
}
return false;
}
protected virtual void OnAlloyShaderGUI(MaterialProperty[] properties) {
}
protected virtual void OnAlloyShaderEnable() {
}
public virtual void OnAlloySceneGUI(SceneView sceneView) {
}
void ClearMaterialArray(PropType type, SerializedProperty props, MaterialProperty[] properties) {
for (int i = 0; i < props.arraySize; ++i) {
var prop = props.GetArrayElementAtIndex(i);
var nameProp = prop.FindPropertyRelative("first");
string propName = nameProp.stringValue;
MaterialProperty matProp = FindProperty(propName, properties, false);
if (matProp == null || matProp.type != type) {
props.DeleteArrayElementAtIndex(i);
--i;
}
}
MatEditor.OnEnable();
}
bool MaterialsAreMismatched() {
var textures = MatEditor.serializedObject.FindProperty("m_SavedProperties.m_TexEnvs");
if (PropsInArrayMismatched(textures)) {
return true;
}
var floats = MatEditor.serializedObject.FindProperty("m_SavedProperties.m_Floats");
if (PropsInArrayMismatched(floats)) {
return true;
}
var colors = MatEditor.serializedObject.FindProperty("m_SavedProperties.m_Colors");
if (PropsInArrayMismatched(colors)) {
return true;
}
return false;
}
bool PropsInArrayMismatched(SerializedProperty props) {
string original = props.propertyPath;
props.Next(true);
props.Next(true);
props.Next(true);
//some weird unity behaviour where it collapses the array
if (!props.propertyPath.Contains(original)) {
return true;
}
do {
var nameProp = props.FindPropertyRelative("first");
if (nameProp.hasMultipleDifferentValues) {
return true;
}
} while (props.NextVisible(false) && props.propertyPath.Contains(original));
return false;
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) {
MatEditor = materialEditor;
m_isValid = true;
if (!m_inited) {
AlloySceneDrawer.Register(this, MatEditor);
OnEnable(properties);
}
if (!m_isValid) {
EditorGUILayout.LabelField("There's a problem with the inspector. Reselect the material to fix");
EditorApplication.delayCall += () => MatEditor.Repaint();
return;
}
if (HasMutlipleShaders()) {
EditorGUILayout.HelpBox("Can't edit materials with different shaders!", MessageType.Warning);
return;
}
GUILayout.Space(10.0f);
if (MatEditor.isVisible) {
OnAlloyShaderGUI(properties);
}
m_inited = true;
}
public virtual void OnAlloyShaderDisable() {
SceneView.onSceneGUIDelegate -= OnAlloySceneGUI;
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b14f7264c7490be4e9efc64c33c313aa
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,162 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace Alloy
{
[Serializable]
public class AlloyTabGroup : ScriptableObject
{
[SerializeField] private List<bool> m_open;
[SerializeField] private List<string> m_names;
private Action<Rect> m_defaultTabFunction = (r) => GUI.Label(r, "-", EditorStyles.whiteLabel);
public static AlloyTabGroup GetTabGroup() {
var o = Resources.FindObjectsOfTypeAll<AlloyTabGroup>();
AlloyTabGroup tab;
if (o.Length != 0) {
tab = o[0];
} else {
tab = CreateInstance<AlloyTabGroup>();
tab.hideFlags = HideFlags.HideAndDontSave;
tab.name = "AlloyTabGroup";
}
return tab;
}
private void OnEnable() {
if (m_open != null && m_names != null) return;
m_open = new List<bool>();
m_names = new List<string>();
}
private int DeclOpen(string nameDecl) {
string actual = nameDecl + GUI.depth;
if (!m_names.Contains(actual)) {
m_open.Add(false);
m_names.Add(actual);
}
return m_names.IndexOf(actual);
}
public bool TabArea(string areaName, Color color, bool hasOptionalGui, out bool removed, string saveAs = "") {
return TabArea(areaName, color, hasOptionalGui, m_defaultTabFunction, out removed, saveAs);
}
public bool TabArea(string areaName, Color color, bool hasOptionalGui, Action<Rect> optionalGUI, out bool removed, string saveAs = "")
{
if (saveAs == "") {
saveAs = areaName;
}
Color oldGuiColor = GUI.color;
Color oldBackgroundColor = GUI.backgroundColor;
GUI.color = Color.Lerp(color, Color.white, 0.8f);
GUI.backgroundColor = color;
bool ret = TabArea(areaName, hasOptionalGui, optionalGUI, out removed, saveAs);
GUI.color = oldGuiColor;
GUI.backgroundColor = oldBackgroundColor;
return ret;
}
public bool TabArea(string areaName, bool hasOptionalGui, out bool removed, string saveAs = "") {
return TabArea(areaName, hasOptionalGui, m_defaultTabFunction, out removed, saveAs);
}
public bool TabArea(string areaName, bool hasOptionalGui, Action<Rect> optionalGUI, out bool removed, string saveAs = "")
{
if (saveAs == "") {
saveAs = areaName;
}
int i = DeclOpen(saveAs);
var tabTextColor = EditorGUIUtility.isProSkin ? new Color(0.7f, 0.7f, 0.7f) : new Color(0.9f, 0.9f, 0.9f);
var oldCol = GUI.color;
GUI.color = oldCol * (m_open[i] ? Color.white : new Color(0.8f, 0.8f, 0.8f));
GUILayout.Label("");
var rect = GUILayoutUtility.GetLastRect();
rect.x -= 35.0f;
rect.width += hasOptionalGui ? 10.0f : 50.0f;
m_open[i] = GUI.Toggle(rect, m_open[i], new GUIContent(""), "ShurikenModuleTitle");
removed = false;
if (hasOptionalGui)
{
var delRect = rect;
delRect.xMin = rect.xMax;
delRect.xMax += 40.0f;
GUI.color = oldCol * (m_open[i] ? new Color(0.7f, 0.7f, 0.7f) : new Color(0.5f, 0.5f, 0.5f));
if (GUI.Button(delRect, "", "ShurikenModuleTitle")) {
removed = true;
}
GUI.color = tabTextColor;
GUI.backgroundColor = Color.white;
delRect.x += 10.0f;
optionalGUI(delRect);
}
rect.x += 35.0f;
GUI.color = tabTextColor;
GUI.Label(rect, areaName, EditorStyles.whiteLabel);
GUI.color = oldCol;
if (GUI.changed) {
EditorUtility.SetDirty(this);
}
return m_open[i];
}
public bool Foldout(string areaName, string saveName, params GUILayoutOption[] options) {
int i = DeclOpen(saveName);
EditorGUILayout.BeginHorizontal();
m_open[i] = EditorGUILayout.Toggle(new GUIContent(""), m_open[i], "foldout", options);
if (areaName != "")
EditorGUILayout.LabelField(new GUIContent(areaName), GUILayout.ExpandWidth(false), GUILayout.Width(180.0f));
EditorGUILayout.EndHorizontal();
if (GUI.changed)
EditorUtility.SetDirty(this);
return m_open[i];
}
public bool IsOpen(string areaName) {
int i = DeclOpen(areaName);
return m_open[i];
}
public void SetOpen(string areaName, bool open) {
int i = DeclOpen(areaName);
m_open[i] = open;
}
public void Close(string areaName) {
int i = DeclOpen(areaName);
m_open[i] = false;
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 700e2ca720a367c41877be522b433566
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: dadbee4584b61ec4792a816f7dfe5061
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
@@ -0,0 +1,167 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.AnimatedValues;
[CanEditMultipleObjects]
public class AlloyFieldBasedEditor : AlloyInspectorBase {
Dictionary<string, AnimBool> m_openCloseAnim = new Dictionary<string, AnimBool>();
AlloyFieldDrawer[] m_fieldDrawers;
string[] m_allTabs;
public bool TabIsEnabled(MaterialProperty prop) {
return !prop.hasMixedValue && prop.floatValue > 0.5f;
}
public void EnableTab(string tab, MaterialProperty prop, int matInst) {
m_openCloseAnim[prop.name].value = false;
TabGroup.SetOpen(tab + matInst, true);
prop.floatValue = 1.0f;
MaterialEditor.ApplyMaterialPropertyDrawers(Targets);
RepaintScene();
}
public void DisableTab(string tab, MaterialProperty prop, int matInst) {
prop.floatValue = 0.0f;
MaterialEditor.ApplyMaterialPropertyDrawers(Targets);
RepaintScene();
m_openCloseAnim[prop.name].target = false;
TabGroup.SetOpen(tab + matInst, false);
}
protected override void OnAlloyShaderEnable() {
Undo.undoRedoPerformed += OnUndo;
}
public override void OnAlloyShaderDisable() {
base.OnAlloyShaderDisable();
if (m_fieldDrawers != null) {
foreach (var drawer in m_fieldDrawers) {
if (drawer != null) {
drawer.OnDisable();
}
}
}
}
void OnUndo() {
MatEditor.Repaint();
}
static HashSet<string> s_knownNulls = new HashSet<string>();
protected override void OnAlloyShaderGUI(MaterialProperty[] properties) {
//Refresh drawer structure if needed
bool structuralChange = false;
if (m_fieldDrawers == null || m_fieldDrawers.Length != properties.Length) {
m_fieldDrawers = new AlloyFieldDrawer[properties.Length];
structuralChange = true;
}
for (int i = 0; i < properties.Length; ++i) {
string propName = properties[i].name;
if (m_fieldDrawers[i] == null && !s_knownNulls.Contains(propName) || m_fieldDrawers[i] != null && m_fieldDrawers[i].Property.name != propName) {
m_fieldDrawers[i] = AlloyFieldDrawerFactory.GetFieldDrawer(this, properties[i]);
if (m_fieldDrawers[i] == null) {
s_knownNulls.Add(propName);
}
else {
structuralChange = true;
}
}
}
//If changed, update the animation stuff
if (structuralChange) {
m_openCloseAnim.Clear();
var allTabs = new List<string>();
for (var i = 0; i < m_fieldDrawers.Length; i++) {
var drawer = m_fieldDrawers[i];
if (!(drawer is AlloyTabDrawer)) {
continue;
}
bool isOpenCur = TabGroup.IsOpen(drawer.DisplayName + MatInst);
var anim = new AnimBool(isOpenCur) {speed = 6.0f, value = isOpenCur};
m_openCloseAnim.Add(properties[i].name, anim);
allTabs.Add(drawer.DisplayName);
}
m_allTabs = allTabs.ToArray();
}
//Formulate arguments to pass to drawing
var args = new AlloyFieldDrawerArgs {
Editor = this,
Materials = Targets.Cast<Material>().ToArray(),
Properties = properties,
PropertiesSkip = new List<string>(),
MatInst = MatInst,
TabGroup = TabGroup,
AllTabNames = m_allTabs,
OpenCloseAnim = m_openCloseAnim
};
for (var i = 0; i < m_fieldDrawers.Length; i++) {
var drawer = m_fieldDrawers[i];
if (drawer == null) {
continue;
}
drawer.Index = i;
drawer.Property = properties[i];
if (drawer.ShouldDraw(args)) {
drawer.Draw(args);
}
}
if (!string.IsNullOrEmpty(args.CurrentTab)) {
EditorGUILayout.EndFadeGroup();
}
GUILayout.Space(10.0f);
AlloyEditor.DrawAddTabGUI(args.TabsToAdd);
//If animating -> Repaint
foreach (var animBool in m_openCloseAnim) {
if (animBool.Value.isAnimating) {
MatEditor.Repaint();
break;
}
}
}
public override void OnAlloySceneGUI(SceneView sceneView) {
foreach (var drawer in m_fieldDrawers) {
if (drawer != null) {
drawer.OnSceneGUI(Targets.Cast<Material>().ToArray());
}
}
}
private void RepaintScene() {
var lastSceneView = SceneView.lastActiveSceneView;
if (lastSceneView != null)
lastSceneView.Repaint();
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a42f0f341bef6df4c8093abde9d7e4f3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,327 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public abstract class AlloyToken
{
public string Token;
protected AlloyToken(string field, AlloyFieldLexer currentLexer) {
Token = field;
}
}
public class AlloyCollectionToken : AlloyToken
{
public List<AlloyToken> SubTokens;
public const char CollectionOpen = '{';
public const char CollectionClose = '}';
public AlloyCollectionToken(string field, AlloyFieldLexer currentLexer)
: base(field, currentLexer) {
SubTokens = currentLexer.GenerateTokens(field);
}
}
public class AlloyArgumentToken : AlloyToken
{
public const char ArgumentChar = ':';
public string ArgumentName;
public AlloyToken ArgumentToken;
public AlloyArgumentToken(string field, AlloyFieldLexer currentLexer)
: base(field, currentLexer) {
int index = field.IndexOf(':');
ArgumentName = field.Substring(0, index);
string valueStr = field.Substring(index + 1);
int outInd;
ArgumentToken = currentLexer.GenerateToken(valueStr, 0, out outInd);
}
}
public class AlloyValueToken : AlloyToken
{
private const string c_true = "True";
private const string c_false = "False";
public enum ValueTypeEnum
{
Bool,
Float,
String
}
public ValueTypeEnum ValueType { get; private set; }
private bool m_boolValue;
private float m_floatValue;
private string m_stringValue;
public bool BoolValue {
get {
ExpectType(ValueTypeEnum.Bool);
return m_boolValue;
}
}
public float FloatValue {
get {
ExpectType(ValueTypeEnum.Float);
return m_floatValue;
}
}
public string StringValue {
get {
ExpectType(ValueTypeEnum.String);
return m_stringValue;
}
}
private void ExpectType(ValueTypeEnum type) {
if (ValueType != type) {
Debug.LogError("Cant read " + type + " value from token!");
}
}
public AlloyValueToken(string field, AlloyFieldLexer currentLexer)
: base(field, currentLexer) {
if (field == c_true) {
ValueType = ValueTypeEnum.Bool;
m_boolValue = true;
return;
}
if (field == c_false) {
ValueType = ValueTypeEnum.Bool;
m_boolValue = false;
return;
}
float val;
if (float.TryParse(field, out val)) {
ValueType = ValueTypeEnum.Float;
m_floatValue = val;
return;
}
ValueType = ValueTypeEnum.String;
m_stringValue = field;
}
}
//The language defines a few concepts
//A pure token will be intepreted as a value
//MyString -> string value MyString
//True -> bool True
//1.03 -> float 1.03
//A collection token defines a set of tokens
//{1.03f True True {}}
//A argument token defines a name and an associated token
//CollectionArgument:{True, False}
public class AlloyFieldLexer
{
private AlloyToken[] m_tokens;
private static char[] s_specialChars = { '.', ':', '_'};
public List<AlloyToken> GenerateTokens(string parseString) {
var ret = new List<AlloyToken>();
int index = 0;
while (index != -1) {
var token = GenerateToken(parseString, index, out index);
if (token == null) {
break;
}
ret.Add(token);
}
return ret;
}
public AlloyToken GenerateToken(string parseString, int startIndex, out int index) {
parseString = PreprocessString(parseString);
for (int i = startIndex; i < parseString.Length; ++i) {
char c = parseString[i];
if (c == ' ') {
continue;
}
string token;
switch (c) {
case AlloyCollectionToken.CollectionOpen:
token = ReadStackedUntil(parseString, i, AlloyCollectionToken.CollectionOpen, AlloyCollectionToken.CollectionClose);
index = i + token.Length + 1;
return new AlloyCollectionToken(token, this);
}
bool charOpen = c == '\'';
if (char.IsLetterOrDigit(c) || charOpen || s_specialChars.Contains(c)) {
bool argument;
token = ReadWord(parseString, i, out argument);
index = i + token.Length + 1;
if (charOpen) {
++index;
}
if (argument) {
return new AlloyArgumentToken(token, this);
}
return new AlloyValueToken(token, this);
}
}
index = -1;
return null;
}
private string PreprocessString(string parseString) {
return parseString.Replace(',', ' ');
}
protected string ReadStackedUntil(string parseString, int index, char openC, char closeC) {
bool found = false;
int stack = 0;
int readIndex;
for (readIndex = index; readIndex < parseString.Length; ++readIndex) {
char c = parseString[readIndex];
if (c == openC) {
++stack;
}
else if (c == closeC) {
--stack;
}
if (stack == 0) {
found = true;
break;
}
}
if (!found) {
Debug.LogError("Parsing fail. Could not find closing char" + closeC);
Debug.Log(parseString);
return null;
}
return parseString.Substring(index + 1, readIndex - index);
}
private string ReadWord(string parseString, int index, out bool isArgument) {
int readIndex = index;
bool found = false;
int stack = 0;
bool inString = parseString[index] == '\'';
if (inString) {
++index;
}
isArgument = false;
for (int i = index; i < parseString.Length; ++i) {
char curChar = parseString[i];
readIndex = i;
if (curChar == ':') {
isArgument = true;
}
if (!inString) {
if (char.IsLetterOrDigit(curChar) || s_specialChars.Contains(curChar)) {
continue;
}
if (curChar == AlloyCollectionToken.CollectionOpen) {
++stack;
continue;
}
if ((curChar == AlloyCollectionToken.CollectionClose) && stack != 0) {
--stack;
if (stack == 0) {
break;
}
}
if (stack != 0) {
continue;
}
}
else {
if (curChar != '\'') {
continue;
}
}
found = true;
break;
}
if (!found) {
readIndex++;
}
string ret = parseString.Substring(index, readIndex - index);
//TODO: Handle argument:'StringToken'
/*
if (found) {
//if (readIndex < parseString.Length - 1 && parseString[readIndex + 1] == ':') {
//ret += ReadWord(parseString, readIndex + 2);
//}
}
*/
return ret;
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 52de48504b3bb25439b7013a009de5e9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,156 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEditor.AnimatedValues;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using Alloy;
using UnityEditor;
//Generates drawers for a certain field
public abstract class AlloyFieldParser {
protected List<AlloyToken> Tokens;
public bool HasSettings;
public string DisplayName;
protected MaterialProperty MaterialProperty;
protected AlloyArgumentToken[] Arguments;
protected AlloyFieldParser(MaterialProperty prop) {
var lexer = new AlloyFieldLexer();
Tokens = lexer.GenerateTokens(prop.displayName);
if (Tokens.Count == 0) {
Debug.LogError("No tokens found!");
return;
}
MaterialProperty = prop;
DisplayName = Tokens[0].Token;
if (Tokens.Count <= 1) {
return;
}
var settingsToken = Tokens[1] as AlloyCollectionToken;
if (settingsToken == null) {
return;
}
HasSettings = true;
Arguments = settingsToken.SubTokens.OfType<AlloyArgumentToken>().ToArray();
}
public AlloyFieldDrawer GetDrawer(AlloyInspectorBase editor) {
if (!HasSettings) {
return null;
}
var drawer = GenerateDrawer(editor);
if (drawer != null) {
drawer.DisplayName = DisplayName;
}
return drawer;
}
protected abstract AlloyFieldDrawer GenerateDrawer(AlloyInspectorBase editor);
}
public class AlloyFieldDrawerArgs {
public AlloyFieldBasedEditor Editor;
public AlloyTabGroup TabGroup;
public Material[] Materials;
public MaterialProperty[] Properties;
public List<string> PropertiesSkip = new List<string>();
public string CurrentTab;
public int MatInst;
public bool DoDraw = true;
public List<AlloyTabAdd> TabsToAdd = new List<AlloyTabAdd>();
public string[] AllTabNames;
public Dictionary<string, AnimBool> OpenCloseAnim;
public MaterialProperty GetMaterialProperty(string velName) {
return Properties.FirstOrDefault(p => p.name == velName);
}
}
public class AlloyTabAdd {
public string Name;
public Color Color;
public GenericMenu.MenuFunction Enable;
}
public abstract class AlloyFieldDrawer {
public MaterialProperty Property;
public int Index;
public string DisplayName;
public abstract void Draw(AlloyFieldDrawerArgs args);
protected MaterialEditor MatEditor;
protected void BeginMaterialProperty(MaterialProperty property) {
MatEditor.BeginAnimatedCheck(Property);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = Property.hasMixedValue;
}
protected bool EndMaterialProperty() {
bool change = EditorGUI.EndChangeCheck();
MatEditor.EndAnimatedCheck();
EditorGUI.showMixedValue = false;
return change;
}
public AlloyFieldDrawer(AlloyInspectorBase editor, MaterialProperty property) {
Property = property;
MatEditor = editor.MatEditor;
}
protected void FloatFieldMin(string displayName, float min) {
BeginMaterialProperty(Property);
float newVal = EditorGUILayout.FloatField(displayName, Property.floatValue);
if (EndMaterialProperty()) {
Property.floatValue = Mathf.Max(newVal, min);
}
}
protected void FloatFieldMax(string displayName, float max) {
BeginMaterialProperty(Property);
float newVal = EditorGUILayout.FloatField(displayName, Property.floatValue);
if (EndMaterialProperty()) {
Property.floatValue = Mathf.Min(newVal, max);
}
}
protected void FloatFieldSlider(string displayName, float min, float max) {
BeginMaterialProperty(Property);
float newVal = EditorGUILayout.Slider(displayName, Property.floatValue, min, max, GUILayout.MinWidth(20.0f));
if (EndMaterialProperty()) {
Property.floatValue = Mathf.Clamp(newVal, min, max);
}
}
public void PropField(string displayName) {
MatEditor.ShaderProperty(Property, displayName);
}
public virtual bool ShouldDraw(AlloyFieldDrawerArgs args) {
return args.DoDraw && !args.PropertiesSkip.Contains(Property.name);
}
public virtual void OnSceneGUI(Material[] materials) {
}
public virtual void OnDisable() {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 23f0b2f9bd608954ca3ef47baea748b7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c8a42743b4a4aee4d901f3b88bbf641f
folderAsset: yes
timeCreated: 1430261445
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,46 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEditor;
using UnityEngine;
public static class AlloyFieldDrawerFactory {
private static AlloyFieldParser GetFieldParser(MaterialProperty prop) {
switch (prop.type) {
case MaterialProperty.PropType.Texture:
if (prop.textureDimension == UnityEngine.Rendering.TextureDimension.Cube) {
return new AlloyCubeParser(prop);
}
return new AlloyTextureParser(prop);
case MaterialProperty.PropType.Range:
case MaterialProperty.PropType.Float:
return new AlloyFloatParser(prop);
case MaterialProperty.PropType.Color:
return new AlloyColorParser(prop);
case MaterialProperty.PropType.Vector:
return new AlloyVectorParser(prop);
default:
Debug.LogError("No appopriate parser found to generate a drawer");
return null;
}
}
public static AlloyFieldDrawer GetFieldDrawer(AlloyInspectorBase editor, MaterialProperty prop) {
AlloyFieldParser parser = GetFieldParser(prop);
if (parser != null) {
return parser.GetDrawer(editor);
}
return null;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 92100f25eeaa5f14c882772983cb2592
timeCreated: 1430261698
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,189 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.Linq;
using UnityEditor;
using UnityEngine;
public class AlloyDefaultDrawer : AlloyFieldDrawer
{
public override void Draw(AlloyFieldDrawerArgs args) {
PropField(DisplayName);
}
public AlloyDefaultDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyLightmapEmissionDrawer : AlloyFieldDrawer {
public override void Draw(AlloyFieldDrawerArgs args) {
args.Editor.MatEditor.LightmapEmissionProperty();
foreach (var material in args.Materials) {
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) {
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
}
}
public AlloyLightmapEmissionDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyRenderQueueDrawer : AlloyFieldDrawer {
public override void Draw(AlloyFieldDrawerArgs args) {
args.Editor.MatEditor.RenderQueueField();
}
public AlloyRenderQueueDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyEnableInstancingDrawer : AlloyFieldDrawer {
public override void Draw(AlloyFieldDrawerArgs args) {
args.Editor.MatEditor.EnableInstancingField();
}
public AlloyEnableInstancingDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyRenderingModeDrawer : AlloyBlendModeDropdownDrawer {
private enum RenderingMode {
Opaque,
Cutout,
Fade,
Transparent
}
private static readonly BlendModeOptionConfig[] s_renderingModes = {
new BlendModeOptionConfig() {
Type = (int)RenderingMode.Opaque,
OverrideTag = "",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "",
RenderQueue = -1
},
new BlendModeOptionConfig() {
Type = (int)RenderingMode.Cutout,
OverrideTag = "TransparentCutout",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "_ALPHATEST_ON",
RenderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest,
},
new BlendModeOptionConfig() {
Type = (int)RenderingMode.Fade,
OverrideTag = "Transparent",
SrcBlend = UnityEngine.Rendering.BlendMode.SrcAlpha,
DstBlend = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha,
ZWrite = 0,
Keyword = "_ALPHABLEND_ON",
RenderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent
},
new BlendModeOptionConfig() {
Type = (int)RenderingMode.Transparent,
OverrideTag = "Transparent",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha,
ZWrite = 0,
Keyword = "_ALPHAPREMULTIPLY_ON",
RenderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent
},
};
public AlloyRenderingModeDrawer(AlloyInspectorBase editor, MaterialProperty property)
: base(editor, property, s_renderingModes) {
}
}
public class AlloySpeedTreeGeometryTypeDrawer : AlloyBlendModeDropdownDrawer {
private enum SpeedTreeGeometryType {
Branch,
BranchDetail,
Frond,
Leaf,
Mesh,
}
private static readonly BlendModeOptionConfig[] s_geometryTypes = {
new BlendModeOptionConfig() {
Type = (int)SpeedTreeGeometryType.Branch,
OverrideTag = "",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "GEOM_TYPE_BRANCH",
RenderQueue = -1
},
new BlendModeOptionConfig() {
Type = (int)SpeedTreeGeometryType.BranchDetail,
OverrideTag = "",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "GEOM_TYPE_BRANCH_DETAIL",
RenderQueue = -1
},
new BlendModeOptionConfig() {
Type = (int)SpeedTreeGeometryType.Frond,
OverrideTag = "TransparentCutout",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "GEOM_TYPE_FROND",
RenderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest
},
new BlendModeOptionConfig() {
Type = (int)SpeedTreeGeometryType.Leaf,
OverrideTag = "TransparentCutout",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "GEOM_TYPE_LEAF",
RenderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest
},
new BlendModeOptionConfig() {
Type = (int)SpeedTreeGeometryType.Mesh,
OverrideTag = "",
SrcBlend = UnityEngine.Rendering.BlendMode.One,
DstBlend = UnityEngine.Rendering.BlendMode.Zero,
ZWrite = 1,
Keyword = "GEOM_TYPE_MESH",
RenderQueue = -1
},
};
public AlloySpeedTreeGeometryTypeDrawer(AlloyInspectorBase editor, MaterialProperty property)
: base(editor, property, s_geometryTypes)
{
}
}
public class AlloyColorParser : AlloyFieldParser{
protected override AlloyFieldDrawer GenerateDrawer(AlloyInspectorBase editor) {
var ret = new AlloyColorDrawer(editor, MaterialProperty);
return ret;
}
public AlloyColorParser(MaterialProperty field) : base(field) {
}
}
public class AlloyColorDrawer : AlloyFieldDrawer {
public override void Draw(AlloyFieldDrawerArgs args) {
PropField(DisplayName);
}
public AlloyColorDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ce2d4023424d8b24e830bed4c9fb55f5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,511 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.Text.RegularExpressions;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
public class AlloyDropdownOption {
public string Name;
public string[] HideFields;
}
public class AlloyFloatParser : AlloyFieldParser {
private readonly Color32 c_defaultSectionColor = new Color32(97, 97, 97, 255);
protected override AlloyFieldDrawer GenerateDrawer(AlloyInspectorBase editor) {
AlloyFieldDrawer retDrawer = null;
foreach (var token in Arguments) {
var argName = token.ArgumentName;
var argToken = token.ArgumentToken;
switch (argName) {
case "Min":
AlloyFloatDrawer minDrawer = null;
var minValToken = argToken as AlloyValueToken;
if (retDrawer != null)
minDrawer = retDrawer as AlloyFloatDrawer;
if (minDrawer == null)
minDrawer = new AlloyFloatDrawer(editor, MaterialProperty);
minDrawer.HasMin = true;
minDrawer.MinValue = minValToken.FloatValue;
retDrawer = minDrawer;
break;
case "Max":
AlloyFloatDrawer maxDrawer = null;
var maxValToken = argToken as AlloyValueToken;
if (retDrawer != null)
maxDrawer = retDrawer as AlloyFloatDrawer;
if (maxDrawer == null)
maxDrawer = new AlloyFloatDrawer(editor, MaterialProperty);
maxDrawer.HasMax = true;
maxDrawer.MaxValue = maxValToken.FloatValue;
retDrawer = maxDrawer;
break;
case "Section":
retDrawer = new AlloySectionDrawer(editor, MaterialProperty);
SetSectionOption(retDrawer, argToken);
break;
case "Feature":
retDrawer = new AlloyFeatureDrawer(editor, MaterialProperty);
SetSectionOption(retDrawer, argToken);
break;
case "Toggle":
retDrawer = new AlloyToggleDrawer(editor, MaterialProperty);
SetToggleOption(retDrawer, argToken);
break;
case "SpeedTreeGeometryType":
retDrawer = new AlloySpeedTreeGeometryTypeDrawer(editor, MaterialProperty);
SetDropdownOption(retDrawer, argToken);
break;
case "RenderingMode":
retDrawer = new AlloyRenderingModeDrawer(editor, MaterialProperty);
SetDropdownOption(retDrawer, argToken);
break;
case "Dropdown":
retDrawer = new AlloyDropdownDrawer(editor, MaterialProperty);
SetDropdownOption(retDrawer, argToken);
break;
case "LightmapEmissionProperty":
retDrawer = new AlloyLightmapEmissionDrawer(editor, MaterialProperty);
break;
case "RenderQueue":
retDrawer = new AlloyRenderQueueDrawer(editor, MaterialProperty);
break;
case "EnableInstancing":
retDrawer = new AlloyEnableInstancingDrawer(editor, MaterialProperty);
break;
}
}
if (retDrawer == null)
retDrawer = new AlloyFloatDrawer(editor, MaterialProperty);
return retDrawer;
}
private static void SetDropdownOption(AlloyFieldDrawer retDrawer, AlloyToken argToken) {
var drawer = retDrawer as AlloyDropdownDrawer;
if (drawer == null) {
return;
}
var options = argToken as AlloyCollectionToken;
if (options == null) {
return;
}
var dropOptions = new List<AlloyDropdownOption>();
for (int i = 0; i < options.SubTokens.Count; i++) {
AlloyArgumentToken arg = (AlloyArgumentToken)options.SubTokens[i];
var collection = arg.ArgumentToken as AlloyCollectionToken;
if (collection == null) {
continue;
}
// Split PascalCase name into words separated by spaces while skipping acronyms.
var dropOption = new AlloyDropdownOption {
Name = Regex.Replace(arg.ArgumentName, @"(?<=[A-Za-z])(?=[A-Z][a-z])|(?<=[a-z0-9])(?=[0-9]?[A-Z])", " "),
HideFields = collection.SubTokens.Select(alloyToken => alloyToken.Token).ToArray()
};
dropOptions.Add(dropOption);
}
drawer.DropOptions = dropOptions.ToArray();
}
private static void SetToggleOption(AlloyFieldDrawer retDrawer, AlloyToken argToken) {
var drawer = retDrawer as AlloyToggleDrawer;
if (drawer == null) {
return;
}
var collectionToken = argToken as AlloyCollectionToken;
if (collectionToken == null) {
return;
}
foreach (var token in collectionToken.SubTokens) {
var arg = token as AlloyArgumentToken;
if (arg != null && arg.ArgumentName == "On") {
var onToken = arg.ArgumentToken as AlloyCollectionToken;
if (onToken != null) {
drawer.OnHideFields = onToken.SubTokens.Select(colToken => colToken.Token).ToArray();
}
}
else if (arg != null && arg.ArgumentName == "Off") {
var offToken = arg.ArgumentToken as AlloyCollectionToken;
if (offToken != null) {
drawer.OffHideFields = offToken.SubTokens.Select(colToken => colToken.Token).ToArray();
}
}
}
}
private static void SetMinOption(AlloyFieldDrawer retDrawer, AlloyToken argToken) {
var floatDrawer = retDrawer as AlloyFloatDrawer;
var minValToken = argToken as AlloyValueToken;
if (floatDrawer != null) {
floatDrawer.HasMin = true;
if (minValToken != null) {
floatDrawer.MinValue = minValToken.FloatValue;
}
}
}
void SetSectionOption(AlloyFieldDrawer retDrawer, AlloyToken argToken) {
var sectionDrawer = retDrawer as AlloyTabDrawer;
if (sectionDrawer != null) {
var collectionToken = argToken as AlloyCollectionToken;
if (collectionToken == null) {
sectionDrawer.Color = c_defaultSectionColor;
}
else {
foreach (var token in collectionToken.SubTokens) {
var arg = token as AlloyArgumentToken;
if (arg != null && arg.ArgumentName == "Color") {
var value = arg.ArgumentToken as AlloyValueToken;
// Calculate color from section index and HSV scale factor.
if (value != null) {
var hueIndex = value.FloatValue;
if (hueIndex > -0.1f)
sectionDrawer.Color = Color.HSVToRGB((hueIndex / AlloyUtils.SectionColorMax) * 0.6f, 0.75f, 0.5f);
}
else {
// Manually specify color.
var colCollection = arg.ArgumentToken as AlloyCollectionToken;
if (colCollection != null) {
var r = colCollection.SubTokens[0] as AlloyValueToken;
var g = colCollection.SubTokens[1] as AlloyValueToken;
var b = colCollection.SubTokens[2] as AlloyValueToken;
if (r != null && g != null && b != null) {
sectionDrawer.Color = new Color32((byte)r.FloatValue, (byte)g.FloatValue, (byte)b.FloatValue, 255);
}
}
}
}
else if (arg != null && arg.ArgumentName == "Hide") {
var featureDrawer = sectionDrawer as AlloyFeatureDrawer;
var offToken = arg.ArgumentToken as AlloyCollectionToken;
if (offToken != null) {
featureDrawer.HideFields = offToken.SubTokens.Select(colToken => colToken.Token).ToArray();
}
}
}
}
}
}
public AlloyFloatParser(MaterialProperty field)
: base(field) {
}
}
public abstract class AlloyTabDrawer : AlloyFieldDrawer
{
public Color Color;
Func<bool, Action<Rect>> m_foldoutAction;
protected void SetAllTabsOpenedTo(bool open, AlloyFieldDrawerArgs args) {
foreach (var tab in args.AllTabNames) {
args.TabGroup.SetOpen(tab + args.MatInst, open);
}
}
public override bool ShouldDraw(AlloyFieldDrawerArgs args) {
return !args.PropertiesSkip.Contains(Property.name);
}
protected void DrawNow(AlloyFieldDrawerArgs args, bool optional) {
var firstDrawer = Index == 0;
var firstTab = string.IsNullOrEmpty(args.CurrentTab);
if (firstDrawer) {
GUILayout.Space(-10.0f);
}
else if (firstTab) {
GUILayout.Space(5.0f);
}
else {
if (args.DoDraw) {
GUILayout.Space(8.0f);
}
EditorGUILayout.EndFadeGroup();
}
if (!optional || args.Editor.TabIsEnabled(Property)) {
bool open;
if (firstTab && !optional) {
bool openAll = args.AllTabNames.All(tab => args.TabGroup.IsOpen(tab + args.MatInst));
bool closeOpen;
bool all = openAll;
open = args.TabGroup.TabArea(DisplayName, Color, true, m_foldoutAction(all), out closeOpen, DisplayName + args.MatInst);
if (closeOpen) {
openAll = !openAll;
SetAllTabsOpenedTo(openAll, args);
}
}
else {
bool removed;
open = args.TabGroup.TabArea(DisplayName, Color, optional, out removed, DisplayName + args.MatInst);
if (removed) {
args.Editor.DisableTab(DisplayName, Property, args.MatInst);
}
}
var anim = args.OpenCloseAnim[Property.name];
anim.target = open;
args.CurrentTab = Property.name;
args.DoDraw = EditorGUILayout.BeginFadeGroup(anim.faded);
}
else {
args.DoDraw = false;
args.TabsToAdd.Add(new AlloyTabAdd { Color = Color, Name = DisplayName, Enable = () => args.Editor.EnableTab(DisplayName, Property, args.MatInst) });
}
}
protected AlloyTabDrawer(AlloyInspectorBase editor, MaterialProperty property)
: base(editor, property) {
m_foldoutAction = all => r => GUI.Label(r, all ? "v" : ">", EditorStyles.whiteLabel);
}
}
public class AlloySectionDrawer : AlloyTabDrawer {
public override void Draw(AlloyFieldDrawerArgs args) {
DrawNow(args, false);
}
public AlloySectionDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyFeatureDrawer : AlloyTabDrawer {
public string[] HideFields;
public override bool ShouldDraw(AlloyFieldDrawerArgs args) {
return true;
}
public override void Draw(AlloyFieldDrawerArgs args) {
bool current = Property.floatValue > 0.5f;
DrawNow(args, true);
if (!current) {
if (HideFields != null) {
args.PropertiesSkip.AddRange(HideFields);
}
}
}
public AlloyFeatureDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyFloatDrawer : AlloyFieldDrawer
{
public bool HasMin;
public float MinValue;
public bool HasMax;
public float MaxValue;
int m_selectedIndex;
public override void Draw(AlloyFieldDrawerArgs args) {
if (HasMin || HasMax) {
if (HasMin && HasMax) {
FloatFieldSlider(DisplayName, MinValue, MaxValue);
}
else if (HasMin) {
FloatFieldMin(DisplayName, MinValue);
}
else {
FloatFieldMax(DisplayName, MaxValue);
}
}
else {
PropField(DisplayName);
}
}
public AlloyFloatDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyDropdownDrawer : AlloyFieldDrawer {
public AlloyDropdownOption[] DropOptions;
protected virtual bool OnSetOption(int newOption, AlloyFieldDrawerArgs args) {
return false;
}
public override void Draw(AlloyFieldDrawerArgs args) {
int current = (int)Property.floatValue;
var label = new GUIContent(DisplayName);
BeginMaterialProperty(Property);
int newVal = EditorGUILayout.Popup(label, current, DropOptions.Select(option => new GUIContent(option.Name)).ToArray());
EditorGUI.showMixedValue = false;
if (!OnSetOption(newVal, args) && EditorGUI.EndChangeCheck()) {
Property.floatValue = newVal;
MaterialEditor.ApplyMaterialPropertyDrawers(args.Materials);
}
MatEditor.EndAnimatedCheck();
args.PropertiesSkip.AddRange(DropOptions[current].HideFields);
}
public AlloyDropdownDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public abstract class AlloyBlendModeDropdownDrawer : AlloyDropdownDrawer {
public struct BlendModeOptionConfig {
public int Type;
public string OverrideTag;
public UnityEngine.Rendering.BlendMode SrcBlend;
public UnityEngine.Rendering.BlendMode DstBlend;
public int ZWrite;
public string Keyword;
public int RenderQueue;
}
protected BlendModeOptionConfig[] BlendModeOptionConfigs = null;
public AlloyBlendModeDropdownDrawer(AlloyInspectorBase editor, MaterialProperty property, BlendModeOptionConfig[] blendModeOptionConfigs) : base(editor, property) {
BlendModeOptionConfigs = blendModeOptionConfigs;
// Get default from keyword.
var keywords = editor.Target.shaderKeywords;
property.floatValue = 0.0f;
foreach (var setting in BlendModeOptionConfigs) {
if (keywords.Contains(setting.Keyword)) {
property.floatValue = setting.Type;
break;
}
}
}
protected override bool OnSetOption(int newOption, AlloyFieldDrawerArgs args) {
base.OnSetOption(newOption, args);
foreach (var material in args.Materials) {
if (Property.floatValue != newOption) {
foreach (var setting in BlendModeOptionConfigs) {
var keyword = setting.Keyword;
if (newOption != setting.Type) {
material.DisableKeyword(keyword);
}
else {
material.SetOverrideTag("RenderType", setting.OverrideTag);
material.SetInt("_SrcBlend", (int)setting.SrcBlend);
material.SetInt("_DstBlend", (int)setting.DstBlend);
material.SetInt("_ZWrite", setting.ZWrite);
material.EnableKeyword(keyword);
material.renderQueue = setting.RenderQueue;
}
}
material.SetInt(Property.name, newOption);
EditorUtility.SetDirty(material);
}
}
Undo.RecordObjects(args.Materials, "set " + Property.name);
return true;
}
}
public class AlloyToggleDrawer : AlloyFieldDrawer {
public string[] OnHideFields;
public string[] OffHideFields;
public override void Draw(AlloyFieldDrawerArgs args) {
bool current = Property.floatValue > 0.5f;
var label = new GUIContent(DisplayName);
//EditorGUI.BeginProperty(new Rect(), label, Serialized);
EditorGUI.showMixedValue = Property.hasMixedValue;
EditorGUI.BeginChangeCheck();
current = EditorGUILayout.Toggle(label, current);
if (EditorGUI.EndChangeCheck()) {
Property.floatValue = current ? 1.0f : 0.0f;
MaterialEditor.ApplyMaterialPropertyDrawers(args.Materials);
}
//EditorGUI.EndProperty();
EditorGUI.showMixedValue = false;
if (!current) {
if (OffHideFields != null) {
args.PropertiesSkip.AddRange(OffHideFields);
}
} else {
if (OnHideFields != null) {
args.PropertiesSkip.AddRange(OnHideFields);
}
}
}
public AlloyToggleDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 70c021998d433f440868615e1d5d09e2
timeCreated: 1430261565
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,400 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using Alloy;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
public class AlloyTextureFieldDrawer : AlloyFieldDrawer {
public enum TextureVisualizeMode {
None,
RGB,
R,
G,
B,
A,
NRM
}
public string ParentTexture {
get { return m_parentTexture; }
set {
m_parentTexture = value;
m_hasParentTexture = !string.IsNullOrEmpty(value);
}
}
public TextureVisualizeMode[] DisplayModes;
public bool Controls = true;
protected int TexInst;
string m_parentTexture = string.Empty;
bool m_hasParentTexture;
protected AlloyTabGroup TabGroup;
AnimBool m_tabOpen = new AnimBool(false);
bool m_firstDraw = true;
int m_vizIndex;
Material m_visualizeMat;
Renderer m_oldSelect;
static GUIContent[] s_uvModes = {new GUIContent("UV0"), new GUIContent("UV1")};
static GUILayoutOption[] s_texLayout = new GUILayoutOption[2];
Material VisualizeMaterial {
get {
if (m_visualizeMat == null) {
m_visualizeMat = new Material(Shader.Find("Hidden/Alloy Visualize")) {hideFlags = HideFlags.HideAndDontSave};
}
return m_visualizeMat;
}
}
protected virtual string TextureProp { get { return "m_Texture"; } }
TextureVisualizeMode Mode {
get { return m_vizIndex == 0 ? TextureVisualizeMode.None : DisplayModes[m_vizIndex - 1]; }
}
protected string SaveName { get { return Property.name + TexInst; } }
protected bool IsOpen { get { return TabGroup.IsOpen(SaveName); } }
//Passed in by the base editor
public AlloyTextureFieldDrawer(AlloyInspectorBase editor, MaterialProperty property)
: base(editor, property) {
TabGroup = AlloyTabGroup.GetTabGroup();
m_tabOpen.value = TabGroup.IsOpen(SaveName);
m_tabOpen.speed = 4.0f;
}
void AdvanceMode() {
m_vizIndex = (m_vizIndex + 1) % (DisplayModes.Length + 1);
}
string GetVisualizeButtonText() {
return Mode == TextureVisualizeMode.None ? "Visualize" : Mode.ToString();
}
void TextureField(float size, MaterialProperty prop, AlloyFieldDrawerArgs args) {
var rawRef = prop.textureValue;
if (rawRef == null
&& !prop.hasMixedValue
&& (!IsOpen || m_hasParentTexture)) {
s_texLayout[0] = GUILayout.Width(100.0f);
s_texLayout[1] = GUILayout.Height(16.0f);
}
else {
s_texLayout[0] = GUILayout.Width(size - 20.0f);
s_texLayout[1] = GUILayout.Height((size - 20.0f) * 0.9f);
}
BeginMaterialProperty(Property);
var tex = EditorGUILayout.ObjectField(rawRef, typeof(Texture), false, s_texLayout) as Texture;
if (EndMaterialProperty()) {
prop.textureValue = tex;
}
}
bool DrawWarningString(MaterialProperty texture) {
//normal map warning
if (DisplayModes == null) {
return false;
}
if (ArrayUtility.Contains(DisplayModes, TextureVisualizeMode.NRM)) {
if (texture.hasMixedValue || texture.textureValue == null) {
return false;
}
string path = AssetDatabase.GetAssetPath(texture.textureValue);
if (!string.IsNullOrEmpty(path)) {
var imp = AssetImporter.GetAtPath(path);
var importer = imp as TextureImporter;
// If the texture isn't a Normal Map, offer to convert it.
if (importer != null && importer.textureType != TextureImporterType.NormalMap) {
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox("Texture not marked as normal map", MessageType.Warning, true);
var rect = GUILayoutUtility.GetLastRect();
rect.xMin += rect.width / 2;
GUILayout.BeginVertical();
GUILayout.Space(14.0f);
if (GUILayout.Button("Fix now", EditorStyles.toolbarButton, GUILayout.Width(60.0f))) {
importer.textureType = TextureImporterType.NormalMap;
AssetDatabase.ImportAsset(path);
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
return true;
}
}
}
return false;
}
void DrawVisualizeButton() {
if (DisplayModes != null && DisplayModes.Length > 0
&& Selection.activeGameObject && Selection.objects.Length == 1) {
if (GUILayout.Button(GetVisualizeButtonText(), EditorStyles.toolbarButton, GUILayout.Width(70.0f))) {
AdvanceMode();
EditorApplication.delayCall += SceneView.RepaintAll;
}
}
}
public override void OnDisable() {
if (Mode != TextureVisualizeMode.None) {
if (m_oldSelect != null) {
EditorUtility.SetSelectedRenderState(m_oldSelect, EditorSelectedRenderState.Highlight);
}
m_vizIndex = 0;
}
}
public override void OnSceneGUI(Material[] materials) {
if (materials.Length > 1) {
return;
}
var material = materials[0];
if (Mode == TextureVisualizeMode.None || Selection.activeGameObject == null || Selection.objects.Length != 1) {
if (m_oldSelect != null) {
EditorUtility.SetSelectedRenderState(m_oldSelect, EditorSelectedRenderState.Highlight);
}
return;
}
var curTex = Property.textureValue;
if (Mode == TextureVisualizeMode.None) {
return;
}
var trans = Property.textureScaleAndOffset;
var uvMode = 0.0f;
var uvName = !m_hasParentTexture ? Property.name + "UV" : m_parentTexture + "UV";
if (material.HasProperty(uvName)) {
uvMode = material.GetFloat(uvName);
}
VisualizeMaterial.SetTexture("_MainTex", curTex);
VisualizeMaterial.SetFloat("_Mode", (int) Mode);
VisualizeMaterial.SetVector("_Trans", trans);
VisualizeMaterial.SetFloat("_UV", uvMode);
var target = Selection.activeGameObject.GetComponent<Renderer>();
if (target != m_oldSelect && m_oldSelect != null) {
EditorApplication.delayCall += SceneView.RepaintAll;
EditorUtility.SetSelectedRenderState(target, EditorSelectedRenderState.Highlight);
return;
}
m_oldSelect = target;
Mesh mesh = null;
var meshFilter = target.GetComponent<MeshFilter>();
var meshRenderer = target.GetComponent<MeshRenderer>();
if (meshFilter != null && meshRenderer != null) {
mesh = meshFilter.sharedMesh;
}
if (mesh == null) {
var skinnedMeshRenderer = target.GetComponent<SkinnedMeshRenderer>();
if (skinnedMeshRenderer != null) {
mesh = skinnedMeshRenderer.sharedMesh;
}
}
if (mesh != null) {
EditorUtility.SetSelectedRenderState(target, EditorSelectedRenderState.Hidden);
Graphics.DrawMesh(mesh, target.localToWorldMatrix, VisualizeMaterial, 0, SceneView.currentDrawingSceneView.camera,
TexInst);
SceneView.currentDrawingSceneView.Repaint();
}
else {
Debug.LogError("Game object does not have a mesh source.");
}
}
public override void Draw(AlloyFieldDrawerArgs args) {
TexInst = args.MatInst;
if (m_firstDraw) {
OnFirstDraw();
m_firstDraw = false;
}
var curTex = Property.textureValue;
GUILayout.Space(9.0f);
GUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical();
float oldWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 80.0f;
bool drewOpen = false;
if (m_hasParentTexture || !Controls) {
GUILayout.Label(DisplayName);
}
else {
bool isOpen = TabGroup.Foldout(DisplayName, SaveName, GUILayout.Width(10.0f));
m_tabOpen.target = isOpen;
if (EditorGUILayout.BeginFadeGroup(m_tabOpen.faded)) {
drewOpen = true;
DrawTextureControls(args);
}
EditorGUILayout.EndFadeGroup();
}
if ((EditorGUILayout.BeginFadeGroup(1.0f - m_tabOpen.faded)
|| !Controls)
&& curTex != null
&& !Property.hasMixedValue) {
if (!DrawWarningString(Property)) {
var oldCol = GUI.color;
GUI.color = EditorGUIUtility.isProSkin ? Color.gray : new Color(0.3f, 0.3f, 0.3f);
string name = curTex.name;
if (name.Length > 17) {
name = name.Substring(0, 14) + "..";
}
GUILayout.Label(name + " (" + curTex.width + "x" + curTex.height + ")", EditorStyles.whiteLabel);
GUI.color = oldCol;
}
}
EditorGUILayout.EndFadeGroup();
if (curTex != null
&& (!m_hasParentTexture || Controls)
&& !Property.hasMixedValue) {
DrawVisualizeButton();
}
if (drewOpen) {
EditorGUILayout.EndVertical();
TextureField(Mathf.Lerp(74.0f, 100.0f, m_tabOpen.faded), Property, args);
}
else {
GUILayout.EndVertical();
GUILayout.FlexibleSpace();
TextureField(74.0f, Property, args);
}
EditorGUIUtility.labelWidth = oldWidth;
GUILayout.EndHorizontal();
if (IsOpen) {
GUILayout.Space(10.0f);
}
if (m_tabOpen.isAnimating) {
args.Editor.MatEditor.Repaint();
}
}
protected void DrawTextureControls(AlloyFieldDrawerArgs args) {
string velName = Property.name + "Velocity";
var scrollProp = args.GetMaterialProperty(velName);
string spinName = Property.name + "Spin";
var spinProp = args.GetMaterialProperty(spinName);
string uvName = Property.name + "UV";
var uvProp = args.GetMaterialProperty(uvName);
BeginMaterialProperty(Property);
var trans = Property.textureScaleAndOffset;
Vector2 tileVal = EditorGUILayout.Vector2Field("Tiling", new Vector2(trans.x, trans.y));
Vector2 offsetVal = EditorGUILayout.Vector2Field("Offset", new Vector2(trans.z, trans.w));
trans.x = tileVal.x;
trans.y = tileVal.y;
trans.z = offsetVal.x;
trans.w = offsetVal.y;
if (scrollProp != null) {
BeginMaterialProperty(scrollProp);
Vector2 curScroll = EditorGUILayout.Vector2Field("Scroll", scrollProp.vectorValue);
if (EndMaterialProperty()) {
scrollProp.vectorValue = curScroll;
}
}
float old = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 75.0f;
if (spinProp != null) {
BeginMaterialProperty(spinProp);
float spin = spinProp.floatValue * Mathf.Rad2Deg;
spin = EditorGUILayout.FloatField(new GUIContent("Spin"), spin, GUILayout.Width(180.0f));
if (EndMaterialProperty()) {
spinProp.floatValue = spin * Mathf.Deg2Rad;
}
}
if (uvProp != null) {
BeginMaterialProperty(uvProp);
float newVal = EditorGUILayout.Popup(new GUIContent("UV Set"), (int) uvProp.floatValue, s_uvModes,
GUILayout.Width(180.0f));
if (EndMaterialProperty()) {
uvProp.floatValue = newVal;
}
}
EditorGUIUtility.labelWidth = old;
if (EndMaterialProperty()) {
Property.textureScaleAndOffset = trans;
}
}
void OnFirstDraw() {
m_tabOpen.value = IsOpen;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 26f92e852a911224cbd5f29a496d6698
timeCreated: 1430261489
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,67 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.Linq;
using UnityEditor;
public class AlloyTextureParser : AlloyFieldParser
{
protected override AlloyFieldDrawer GenerateDrawer(AlloyInspectorBase editor) {
var ret = new AlloyTextureFieldDrawer(editor, MaterialProperty);
foreach (var token in Arguments) {
var argName = token.ArgumentName;
var argToken = token.ArgumentToken;
switch (argName) {
case "Visualize": {
var container = argToken as AlloyCollectionToken;
if (container != null) {
ret.DisplayModes = container.SubTokens.Select(t => (AlloyTextureFieldDrawer.TextureVisualizeMode)Enum.Parse(typeof(AlloyTextureFieldDrawer.TextureVisualizeMode), t.Token)).ToArray();
}
}
break;
case "Parent": {
ret.ParentTexture = argToken.Token;
}
break;
case "Controls":
var valueToken = argToken as AlloyValueToken;
if (valueToken != null) {
ret.Controls = valueToken.BoolValue;
}
break;
// case "Keyword":
// ret.Keyword = argToken.Token;
// break;
}
}
return ret;
}
public AlloyTextureParser(MaterialProperty field)
: base(field) {
}
}
public class AlloyCubeParser : AlloyFieldParser
{
public AlloyCubeParser(MaterialProperty field)
: base(field) {
}
protected override AlloyFieldDrawer GenerateDrawer(AlloyInspectorBase editor) {
return new AlloyDefaultDrawer(editor, MaterialProperty);
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5767db00543c76746b04f3bf27442325
timeCreated: 1430261463
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,184 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using Alloy;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
using UnityEngine.UI;
public class AlloyVectorParser : AlloyFieldParser {
protected override AlloyFieldDrawer GenerateDrawer(AlloyInspectorBase editor) {
AlloyFieldDrawer ret = null;
for (int i = 0; i < Arguments.Length; i++) {
var argument = Arguments[i];
var valProp = argument.ArgumentToken as AlloyValueToken;
switch (argument.ArgumentName) {
case "Vector":
if (valProp != null) {
ret = SetupVectorDrawer(editor, valProp, ret);
}
break;
}
}
if (ret == null) {
ret = new AlloyVectorDrawer(editor, MaterialProperty);
((AlloyVectorDrawer) ret).Mode = AlloyVectorDrawer.VectorMode.Vector4;
}
return ret;
}
AlloyFieldDrawer SetupVectorDrawer(AlloyInspectorBase editor,
AlloyValueToken valProp,
AlloyFieldDrawer ret) {
if (valProp.ValueType == AlloyValueToken.ValueTypeEnum.String) {
switch (valProp.StringValue) {
case "Euler":
ret = new AlloyVectorDrawer(editor, MaterialProperty);
((AlloyVectorDrawer) ret).Mode = AlloyVectorDrawer.VectorMode.Euler;
break;
case "TexCoord":
ret = new AlloyTexCoordDrawer(editor, MaterialProperty);
break;
case "Channels":
ret = new AlloyMaskDrawer(editor, MaterialProperty);
break;
default:
Debug.LogError("Non supported vector property!");
break;
}
}
else if (valProp.ValueType == AlloyValueToken.ValueTypeEnum.Float) {
switch ((int) valProp.FloatValue) {
case 2:
ret = new AlloyVectorDrawer(editor, MaterialProperty);
((AlloyVectorDrawer) ret).Mode = AlloyVectorDrawer.VectorMode.Vector2;
break;
case 3:
ret = new AlloyVectorDrawer(editor, MaterialProperty);
((AlloyVectorDrawer) ret).Mode = AlloyVectorDrawer.VectorMode.Vector3;
break;
case 4:
ret = new AlloyVectorDrawer(editor, MaterialProperty);
((AlloyVectorDrawer) ret).Mode = AlloyVectorDrawer.VectorMode.Vector4;
break;
default:
Debug.LogError("Non supported vector property!");
break;
}
}
return ret;
}
public AlloyVectorParser(MaterialProperty field)
: base(field) {
}
}
public class AlloyVectorDrawer : AlloyFieldDrawer {
public enum VectorMode {
Vector2,
Vector3,
Vector4,
Euler
}
public VectorMode Mode = VectorMode.Vector4;
public override void Draw(AlloyFieldDrawerArgs args) {
Vector4 newVal = Vector4.zero;
var label = new GUIContent(DisplayName);
BeginMaterialProperty(Property);
switch (Mode) {
case VectorMode.Vector4:
newVal = EditorGUILayout.Vector4Field(label.text, Property.vectorValue);
break;
case VectorMode.Vector3:
newVal = EditorGUILayout.Vector3Field(label.text, Property.vectorValue);
break;
case VectorMode.Vector2:
newVal = EditorGUILayout.Vector2Field(label.text, Property.vectorValue);
break;
case VectorMode.Euler:
var value = args.GetMaterialProperty(Property.name + "EulerUI").vectorValue;
//var value = (Vector4)args.Editor.GetProperty(MaterialProperty.PropType.Vector, Property.name + "EulerUI").colorValue;
newVal = Quaternion.Euler(value) * Vector3.up;
GUI.changed = true;
break;
}
if (EndMaterialProperty()) {
Property.vectorValue = newVal;
}
}
public AlloyVectorDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
}
public class AlloyTexCoordDrawer : AlloyTextureFieldDrawer {
AnimBool m_tabOpen = new AnimBool(false);
public AlloyTexCoordDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
public override void Draw(AlloyFieldDrawerArgs args) {
TexInst = args.MatInst;
bool isOpen = TabGroup.Foldout(DisplayName, SaveName, GUILayout.Width(10.0f));
m_tabOpen.target = isOpen;
if (m_tabOpen.value) {
EditorGUILayout.BeginFadeGroup(m_tabOpen.faded);
DrawTextureControls(args);
EditorGUILayout.EndFadeGroup();
}
if (m_tabOpen.isAnimating) {
args.Editor.MatEditor.Repaint();
}
}
}
public class AlloyMaskDrawer : AlloyFieldDrawer {
public AlloyMaskDrawer(AlloyInspectorBase editor, MaterialProperty property) : base(editor, property) {
}
public override void Draw(AlloyFieldDrawerArgs args) {
Vector4 newVal = Property.vectorValue;
var label = new GUIContent(DisplayName);
BeginMaterialProperty(Property);
GUILayout.BeginHorizontal();
GUILayout.Label(label);
newVal.x = GUILayout.Toggle(newVal.x > 0.5f, "R", EditorStyles.toolbarButton) ? 1.0f : 0.0f;
newVal.y = GUILayout.Toggle(newVal.y > 0.5f, "G", EditorStyles.toolbarButton) ? 1.0f : 0.0f;
newVal.z = GUILayout.Toggle(newVal.z > 0.5f, "B", EditorStyles.toolbarButton) ? 1.0f : 0.0f;
newVal.w = GUILayout.Toggle(newVal.w > 0.5f, "A", EditorStyles.toolbarButton) ? 1.0f : 0.0f;
GUILayout.EndHorizontal();
if (EndMaterialProperty()) {
Property.vectorValue = newVal;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6c2ebab9324a76547a9d5df7b45cd747
timeCreated: 1430261728
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 6e87a104f11c6ab4295a1bec1f86e81c
folderAsset: yes
DefaultImporter:
userData:
@@ -0,0 +1,77 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
Shader "Hidden/Alloy Visualize" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Mode("Mode", Float) = 0
_Trans("Trans", Vector) = (0, 0, 0, 0)
_UV("UV", Float) = 0
}
SubShader {
Offset 0,-10
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
struct v2f {
float4 pos : SV_POSITION;
float2 uv_MainTex : TEXCOORD0;
};
float4 _MainTex_ST;
float _Mode;
float _UV;
v2f vert(appdata_full v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex.xyz);
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
//o.pos.w += 1e-5;
o.uv_MainTex = _UV == 0.0f ? v.texcoord.xy : v.texcoord1.xy;
return o;
}
sampler2D _MainTex;
float4 _Trans;
float4 frag(v2f IN) : SV_Target {
float4 c = tex2D (_MainTex, IN.uv_MainTex * _Trans.xy + _Trans.zw).rgba;
float eps = 0.001f;
if (_Mode <= eps){
c.rgb = 0.0f;
}
else if (_Mode <= 1 + eps) {
c.rgb = c.rgb; // Assumes automatic sRGB
}
else if (_Mode <= 2 + eps){
c.rgb = pow(c.rrr, 2.2f);
}
else if (_Mode <= 3 + eps){
c.rgb = pow(c.ggg, 2.2f);
}
else if (_Mode <= 4 + eps){
c.rgb = pow(c.bbb, 2.2f);
}
else if (_Mode <= 5 + eps){
c.rgb = pow(c.aaa, 2.2f);
}
else if (_Mode <= 6 + eps){
c.rgb = pow(UnpackNormal(c) * 0.5f + 0.5f, 2.2f);
}
return c;
}
ENDCG
}
}
}
@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 5bca5ef19340cc044b0acb00214f111b
ShaderImporter:
defaultTextures: []
userData:
@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 2c93dc09429ea9e4fa76bf67d52294fc
folderAsset: yes
DefaultImporter:
userData:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a69ac5a688c6fbb428b61b55448c7392
folderAsset: yes
timeCreated: 1467548303
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,41 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f11657fe81562504cb1b05d4e700d54d, type: 3}
m_Name: AlphaPack
m_EditorClassIdentifier:
Title: Alpha
Suffix: _AlloyAM
VarianceBias: 1
ImportSettings:
IsLinear: 0
Filter: 2
DefaultCompressed: 1
Channels:
- Title: Color
HelpText:
BackgroundColor: {r: 0, g: .583999991, b: .0520000011, a: 1}
CanInvert: 0
InputChannels: 7
OutputChannels: 7
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Alpha
HelpText:
BackgroundColor: {r: 0, g: 0, b: 0, a: 1}
CanInvert: 1
InputChannels: 2
OutputChannels: 8
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5d1947582bfff244299d3af2cb6ab782
timeCreated: 1439420452
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f11657fe81562504cb1b05d4e700d54d, type: 3}
m_Name: MasksPack
m_EditorClassIdentifier:
Title: Masks
Suffix: _AlloyMM
VarianceBias: 1
ImportSettings:
IsLinear: 1
Filter: 2
DefaultCompressed: 1
Channels:
- Title: Red
HelpText:
BackgroundColor: {r: 0.5882353, g: 0, b: 0, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 2
OutputChannels: 1
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Green
HelpText:
BackgroundColor: {r: 0, g: 0.584, b: 0.052, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 2
OutputChannels: 2
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Blue
HelpText:
BackgroundColor: {r: 0.043137256, g: 0, b: 0.5803922, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 2
OutputChannels: 4
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Alpha
HelpText:
BackgroundColor: {r: 0, g: 0, b: 0, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 2
OutputChannels: 8
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f0d4fc30aba4a084ba51be9301faf8a9
timeCreated: 1439420318
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,61 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f11657fe81562504cb1b05d4e700d54d, type: 3}
m_Name: PackedPack
m_EditorClassIdentifier:
Title: Packed
Suffix: _AlloyPM
VarianceBias: 1
ImportSettings:
IsLinear: 1
Filter: 2
DefaultCompressed: 1
Channels:
- Title: Metallic
HelpText: Black = Non-metal, White = Metal
BackgroundColor: {r: .588235319, g: 0, b: 0, a: 1}
CanInvert: 1
InputChannels: 2
OutputChannels: 1
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Occlusion
HelpText: Black = Occluded, White = Unoccluded
BackgroundColor: {r: 0, g: .583999991, b: .0520000011, a: 1}
CanInvert: 1
InputChannels: 2
OutputChannels: 2
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Specularity
HelpText: Black = Air, Gray = Paint, White = Gems
BackgroundColor: {r: .0431372561, g: 0, b: .580392182, a: 1}
CanInvert: 1
InputChannels: 2
OutputChannels: 4
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 1
- Title: Roughness
HelpText: Black = Smooth, White = Rough
BackgroundColor: {r: 0, g: 0, b: 0, a: 1}
CanInvert: 1
InputChannels: 2
OutputChannels: 8
RoughnessCorrect: 1
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1d42740116df09f4f9c9e144a4b9885f
timeCreated: 1439419411
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,41 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f11657fe81562504cb1b05d4e700d54d, type: 3}
m_Name: TerrainPack
m_EditorClassIdentifier:
Title: Terrain
Suffix: _AlloyTM
VarianceBias: 1
ImportSettings:
IsLinear: 0
Filter: 2
DefaultCompressed: 1
Channels:
- Title: Color
HelpText: Base color for terrain.
BackgroundColor: {r: 0, g: 0.584, b: 0.052, a: 1}
CanInvert: 0
InputChannels: 7
OutputChannels: 7
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Roughness
HelpText: Black = Smooth, White = Rough
BackgroundColor: {r: 0, g: 0, b: 0, a: 1}
CanInvert: 1
InputChannels: 2
OutputChannels: 8
RoughnessCorrect: 1
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2bf47aefc6b2d2b4fa519cb677bb4346
timeCreated: 1439420067
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f11657fe81562504cb1b05d4e700d54d, type: 3}
m_Name: UnityPackedPack
m_EditorClassIdentifier:
Title: Unity PM
Suffix: _AlloyUPM
VarianceBias: 1
ImportSettings:
IsLinear: 1
Filter: 2
DefaultCompressed: 1
Channels:
- Title: Metallic
HelpText: Black = Non-metal, White = Metal
BackgroundColor: {r: 0.5882353, g: 0, b: 0, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 1
OutputChannels: 1
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Occlusion
HelpText: Black = Occluded, White = Unoccluded
BackgroundColor: {r: 0, g: 0.584, b: 0.052, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 2
OutputChannels: 2
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Specularity
HelpText: Black = Air, Gray = Paint, White = Gems
BackgroundColor: {r: 0.043137256, g: 0, b: 0.5803922, a: 1}
CanInvert: 1
InvertByDefault: 0
InputChannels: 4
OutputChannels: 4
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 1
- Title: Smoothness
HelpText: Black = Rough, White = Smooth
BackgroundColor: {r: 0, g: 0, b: 0, a: 1}
CanInvert: 1
InvertByDefault: 1
InputChannels: 8
OutputChannels: 8
RoughnessCorrect: 1
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 23522b2d0809c9c4d9428659169ec2a1
timeCreated: 1458592032
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,43 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f11657fe81562504cb1b05d4e700d54d, type: 3}
m_Name: UnityTerrainPack
m_EditorClassIdentifier:
Title: Unity TM
Suffix: _AlloyUTM
VarianceBias: 1
ImportSettings:
IsLinear: 0
Filter: 2
DefaultCompressed: 1
Channels:
- Title: Color
HelpText: Base color for terrain.
BackgroundColor: {r: 0, g: 0.584, b: 0.052, a: 1}
CanInvert: 0
InvertByDefault: 0
InputChannels: 7
OutputChannels: 7
RoughnessCorrect: 0
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
- Title: Smoothness
HelpText: Black = Rough, White = Smooth
BackgroundColor: {r: 0, g: 0, b: 0, a: 1}
CanInvert: 1
InvertByDefault: 1
InputChannels: 8
OutputChannels: 8
RoughnessCorrect: 1
OutputVariance: 0
HideChannel: 0
DefaultMode: 4
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 972cff293012f9740a9250f756d7418b
timeCreated: 1458593840
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,26 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e5c13c2962344f14d8d0d22b07fa9495, type: 3}
m_Name: _PackerDefinition
m_EditorClassIdentifier:
PackedMaps:
- {fileID: 11400000, guid: 1d42740116df09f4f9c9e144a4b9885f, type: 2}
- {fileID: 11400000, guid: 2bf47aefc6b2d2b4fa519cb677bb4346, type: 2}
- {fileID: 11400000, guid: f0d4fc30aba4a084ba51be9301faf8a9, type: 2}
- {fileID: 11400000, guid: 5d1947582bfff244299d3af2cb6ab782, type: 2}
- {fileID: 11400000, guid: 23522b2d0809c9c4d9428659169ec2a1, type: 2}
- {fileID: 11400000, guid: 972cff293012f9740a9250f756d7418b, type: 2}
NRMChannel:
Title: Normal map
HelpText: (Optional) Used for Specular AA
BackgroundColor: {r: 0.322, g: 0, b: 0.472, a: 1}
VarianceText: Bias normal map variance toward zero to reduce Specular AA effect.
AutoRegenerateText: Regenerate this map when any of its input textures are updated./
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e29b4e8febd8e3949a1d18cf25c0271a
timeCreated: 1491251285
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 0ce61627d85169d48874646872429200
folderAsset: yes
DefaultImporter:
userData:
@@ -0,0 +1,288 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.Linq;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Alloy {
public class AlloyCustomImportAction : AssetPostprocessor {
delegate void OnAlloyImportFunc(AlloyCustomImportObject settings, Texture2D texture, string path);
public static bool IsAlloyPackedMapPath(string path) {
path = Path.GetFileNameWithoutExtension(path);
var definition = AlloyMaterialMapChannelPacker.GlobalDefinition;
//Alloy not imported yet -> Assume we're either importing new alloy
//and we're importing it now
if (definition == null) {
return false;
}
return definition.IsPackedMap(path);
}
//Make sure to generate PNG alongside .asset file if it doesn't exist yet
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets,
string[] movedFromAssetPath) {
foreach (var asset in importedAssets) {
if (!IsAlloyPackedMapPath(asset)) {
continue;
}
if (File.Exists(asset.Replace(".asset", ".png"))) {
continue;
}
var settings = AssetDatabase.LoadAssetAtPath(asset, typeof (AlloyCustomImportObject)) as AlloyCustomImportObject;
if (settings != null) {
settings.GenerateMap();
}
}
}
private void OnAlloyImport(Texture2D texture, OnAlloyImportFunc onImport) {
// Check to see if this is an Alloy material that we need to edit.
if (!IsAlloyPackedMapPath(assetPath)) {
return;
}
// and if we've got saved settings/data for it...
var textureName = Path.GetFileNameWithoutExtension(assetPath);
var path = Path.Combine(Path.GetDirectoryName(assetPath), textureName) + ".asset";
//Import can fail because of a variety of reasons, so make sure it's all good here
if (!File.Exists(path)) {
Debug.LogError(textureName + " has no post-processing data! Please contact Alloy support.");
Selection.activeObject = texture;
return;
}
var settings = AssetDatabase.LoadAssetAtPath(path, typeof (AlloyCustomImportObject)) as AlloyCustomImportObject;
if (settings == null) {
if (AlloyImporterSupervisor.IsFinalTry) {
Debug.LogError(textureName + " settings file is corrupt! Contact Alloy support");
return;
}
AlloyImporterSupervisor.OnFailedImport(path);
return;
}
for (int i = 0; i < 4; ++i) {
if (settings.SelectedModes[i] == TextureValueChannelMode.Texture && settings.GetTexture(i) == null) {
if (AlloyImporterSupervisor.IsFinalTry) {
Debug.LogError(textureName + " texture input " + (i + 1) + " can't be loaded!");
return;
}
AlloyImporterSupervisor.OnFailedImport(path);
return;
}
}
if (!string.IsNullOrEmpty(settings.NormalGUID) && settings.NormalMapTexture == null) {
if (AlloyImporterSupervisor.IsFinalTry) {
Debug.LogError(textureName + " normalmap texture input can't be loaded!");
return;
}
AlloyImporterSupervisor.OnFailedImport(path);
return;
}
//If it's all good, do the importing action
onImport(settings, texture, path);
}
void ApplyImportSettings(AlloyCustomImportObject settings, Texture2D texture, string path) {
var importer = assetImporter as TextureImporter;
var size = settings.GetOutputSize();
var def = settings.PackMode;
var importSettings = def.ImportSettings;
importer.textureType = TextureImporterType.Default;
importer.sRGBTexture = !importSettings.IsLinear;
importer.filterMode = importSettings.Filter;
importer.mipmapEnabled = true;
// They need the ability to set this themselves, but we should cap it.
var nextPowerOfTwo = Mathf.NextPowerOfTwo((int) Mathf.Max(size.x, size.y));
if (importer.maxTextureSize > nextPowerOfTwo) {
importer.maxTextureSize = nextPowerOfTwo;
}
// Allow setting to uncompressed, else use compressed. Disallows any other format!
if (def.ImportSettings.DefaultCompressed
&& importer.textureCompression != TextureImporterCompression.Uncompressed
&& importer.textureCompression != TextureImporterCompression.CompressedLQ
&& importer.textureCompression != TextureImporterCompression.CompressedHQ) {
importer.textureCompression = TextureImporterCompression.Compressed;
}
}
private void HandleAutoRefresh() {
var paths = AssetDatabase.GetAllAssetPaths();
var texGUID = AssetDatabase.AssetPathToGUID(assetPath);
foreach (var path in paths) {
if (!IsAlloyPackedMapPath(path)) {
continue;
}
var setting = AssetDatabase.LoadAssetAtPath(path, typeof (AlloyCustomImportObject)) as AlloyCustomImportObject;
if (setting == null || (texGUID != setting.NormalGUID && !setting.TexturesGUID.Contains(texGUID))) {
continue;
}
if (setting.DoAutoRegenerate) {
AssetDatabase.ImportAsset(path.Replace(".asset", ".png"));
}
}
}
private void OnPreprocessTexture() {
OnAlloyImport(null, ApplyImportSettings);
HandleAutoRefresh();
}
private void OnPostprocessTexture(Texture2D texture) {
OnAlloyImport(texture, GeneratePackedMaterialMap);
}
public static void CreatePostProcessingInformation(string filePath, AlloyCustomImportObject settings) {
settings.hideFlags = HideFlags.None;
AssetDatabase.CreateAsset(settings, filePath);
}
/// <summary>
/// Generates the packed material map for an object
/// </summary>
public static void GeneratePackedMaterialMap(AlloyCustomImportObject settings, Texture2D target, string filePath) {
var size = settings.GetOutputSize();
var normalMap = settings.NormalMapTexture;
var useUnityGeneratedMipmaps = normalMap == null;
int width = (int) size.x;
int height = (int) size.y;
int mipmapCount = 1;
// When explicitly generating mip levels pick output count based on the largest input texture.
if (!useUnityGeneratedMipmaps) {
mipmapCount = GetMipmapCount(normalMap);
for (int i = 0; i < 4; ++i) {
if (settings.SelectedModes[i] != TextureValueChannelMode.Texture
|| settings.GetTexture(i) == null) {
continue;
}
mipmapCount = Math.Max(mipmapCount, GetMipmapCount(settings.GetTexture(i)));
}
}
// Adjust the dimensions of the output texture if necessary.
if (target.width != width || target.height != height) {
target.Resize(width, height);
}
if (!Mathf.IsPowerOfTwo(width) || !Mathf.IsPowerOfTwo(height)) {
Debug.LogWarning(
"Alloy: Texture resolution is not power of 2; will have issues generating correct mip maps if custom sizing is specified in generated texture platform settings.");
}
// Get readable input textures.
var readableNormal = AlloyTextureReader.GetReadable(normalMap, true);
var readableTextures = new Texture2D[settings.TexturesGUID.Length];
for (int i = 0; i < settings.TexturesGUID.Length; ++i) {
if (settings.SelectedModes[i] != TextureValueChannelMode.Texture) {
continue;
}
var settingsTex = settings.GetTexture(i);
if (settingsTex == null) {
readableTextures[i] = null;
} else {
readableTextures[i] = AlloyTextureReader.GetReadable(settingsTex, false);
}
}
// Use renderer to sample mipmaps.
try {
var message = string.Format("Packing: \"{0}\"", settings.name);
var progress = 1.0f;
var bodyText = message;
for (int mipLevel = 0; mipLevel < mipmapCount; mipLevel++) {
if (mipmapCount > 1) {
progress = (float)mipLevel / (mipmapCount - 1);
bodyText = string.Format("{0} ({1})", message, progress.ToString("0%"));
}
EditorUtility.DisplayProgressBar("Building Packed maps...", bodyText, progress);
// CPU Method - more reliable/consistent across GPUs, but slower.
var normalCache = new AlloyTextureColorCache(readableNormal, target);
UnityEngine.Profiling.Profiler.BeginSample("Read");
var texCache = readableTextures.Select(tex => new AlloyTextureColorCache(tex, target)).ToArray();
UnityEngine.Profiling.Profiler.EndSample();
AlloyPackerCompositor.CompositeMips(target, settings, texCache, normalCache, mipLevel);
}
} finally {
EditorUtility.ClearProgressBar();
}
// Clean up the readable textures.
foreach (var texture in readableTextures) {
Object.DestroyImmediate(texture);
}
Object.DestroyImmediate(readableNormal);
// Update the texture's associated settings .asset object.
settings.Width = width;
settings.Height = height;
settings.MaxResolution = 0;
EditorUtility.SetDirty(settings);
// Update the texture object.
target.Apply(useUnityGeneratedMipmaps, false);
}
private static int GetMipmapCount(Texture tex) {
int count = 1;
var texture2D = tex as Texture2D;
var renderTexture = tex as RenderTexture;
var proceduralTexture = tex as ProceduralTexture;
if (texture2D != null) {
count = texture2D.mipmapCount;
} else if (renderTexture != null) {
count = renderTexture.useMipMap ? GetMipCountFromSize(tex) : 1;
} else if (proceduralTexture != null) {
var mat =
proceduralTexture.GetType()
.GetMethod("GetProceduralMaterial", BindingFlags.Instance | BindingFlags.NonPublic)
.Invoke(proceduralTexture, null) as ProceduralMaterial;
var imp = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(mat)) as SubstanceImporter;
count = imp != null && imp.GetGenerateMipMaps(mat) ? GetMipCountFromSize(tex) : 1;
}
return count;
}
private static int GetMipCountFromSize(Texture tex) {
return Mathf.CeilToInt(Mathf.Log(Mathf.Max(tex.width, tex.height), 2.0f)) + 1;
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e111aca273d4c2b4783aa7111c7f715f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,161 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace Alloy
{
// This stores information used by the asset re-importer;
// to rebuild Mip Maps with corrected roughness information.
public class AlloyCustomImportObject : ScriptableObject
{
[HideInInspector]
public Vector4 ChannelValues = new Vector4(0.0f, 0.0f, 0.5f, 0.0f);
public string[] TexturesGUID = {"", "", "", ""};
public string NormalGUID;
public bool[] DoInvert = {false, false, false, false};
public float VarianceBias;
public int Width;
public int Height;
public bool DoAutoRegenerate;
public TextureValueChannelMode[] SelectedModes = {
TextureValueChannelMode.Texture,
TextureValueChannelMode.Texture,
TextureValueChannelMode.Gray,
TextureValueChannelMode.Texture
};
Texture2D[] m_textures;
public static readonly int[] s_Resolutions = {0, 32, 64, 128, 256, 512, 1024, 2048, 4096};
[HideInInspector] public int MaxResolution = 0;
/// ///LEGACY:
public bool IsDetailMap;
public bool IsTerrainMap;
/// ///
[SerializeField]
PackedMapDefinition m_packMode;
public PackedMapDefinition PackMode {
get {
if (m_packMode == null) {
var defintion = AlloyMaterialMapChannelPacker.GlobalDefinition;
if (IsDetailMap) {
m_packMode = defintion.DetailPack;
}else if (IsTerrainMap) {
m_packMode = defintion.TerrainPack;
} else {
m_packMode = defintion.PackedPack;
}
}
return m_packMode;
}
set { m_packMode = value; }
}
Texture2D m_normalTex;
public Texture2D NormalMapTexture {
get {
if (m_normalTex == null) {
m_normalTex =
AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(NormalGUID), typeof(Texture2D)) as Texture2D;
}
return m_normalTex;
}
set {
m_normalTex = value;
NormalGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(value));
}
}
public void SetTextures(Texture2D[] textures, Texture2D normalMap) {
m_textures = textures;
NormalMapTexture = normalMap;
TexturesGUID = new string[textures.Length];
for (int i = 0; i < textures.Length; ++i) {
TexturesGUID[i] = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(textures[i]));
}
NormalGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(normalMap));
}
public Texture2D GetTexture(int index) {
if (m_textures == null || m_textures.Length == 0) {
m_textures = new Texture2D[4];
}
if (m_textures[index] == null) {
m_textures[index] =
AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(TexturesGUID[index]), typeof (Texture2D)) as Texture2D;
}
return m_textures[index];
}
public const int DefaultOutputWidth = 32,
DefaultOutputHeight = 32,
DefaultOutputMipmapCount = 1;
public Vector2 GetOutputSize() {
int width = DefaultOutputWidth;
int height = DefaultOutputHeight;
// Pick output texture dimensions based on the largest input texture.
for (int i = 0; i < 4; ++i) {
var texture = GetTexture(i);
if (SelectedModes[i] == TextureValueChannelMode.Texture && texture != null) {
// So we can accomodate rectangles, if need be.
width = Math.Max(width, texture.width);
height = Math.Max(height, texture.height);
}
}
if (NormalMapTexture != null) {
width = Math.Max(width, NormalMapTexture.width);
height = Math.Max(height, NormalMapTexture.height);
}
return new Vector2(width, height);
}
public void GenerateMap() {
string path = AssetDatabase.GetAssetPath(this).Replace(".asset", ".png");
var tempTex = new Texture2D(4, 4, TextureFormat.ARGB32, true);
AssetDatabase.DeleteAsset(path);
File.WriteAllBytes(path, tempTex.EncodeToPNG());
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
}
public void SetTexture(Texture2D selTex, int texIndex) {
TexturesGUID[texIndex] = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(selTex));
m_textures[texIndex] = selTex;
}
public void ClearCache() {
m_textures[0] = null;
m_textures[1] = null;
m_textures[2] = null;
m_textures[3] = null;
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3b158258a30cea746ad413697b1d071b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,40 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using UnityEditor;
using UnityEngine;
namespace Alloy
{
[CustomEditor(typeof(AlloyCustomImportObject))]
public class AlloyCustomImportObjectEditor : Editor
{
private AlloyMaterialMapChannelPacker m_packer;
private Vector2 m_scrollPos;
void OnEnable() {
m_packer = CreateInstance<AlloyMaterialMapChannelPacker>();
m_packer.hideFlags = HideFlags.HideAndDontSave;
m_packer.Target = target as AlloyCustomImportObject;
}
void OnDisable() {
DestroyImmediate(m_packer);
}
public override void OnInspectorGUI() {
m_scrollPos = GUILayout.BeginScrollView(m_scrollPos);
bool isValid = m_packer.BaseGUI();
bool isButtonClicked = m_packer.GenerateButtonGUI("Regenerate", isValid);
GUILayout.EndScrollView();
if (isButtonClicked) {
m_packer.Target.GenerateMap();
}
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a625ab56dacfde649b3eb51e51a49a52
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,83 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace Alloy
{
public class AlloyImportFloat : ScriptableObject {}
[InitializeOnLoad]
public static class AlloyImporterSupervisor
{
private static List<string> s_failedImportAttempts = new List<string>();
public static bool IsFinalTry;
private static AlloyImportFloat m_float;
public static void OnFailedImport(string path) {
if (!s_failedImportAttempts.Contains(path)) {
s_failedImportAttempts.Add(path);
}
}
static AlloyImporterSupervisor() {
var all = Resources.FindObjectsOfTypeAll<AlloyImportFloat>();
if (all.Length == 0) {
m_float = ScriptableObject.CreateInstance<AlloyImportFloat>();
m_float.hideFlags = HideFlags.HideAndDontSave;
ScanForLateImport();
} else {
m_float = all[0];
}
EditorApplication.update += Update;
}
private static void ScanForLateImport() {
var assets = AssetDatabase.FindAssets("t:AlloyCustomImportObject");
foreach (var asset in assets) {
var path = AssetDatabase.GUIDToAssetPath(asset);
var png = path.Replace(".asset", ".png");
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(png);
if (tex == null) {
AssetDatabase.ImportAsset(path);
} else {
if (tex.width == 4 && tex.height == 4) {
AssetDatabase.ImportAsset(png);
}
}
}
}
// Update is called once per frame
private static void Update() {
if (s_failedImportAttempts.Count == 0) {
return;
}
var failed = s_failedImportAttempts.ToArray();
foreach (var path in failed) {
var settings = AssetDatabase.LoadAssetAtPath(path, typeof (AlloyCustomImportObject)) as AlloyCustomImportObject;
if (settings == null) {
continue;
}
IsFinalTry = true;
settings.GenerateMap();
IsFinalTry = false;
s_failedImportAttempts.Remove(path);
}
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ea64fb811f5753944b3b1fa1735e0f23
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,537 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Alloy;
using Object = UnityEngine.Object;
public class AlloyMaterialMapChannelPacker : EditorWindow {
protected const string SelectTextureOrValueErrorMessage = "Please select a texture or a value.";
protected const string EnterFilenameErrorMessage = "Please enter a filename.";
private const string c_assetPathRoot = "Assets";
private const string c_defaultFilename = "Output";
protected Vector2 ScrollPosition = new Vector2(0, 0);
[SerializeField]
protected string SaveName = string.Empty;
private static Texture2D s_rectTexture;
private static GUIStyle s_staticRectStyle;
private void OnEnable() {
SaveName = GetSelectedOrDefaultFilename();
Undo.undoRedoPerformed += UndoRedoPerformed;
}
private void OnSelectionChange() {
Repaint();
SaveName = GetSelectedOrDefaultFilename();
}
protected string GetSelectedAssetPath() {
var path = c_assetPathRoot;
foreach (Object obj in Selection.GetFiltered(typeof(Object), SelectionMode.Assets)) {
path = AssetDatabase.GetAssetPath(obj);
if (File.Exists(path)) {
path = Path.GetDirectoryName(path);
}
break;
}
return path;
}
protected string GetSelectedOrDefaultFilename() {
string fileName;
var path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (string.IsNullOrEmpty(path) || !Path.HasExtension(path)) {
fileName = c_defaultFilename;
} else {
fileName = Path.GetFileNameWithoutExtension(path);
}
return fileName;
}
protected void TitleLabel(string text) {
GUILayout.Label(text, EditorStyles.boldLabel, GUILayout.Width(150.0f));
}
protected void HelpLabel(string text) {
GUI.color = EditorGUIUtility.isProSkin ? Color.gray : Color.black;
var wrappedWhiteLabel = new GUIStyle(EditorStyles.whiteLabel);
wrappedWhiteLabel.wordWrap = true;
GUILayout.Label(text, wrappedWhiteLabel);
}
// Note that this function is only meant to be called from OnGUI() functions.
public static void GUIDrawRect(Rect position, Color color) {
if (s_rectTexture == null) {
// Use this format so that input colors are treated as though they
// are in gamma-space.
s_rectTexture = new Texture2D(1, 1, TextureFormat.RGB24, false, true);
}
if (s_staticRectStyle == null) {
s_staticRectStyle = new GUIStyle();
}
s_rectTexture.SetPixel(0, 0, color);
s_rectTexture.Apply();
s_staticRectStyle.normal.background = s_rectTexture;
GUI.Box(position, GUIContent.none, s_staticRectStyle);
}
protected bool FileEntryGUI(string suffix, string extension, ref string filename, out string curPath) {
curPath = GetSelectedAssetPath();
var displayPath = curPath + "/";
if (filename.Contains(suffix)) {
int fileExtPos = filename.LastIndexOf(suffix, StringComparison.Ordinal);
if (fileExtPos >= 0) {
filename = filename.Substring(0, fileExtPos);
}
}
displayPath = displayPath.Remove(0, 7);
var dirs = displayPath.Split('/');
var dirsCount = dirs.Length - 4;
for (int i = 0; i < dirsCount; i++) {
dirs[i] = "..";
}
displayPath = string.Join("/", dirs);
// Output filename section.
using (new EditorGUILayout.VerticalScope()) {
using (new EditorGUILayout.HorizontalScope()) {
Color defaultContentColor = GUI.contentColor;
GUI.contentColor = EditorGUIUtility.isProSkin ? Color.yellow : Color.black;
GUILayout.Label(displayPath, EditorStyles.whiteLabel);
GUI.contentColor = defaultContentColor;
GUILayout.Space(10.0f);
SaveName = GUILayout.TextField(filename, GUILayout.Width(180.0f));
GUILayout.Label(suffix + extension);
GUILayout.FlexibleSpace();
}
}
GUILayout.Space(5.0f);
// Warning message.
bool isValid = true;
using (new EditorGUILayout.HorizontalScope()) {
if (string.IsNullOrEmpty(filename)) {
EditorGUILayout.HelpBox(EnterFilenameErrorMessage, MessageType.Warning);
isValid = false;
}
if (filename.Contains("/") || filename.Contains("\\") || filename.Contains(".")) {
EditorGUILayout.HelpBox("Name is not valid!", MessageType.Warning);
isValid = false;
}
GUILayout.FlexibleSpace();
}
return isValid;
}
[SerializeField] public AlloyCustomImportObject Target;
static MaterialMapChannelPackerDefinition s_definition;
public static MaterialMapChannelPackerDefinition GlobalDefinition {
get {
if (s_definition == null) {
string path = "Assets/Alloy/Scripts/MaterialMapChannelPacker/Config/_PackerDefinition.asset";
s_definition =
AssetDatabase.LoadAssetAtPath(path, typeof (MaterialMapChannelPackerDefinition)) as
MaterialMapChannelPackerDefinition;
}
return s_definition;
}
}
private const int c_editorMinWidth = 236;
[MenuItem(AlloyUtils.MenuItem + "Material Map Channel Packer", false, 0)]
private static void LoadWindow() {
var all = Resources.FindObjectsOfTypeAll<AlloyMaterialMapChannelPacker>();
foreach (var channelPacker in all) {
DestroyImmediate(channelPacker);
}
GetWindow<AlloyMaterialMapChannelPacker>(false, "Material Map");
}
private void UndoRedoPerformed() {
Target.ClearCache();
Repaint();
}
private void OnDisable() {
if (Target != null && !EditorUtility.IsPersistent(Target)) {
DestroyImmediate(Target);
}
Undo.undoRedoPerformed -= UndoRedoPerformed;
}
void OnGUI() {
if (Target == null) {
Target = CreateInstance<AlloyCustomImportObject>();
UpdateDefaults();
}
var definition = GlobalDefinition;
if (definition == null) {
EditorGUILayout.HelpBox("Error: Cannot find packed map defintion file. Please ask for support on the forum", MessageType.Error);
return;
}
ScrollPosition = EditorGUILayout.BeginScrollView(ScrollPosition, false, false,
GUILayout.MinWidth(c_editorMinWidth),
GUILayout.MaxWidth(position.width));
GUILayout.Space(10.0f);
var def = Target.PackMode;
// Pack mode tabs.
using (new EditorGUILayout.HorizontalScope()) {
foreach (var tabMode in definition.PackedMaps) {
EditorGUI.BeginChangeCheck();
bool toggle = GUILayout.Toggle(def == tabMode, tabMode.Title, EditorStyles.toolbarButton);
if (EditorGUI.EndChangeCheck()) {
if (toggle && def != tabMode) {
Target.PackMode = tabMode; // Update packed map definition.
UpdateDefaults();
}
}
}
}
string curPath;
var suffix = Target.PackMode.Suffix;
bool isValid = true;
isValid = BaseGUI();
isValid = FileEntryGUI(suffix, ".png", ref SaveName, out curPath) && isValid;
if (GenerateButtonGUI("Generate", isValid)) {
var path = curPath + "/" + SaveName;
path += suffix;
Target = Instantiate(Target);
AlloyCustomImportAction.CreatePostProcessingInformation(path + ".asset", Target);
}
EditorGUILayout.EndScrollView();
}
private void UpdateDefaults() {
var channels = Target.PackMode.Channels;
foreach (var channel in channels) {
var outIndices = channel.OutputIndices.ToArray();
foreach (var outIndex in outIndices) {
Target.DoInvert[outIndex] = channel.InvertByDefault;
Target.SelectedModes[outIndex] = channel.DefaultMode;
}
}
}
bool DrawPackedMapDefinition(PackedMapDefinition def) {
var definition = GlobalDefinition;
if (definition == null) {
EditorGUILayout.HelpBox("Error: Cannot find packed map defintion file. Please ask for support on the forum", MessageType.Error);
return true;
}
bool anyNrm = false;
bool isValid = true;
foreach (var channel in def.Channels) {
if (!(channel.OutputVariance || channel.HideChannel)) {
isValid = DrawChannel(channel, false) && isValid;
}
if (channel.UseNormals) {
anyNrm = true;
}
}
if (anyNrm) {
isValid = DrawChannel(definition.NRMChannel, true) && isValid;
}
using (new EditorGUILayout.VerticalScope("HelpBox")) {
TitleLabel("Auto Regenerate");
using (new EditorGUILayout.HorizontalScope()) {
HelpLabel(definition.AutoRegenerateText);
GUI.color = Color.white;
GUILayout.FlexibleSpace();
Target.DoAutoRegenerate = EditorGUILayout.Toggle("", Target.DoAutoRegenerate, GUILayout.Width(120.0f));
}
// Does anyone really use this?
//if (def.Channels.Any(c => c.UseNormals) && def.VarianceBias) {
// TitleLabel("Variance Bias");
// using (new EditorGUILayout.HorizontalScope()) {
// HelpLabel(GlobalDefinition.VarianceText);
// GUI.color = Color.white;
// GUILayout.FlexibleSpace();
// Target.VarianceBias = EditorGUILayout.Slider(Target.VarianceBias, 0.0f, 1.0f, GUILayout.Width(120.0f));
// }
//}
}
return isValid;
}
private bool DrawChannel(BaseTextureChannelMapping def, bool normal) {
bool isValid = true;
GUI.backgroundColor = def.BackgroundColor;
using (new EditorGUILayout.VerticalScope("HelpBox")) {
GUI.backgroundColor = Color.white;
using (new EditorGUILayout.HorizontalScope()) {
var map = def as MapTextureChannelMapping;
using (new EditorGUILayout.VerticalScope()) {
using (new EditorGUILayout.HorizontalScope()) {
TitleLabel(def.Title);
if (map != null) {
string inChannel = map.InputString;
string outChannel = map.OutputString;
HelpLabel("(" + inChannel + " → " + outChannel + ")");
}
}
HelpLabel(def.HelpText);
GUI.color = Color.white;
if (normal) {
Texture2D normalMap = Target.NormalMapTexture;
if (normalMap != null) {
string path = AssetDatabase.GetAssetPath(normalMap);
if (!string.IsNullOrEmpty(path)) {
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
if (!importer.mipmapEnabled || importer.textureType != TextureImporterType.NormalMap) {
isValid = false;
EditorGUILayout.HelpBox("Texture type must be \"Normal map\" with mipmaps.", MessageType.Error);
}
}
}
} else if (map != null
&& (Target.SelectedModes[map.MainIndex] == TextureValueChannelMode.Texture)
&& Target.GetTexture(map.MainIndex) == null) {
isValid = false;
EditorGUILayout.HelpBox(SelectTextureOrValueErrorMessage, MessageType.Warning);
}
}
GUILayout.FlexibleSpace();
if (normal) {
Target.NormalMapTexture =
EditorGUILayout.ObjectField(Target.NormalMapTexture, typeof (Texture2D), false, GUILayout.Width(70.0f),
GUILayout.Height(70.0f))
as Texture2D;
} else if (map != null) {
int texIndex = map.MainIndex;
var mode = Target.SelectedModes[texIndex];
int index = (int) mode;
GUILayout.BeginVertical();
bool ch1 = GUILayout.Toggle(index == 0, "Black", EditorStyles.toolbarButton);
bool ch2 = GUILayout.Toggle(index == 1, "Gray", EditorStyles.toolbarButton);
bool ch3 = GUILayout.Toggle(index == 2, "White", EditorStyles.toolbarButton);
bool ch4 = GUILayout.Toggle(index == 3, "Custom", EditorStyles.toolbarButton);
bool ch5 = GUILayout.Toggle(index == 4, "Texture", EditorStyles.toolbarButton);
float channelValue = 0.0f;
if (ch1 && index != 0) {
index = 0;
} else if (ch2 && index != 1) {
index = 1;
} else if (ch3 && index != 2) {
index = 2;
} else if (ch4 && index != 3) {
index = 3;
} else if (ch5 && index != 4) {
index = 4;
}
GUILayout.EndVertical();
var selTex = Target.GetTexture((int) texIndex);
if (mode != TextureValueChannelMode.Texture) {
selTex = null;
}
GUILayout.Space(10.0f);
// Color or texture picker.
switch (mode) {
case TextureValueChannelMode.Texture:
using (new EditorGUILayout.VerticalScope()) {
selTex =
EditorGUILayout.ObjectField(selTex, typeof (Texture2D), false, GUILayout.Width(70.0f), GUILayout.Height(70.0f))
as Texture2D;
if (map.CanInvert) {
float label = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 60.0f;
Target.DoInvert[texIndex] = EditorGUILayout.Toggle("Invert", Target.DoInvert[texIndex], GUILayout.Width(70.0f));
EditorGUIUtility.labelWidth = label;
}
}
Target.SetTexture(selTex, texIndex);
foreach (var mapIndex in map.OutputIndices) {
Target.SetTexture(selTex, mapIndex);
Target.DoInvert[mapIndex] = Target.DoInvert[texIndex];
}
break;
case TextureValueChannelMode.Black:
channelValue = 0.0f;
DrawColorBox(Color.black);
break;
case TextureValueChannelMode.Gray:
channelValue = 0.5f;
DrawColorBox(Color.gray);
break;
case TextureValueChannelMode.White:
channelValue = 1.0f;
DrawColorBox(Color.white);
break;
case TextureValueChannelMode.Custom:
channelValue = Target.ChannelValues[(int) texIndex];
EditorGUILayout.BeginVertical();
channelValue = Mathf.Clamp01(channelValue);
channelValue = EditorGUILayout.FloatField(channelValue,
GUILayout.Width(50.0f));
DrawColorBox(new Color(channelValue, channelValue, channelValue));
EditorGUILayout.EndVertical();
break;
}
if (mode != TextureValueChannelMode.Texture) {
foreach (var mapIndex in map.OutputIndices) {
Target.DoInvert[mapIndex] = false;
}
}
Target.ChannelValues[texIndex] = channelValue;
Target.SelectedModes[texIndex] = (TextureValueChannelMode) index;
foreach (var mapIndex in map.OutputIndices) {
Target.ChannelValues[mapIndex] = channelValue;
Target.SelectedModes[mapIndex] = (TextureValueChannelMode) index;
}
}
}
GUILayout.Space(10.0f);
}
return isValid;
}
private static void DrawColorBox(Color col) {
var rect = GUILayoutUtility.GetRect(74.0f, 74.0f);
var borderColor = new Color {
r = (col.r + 0.2f) / 2.0f,
g = (col.g + 0.2f) / 2.0f,
b = (col.b + 0.2f) / 2.0f,
a = 1.0f
};
GUIDrawRect(rect, borderColor);
rect.x += 2.0f;
rect.width -= 4.0f;
rect.y += 2.0f;
rect.height -= 4.0f;
GUIDrawRect(rect, col);
}
public bool BaseGUI() {
EditorGUI.BeginChangeCheck();
Undo.RecordObject(Target, "Packed map");
bool isValid = DrawPackedMapDefinition(Target.PackMode);
if (EditorGUI.EndChangeCheck()) {
EditorUtility.SetDirty(Target);
}
return isValid;
}
public bool GenerateButtonGUI(string text, bool enabled)
{
bool isButtonClicked;
GUI.enabled = enabled;
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
isButtonClicked = GUILayout.Button(text, EditorStyles.toolbarButton, GUILayout.Width(120.0f),
GUILayout.Height(70.0f));
GUILayout.FlexibleSpace();
}
GUI.enabled = true;
GUILayout.Space(5.0f);
return isButtonClicked;
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bdefa218d1369324ca83faefe3c27067
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,294 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
using System.Linq;
using UnityEngine;
namespace Alloy {
public struct AlloyTextureColorCache {
public bool NativeSize;
public bool EmptyTexture;
public Color[] Values;
public float[] ValueChannelR;
public float[] ValueChannelG;
public float[] ValueChannelB;
public float[] ValueChannelA;
public float[] ActiveChannel;
private int m_texWidth;
private int m_texHeight;
public AlloyTextureColorCache(Texture2D texture, Texture2D target) {
if (texture == null) {
EmptyTexture = true;
m_texWidth = 0;
m_texHeight = 0;
Values = null;
ValueChannelR = null;
ValueChannelG = null;
ValueChannelB = null;
ValueChannelA = null;
NativeSize = false;
}
else {
Values = texture.GetPixels();
m_texWidth = texture.width;
m_texHeight = texture.height;
EmptyTexture = false;
NativeSize = texture.width == target.width && texture.height == target.height;
ValueChannelR = new float[Values.Length];
ValueChannelG = new float[Values.Length];
ValueChannelB = new float[Values.Length];
ValueChannelA = new float[Values.Length];
for (int i = 0; i < Values.Length; ++i) {
ValueChannelR[i] = Values[i].r;
ValueChannelG[i] = Values[i].g;
ValueChannelB[i] = Values[i].b;
ValueChannelA[i] = Values[i].a;
}
}
ActiveChannel = null;
}
public void SetActiveChannel(int channel) {
switch (channel) {
case 0:
ActiveChannel = ValueChannelR;
break;
case 1:
ActiveChannel = ValueChannelG;
break;
case 2:
ActiveChannel = ValueChannelB;
break;
case 3:
ActiveChannel = ValueChannelA;
break;
}
}
public float GetChannelBilinear(float u, float v, int mipLevel, float rangeX, float rangeY) {
if (mipLevel == 0) {
u = Mathf.Clamp01(u);
v = Mathf.Clamp01(v);
float uScaled = u * (m_texWidth - 1);
float vScaled = v * (m_texHeight - 1);
int left = Mathf.FloorToInt(uScaled);
int bottom = Mathf.FloorToInt(vScaled);
int right = Mathf.CeilToInt(uScaled);
int top = Mathf.CeilToInt(vScaled);
float lbVal = ActiveChannel[left + bottom * m_texWidth];
float rbVal = ActiveChannel[right + bottom * m_texWidth];
float luVal = ActiveChannel[left + top * m_texWidth];
float ruVal = ActiveChannel[right + top * m_texWidth];
float uFrac = uScaled - Mathf.Floor(uScaled);
float vFrac = vScaled - Mathf.Floor(vScaled);
float lrBottom = Mathf.LerpUnclamped(lbVal, rbVal, uFrac);
float lrUp = Mathf.LerpUnclamped(luVal, ruVal, uFrac);
return Mathf.Lerp(lrBottom, lrUp, vFrac);
}
float value = 0.0f;
// Averages the result over the area within the 'pixel' for this mip level
// this is similar, but not quite exactly the same as trilinear filtering.
for (int i = -mipLevel; i < mipLevel; ++i) {
for (int j = -mipLevel; j < mipLevel; ++j) {
float um = u + (i * rangeX);
float vm = v - (j * rangeY);
value += GetChannelBilinear(um, vm, 0, rangeX, rangeY);
}
}
int t = mipLevel * 2;
value /= t * t;
return value;
}
public Vector3 GetPixelNormal(float u, float v, int mipLevel, float rangeX, float rangeY) {
if (mipLevel == 0) {
u = Mathf.Clamp01(u);
v = Mathf.Clamp01(v);
float uScaled = u * (m_texWidth - 1);
float vScaled = v * (m_texHeight - 1);
int left = Mathf.FloorToInt(uScaled);
int bottom = Mathf.FloorToInt(vScaled);
int right = Mathf.CeilToInt(uScaled);
int top = Mathf.CeilToInt(vScaled);
Color lbVal = Values[left + bottom * m_texWidth];
Color rbVal = Values[right + bottom * m_texWidth];
Color luVal = Values[left + top * m_texWidth];
Color ruVal = Values[right + top * m_texWidth];
float uFrac = uScaled - Mathf.Floor(uScaled);
float vFrac = vScaled - Mathf.Floor(vScaled);
float rLerp = Mathf.LerpUnclamped(Mathf.LerpUnclamped(lbVal.r, rbVal.r, uFrac), Mathf.LerpUnclamped(luVal.r, ruVal.r, uFrac), vFrac);
float gLerp = Mathf.LerpUnclamped(Mathf.LerpUnclamped(lbVal.g, rbVal.g, uFrac), Mathf.LerpUnclamped(luVal.g, ruVal.g, uFrac), vFrac);
float bLerp = Mathf.LerpUnclamped(Mathf.LerpUnclamped(lbVal.b, rbVal.b, uFrac), Mathf.LerpUnclamped(luVal.b, ruVal.b, uFrac), vFrac);
return new Vector3(rLerp, gLerp, bLerp);
}
Vector3 value = Vector3.zero;
// Averages the result over the area within the 'pixel' for this mip level
// this is similar, but not quite exactly the same as trilinear filtering.
for (int i = -mipLevel; i < mipLevel; ++i) {
for (int j = -mipLevel; j < mipLevel; ++j) {
float um = u + (i * rangeX);
float vm = v - (j * rangeY);
value += GetPixelNormal(um, vm, 0, rangeX, rangeY);
}
}
int t = mipLevel * 2;
value /= t * t;
return value;
}
}
public static class AlloyPackerCompositor {
public static void CompositeMips(Texture2D target, AlloyCustomImportObject source,
AlloyTextureColorCache[] mapCache, AlloyTextureColorCache normalCache, int mipLevel) {
// Basically a 1:1 port of the original shader
// The only point of major difference is the filtering method used; which is a fraction simpler.
// This was disabled, since it appears GetPixels results don't appear to be affected by Unity's messing with Linear inputs; the same way they do at runtime. Re-enable if you like.
int w = Mathf.Max(2, target.width >> mipLevel);
int h = Mathf.Max(2, target.height >> mipLevel);
var colors = new Color[w * h];
float rangeX = (1.0f / (mipLevel + 1)) / target.width;
float rangeY = (1.0f / (mipLevel + 1)) / target.height;
UnityEngine.Profiling.Profiler.BeginSample("Composite mips");
for (int channelIndex = 0; channelIndex < source.PackMode.Channels.Count; channelIndex++) {
var channel = source.PackMode.Channels[channelIndex];
var inIndices = channel.InputIndices.ToArray();
var outIndices = channel.OutputIndices.ToArray();
bool hasInputs = inIndices.Length > 0;
for (int i = 0; i < outIndices.Length; ++i) {
int storeIndex = outIndices[i];
var tex = mapCache[storeIndex];
var channelVal = source.ChannelValues[storeIndex];
if (hasInputs) {
int readIndex = inIndices[Mathf.Min(i, inIndices.Length - 1)];
tex.SetActiveChannel(readIndex);
}
bool doInvert = source.DoInvert[storeIndex];
bool doNormal = channel.UseNormals && !normalCache.EmptyTexture;
bool doNative = hasInputs && tex.NativeSize && mipLevel == 0;
UnityEngine.Profiling.Profiler.BeginSample("Blit");
for (int x = 0; x < w; ++x) {
for (int y = 0; y < h; ++y) {
var pixelIndex = x + y * w;
var input = 0.0f;
if (!hasInputs || tex.EmptyTexture) {
input = channelVal;
}
else if (doNative) {
input = tex.ActiveChannel[pixelIndex];
}
else {
input = tex.GetChannelBilinear((float)x / (w - 1), (float)y / (h - 1), mipLevel, rangeX, rangeY);
}
if (doInvert) {
input = 1.0f - input;
}
if (doNormal) {
Vector3 normal;
if (normalCache.NativeSize && mipLevel == 0) {
normal = (Vector4)normalCache.Values[pixelIndex];
}
else {
normal = normalCache.GetPixelNormal((float)x / (w - 1), (float)y / (h - 1), mipLevel, rangeX,
rangeY);
}
normal.x = (normal.x * 2.0f) - 1.0f;
normal.y = (normal.y * 2.0f) - 1.0f;
normal.z = (normal.z * 2.0f) - 1.0f;
// Specular AA for Beckmann roughness.
// cf http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf pg92
var variance = 0.0f;
var avgNormalLength = normal.magnitude;
var applyAA = avgNormalLength < 1.0f;
if (applyAA) {
float avgNormLen2 = avgNormalLength * avgNormalLength;
float kappa = (3.0f * avgNormalLength - avgNormalLength * avgNormLen2) / (1.0f - avgNormLen2);
variance = Mathf.Clamp01(1.0f / (2.0f * kappa));// - source.VarianceBias);
}
if (channel.OutputVariance) {
input = variance;
}
else if (channel.RoughnessCorrect && applyAA) {
float a = input * input;
a = Mathf.Sqrt(Mathf.Clamp01(a * a + variance));
input = Mathf.Sqrt(a);
}
}
switch (storeIndex) {
case 0: colors[pixelIndex].r = input; break;
case 1: colors[pixelIndex].g = input; break;
case 2: colors[pixelIndex].b = input; break;
case 3: colors[pixelIndex].a = input; break;
}
}
}
UnityEngine.Profiling.Profiler.EndSample();
}
}
UnityEngine.Profiling.Profiler.BeginSample("Set pixels");
target.SetPixels(colors, mipLevel);
UnityEngine.Profiling.Profiler.EndSample();
UnityEngine.Profiling.Profiler.EndSample();
}
}
}

Some files were not shown because too many files have changed in this diff Show More