diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52074a364e..0a65ad322e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -778,6 +778,12 @@ jobs: name: Android Pico path: build_android_pico + - name: Download Build Artifacts (Linux) + uses: actions/download-artifact@v4 + with: + name: Linux + path: build_linux + - name: Download Build Artifacts (Mac) uses: actions/download-artifact@v4 with: @@ -795,11 +801,13 @@ jobs: mv build_windows_openxr/StandaloneWindows64/ releases/OpenBrush_Desktop_$VERSION/ mv build_windows_rift/StandaloneWindows64/ releases/OpenBrush_Rift_$VERSION/ mv build_macos/*.dmg releases/OpenBrush_Mac_$VERSION.dmg + mv build_linux/StandaloneLinux64/ releases/OpenBrush_Linux_$VERSION/ cd releases zip -r OpenBrush_Desktop_$VERSION.zip OpenBrush_Desktop_$VERSION/ - zip -r OpenBrush_Rift_$VERSION.zip OpenBrush_Rift_$VERSION/ rm -rf OpenBrush_Desktop_$VERSION + zip -r OpenBrush_Rift_$VERSION.zip OpenBrush_Rift_$VERSION/ rm -rf OpenBrush_Rift_$VERSION + zip -r OpenBrush_Linux_$VERSION.zip OpenBrush_Linux_$VERSION/ - name: Publish uses: softprops/action-gh-release@v2 @@ -917,6 +925,11 @@ jobs: with: name: MacOS (signed) path: build_macos + - name: Download Build Artifacts (Linux) + uses: actions/download-artifact@v4 + with: + name: Linux + path: build_linux - name: Upload Build run: | cd build_macos @@ -926,6 +939,7 @@ jobs: jinjanate Support/steam/app.vdf.j2 > app.vdf jinjanate Support/steam/main_depot.win.vdf.j2 > build_windows_openxr/main_depot.vdf jinjanate Support/steam/main_depot.mac.vdf.j2 > build_macos/main_depot.vdf + jinjanate Support/steam/main_depot.linux.vdf.j2 > build_linux/main_depot.vdf jinjanate Support/steam/installscript_win.vdf.j2 > build_windows_openxr/installscript_win.vdf steamcmd +login $STEAM_USERNAME +run_app_build $(pwd)/app.vdf +quit env: @@ -935,7 +949,8 @@ jobs: OPEN_BRUSH_APP_ID: ${{ vars.STEAM_APP_ID }} OPEN_BRUSH_WINDOWS_DEPOT_ID: ${{ vars.STEAM_WINDOWS_DEPOT_ID }} OPEN_BRUSH_MAC_DEPOT_ID: ${{ vars.STEAM_MAC_DEPOT_ID }} - OPEN_BRUSH_EXECUTABLE: ${{ needs.configuration.outputs.basename}}.exe + OPEN_BRUSH_LINUX_DEPOT_ID: ${{ vars.STEAM_LINUX_DEPOT_ID }} + OPEN_BRUSH_WINDOWS_EXECUTABLE: ${{ needs.configuration.outputs.basename}}.exe CHANNEL: beta - name: Update steam login secret run: | diff --git a/Assets/Editor/Tests/TestExport.cs b/Assets/Editor/Tests/TestExport.cs index 12037729b0..c5677820e9 100644 --- a/Assets/Editor/Tests/TestExport.cs +++ b/Assets/Editor/Tests/TestExport.cs @@ -16,138 +16,155 @@ using System; using System.Collections.Generic; using System.IO; - using Autodesk.Fbx; using NUnit.Framework; using UnityEngine; using UnityEditor; -namespace TiltBrush { - -internal class TestExport { - [Test] - public void TestFbxQuaternion() { - var uq = new Quaternion(1, 2, 3, 4); - var fq = uq.ToFbxQuaternion(); - - // Basic round-tripping - var uq2 = fq.ToUQuaternion(); - MathTestUtils.AssertAlmostEqual(uq, uq2); - - // Check that [3] is w, the real part (docs don't say anything about this) - var fqc = new FbxQuaternion(fq); - fqc.Conjugate(); - // [3] is the real part - MathTestUtils.AssertAlmostEqual((float)fq.GetAt(3), (float)fqc.GetAt(3)); - // and 0-2 are the imaginary part - MathTestUtils.AssertAlmostEqual((float)fq.GetAt(1), -(float)fqc.GetAt(1)); - } - - [Test] - public void TestPositionAndVectorSemanticsHaveAtLeast3Elements() { - foreach (var guid in AssetDatabase.FindAssets("t:BrushDescriptor")) { - var path = AssetDatabase.GUIDToAssetPath(guid); - var desc = AssetDatabase.LoadAssetAtPath(path); - GeometryPool.VertexLayout layout; - try { - layout = desc.VertexLayout; - } catch (Exception e) { - throw new Exception("Bad descriptor " + path, e); - } - for (int channel = 0; channel < GeometryPool.kNumTexcoords; ++channel) { - var info = layout.GetTexcoordInfo(channel); - if (( info.semantic == GeometryPool.Semantic.Position - || info.semantic == GeometryPool.Semantic.Vector) - && info.size < 3) { - throw new Exception( - string.Format("{0} channel {1} is {2} and size {3} != 3", - desc.m_DurableName, channel, info.semantic, info.size)); +namespace TiltBrush +{ + + internal class TestExport + { + [Test] + public void TestFbxQuaternion() + { + var uq = new Quaternion(1, 2, 3, 4); + var fq = uq.ToFbxQuaternion(); + + // Basic round-tripping + var uq2 = fq.ToUQuaternion(); + MathTestUtils.AssertAlmostEqual(uq, uq2); + + // Check that [3] is w, the real part (docs don't say anything about this) + var fqc = new FbxQuaternion(fq); + fqc.Conjugate(); + // [3] is the real part + MathTestUtils.AssertAlmostEqual((float)fq.GetAt(3), (float)fqc.GetAt(3)); + // and 0-2 are the imaginary part + MathTestUtils.AssertAlmostEqual((float)fq.GetAt(1), -(float)fqc.GetAt(1)); } - } - } - } - - [Test] - public void TestAxisConvention() { - AxisConvention[] acs = { - AxisConvention.kUnity, - AxisConvention.kGltf2, - AxisConvention.kUsd, - AxisConvention.kStl, - AxisConvention.kUnreal - }; - - foreach (var ac1 in acs) - foreach (var ac2 in acs) { - Matrix4x4 ac1FromAc2 = AxisConvention.GetToDstFromSrc(ac1, ac2); - Assert.AreEqual(ac1.forward, ac1FromAc2.MultiplyVector(ac2.forward)); - Assert.AreEqual(ac1.right, ac1FromAc2.MultiplyVector(ac2.right )); - Assert.AreEqual(ac1.up, ac1FromAc2.MultiplyVector(ac2.up )); - } - foreach (var ac in acs) { - Matrix4x4 fromUnity = AxisConvention.GetFromUnity(ac); - Assert.AreEqual(ac.forward, fromUnity.MultiplyVector(Vector3.forward)); - Assert.AreEqual(ac.right, fromUnity.MultiplyVector(Vector3.right )); - Assert.AreEqual(ac.up, fromUnity.MultiplyVector(Vector3.up )); + [Test] + public void TestPositionAndVectorSemanticsHaveAtLeast3Elements() + { + foreach (var guid in AssetDatabase.FindAssets("t:BrushDescriptor")) + { + var path = AssetDatabase.GUIDToAssetPath(guid); + var desc = AssetDatabase.LoadAssetAtPath(path); + GeometryPool.VertexLayout layout; + try + { + layout = desc.VertexLayout; + } + catch (Exception e) + { + throw new Exception("Bad descriptor " + path, e); + } + for (int channel = 0; channel < GeometryPool.kNumTexcoords; ++channel) + { + var info = layout.GetTexcoordInfo(channel); + if ((info.semantic == GeometryPool.Semantic.Position + || info.semantic == GeometryPool.Semantic.Vector) + && info.size < 3) + { + throw new Exception( + string.Format("{0} channel {1} is {2} and size {3} != 3", + desc.m_DurableName, channel, info.semantic, info.size)); + } + } + } + } - Matrix4x4 toUnity = AxisConvention.GetToUnity(ac); - Assert.AreEqual(Vector3.forward, toUnity.MultiplyVector(ac.forward)); - Assert.AreEqual(Vector3.right, toUnity.MultiplyVector(ac.right )); - Assert.AreEqual(Vector3.up, toUnity.MultiplyVector(ac.up )); - } - } - - [Test] - public void TestGltfDispose() { - string tempDir = Path.Combine(Application.dataPath, "..", "Temp", "TiltBrushUnitTests"); - using (var globals = new GlTF_Globals(tempDir, gltfVersion: 1)) { - globals.binary = true; - globals.OpenFiles(Path.Combine(tempDir, "foo.glb1")); - globals.CloseFiles(); + [Test] + public void TestAxisConvention() + { + AxisConvention[] acs = + { + AxisConvention.kUnity, + AxisConvention.kGltf2, + AxisConvention.kUsd, + AxisConvention.kStl, + AxisConvention.kUnreal + }; + + foreach (var ac1 in acs) + foreach (var ac2 in acs) + { + Matrix4x4 ac1FromAc2 = AxisConvention.GetToDstFromSrc(ac1, ac2); + Assert.AreEqual(ac1.forward, ac1FromAc2.MultiplyVector(ac2.forward)); + Assert.AreEqual(ac1.right, ac1FromAc2.MultiplyVector(ac2.right)); + Assert.AreEqual(ac1.up, ac1FromAc2.MultiplyVector(ac2.up)); + } + + foreach (var ac in acs) + { + Matrix4x4 fromUnity = AxisConvention.GetFromUnity(ac); + Assert.AreEqual(ac.forward, fromUnity.MultiplyVector(Vector3.forward)); + Assert.AreEqual(ac.right, fromUnity.MultiplyVector(Vector3.right)); + Assert.AreEqual(ac.up, fromUnity.MultiplyVector(Vector3.up)); + + Matrix4x4 toUnity = AxisConvention.GetToUnity(ac); + Assert.AreEqual(Vector3.forward, toUnity.MultiplyVector(ac.forward)); + Assert.AreEqual(Vector3.right, toUnity.MultiplyVector(ac.right)); + Assert.AreEqual(Vector3.up, toUnity.MultiplyVector(ac.up)); + } + } + + [Test] + public void TestGltfDispose() + { + string tempDir = Path.Combine(Application.dataPath, "..", "Temp", "TiltBrushUnitTests"); + using (var globals = new GlTF_Globals(tempDir, gltfVersion: 1)) + { + globals.binary = true; + globals.OpenFiles(Path.Combine(tempDir, "foo.glb1")); + globals.CloseFiles(); + } + } + + [Test] + public void TestGetOrCreateSafeLocal() + { + var dp = Application.dataPath; + var ctx = new ExportFileReference.DisambiguationContext(); + var paper = ExportFileReference.GetOrCreateSafeLocal( + ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper"); + var paper2 = ExportFileReference.GetOrCreateSafeLocal( + ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper"); + Assert.AreEqual(paper, paper2); // reference equality + Assert.AreEqual("main.png", paper.m_uri); + Assert.AreEqual("main.png", paper2.m_uri); + + var ductTape = ExportFileReference.GetOrCreateSafeLocal( + ctx, "main.png", dp + @"\Resources\Brushes\Basic\DuctTape"); + Assert.AreNotEqual(paper, ductTape); + Assert.AreEqual("main_1.png", ductTape.m_uri); + + var peverse = ExportFileReference.GetOrCreateSafeLocal( + ctx, "main_1.png", dp + @"\Editor\Tests\TestData"); + Assert.AreEqual("main_1_1.png", peverse.m_uri); + + var withNamespace = ExportFileReference.GetOrCreateSafeLocal( + ctx, "main.png", dp + @"\Resources\Brushes\Basic\Hypercolor", + @"subdirectory\brush_main.png"); + Assert.AreEqual("brush_main.png", withNamespace.m_uri); + } + + [Test] + public void TestCreateUniqueName() + { + HashSet names = new HashSet(); + string Create(string name) => ExportUtils.CreateUniqueName(name, names); + Assert.AreEqual("main.png", Create("main.png")); + Assert.AreEqual("main_1.png", Create("main.png")); + Assert.AreEqual("main_1_1.png", Create("main_1.png")); // perverse + Assert.AreEqual("main_2.png", Create("main.png")); + + Assert.AreEqual("initialShadingGroup", Create("initialShadingGroup")); + Assert.AreEqual("initialShadingGroup_1", Create("initialShadingGroup")); + } } - } - - [Test] - public void TestGetOrCreateSafeLocal() { - var dp = Application.dataPath; - var ctx = new ExportFileReference.DisambiguationContext(); - var paper = ExportFileReference.GetOrCreateSafeLocal( - ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper"); - var paper2 = ExportFileReference.GetOrCreateSafeLocal( - ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper"); - Assert.AreEqual(paper, paper2); // reference equality - Assert.AreEqual("main.png", paper.m_uri); - Assert.AreEqual("main.png", paper2.m_uri); - - var ductTape = ExportFileReference.GetOrCreateSafeLocal( - ctx, "main.png", dp + @"\Resources\Brushes\Basic\DuctTape"); - Assert.AreNotEqual(paper, ductTape); - Assert.AreEqual("main_1.png", ductTape.m_uri); - - var peverse = ExportFileReference.GetOrCreateSafeLocal( - ctx, "main_1.png", dp + @"\Editor\Tests\TestData"); - Assert.AreEqual("main_1_1.png", peverse.m_uri); - - var withNamespace = ExportFileReference.GetOrCreateSafeLocal( - ctx, "main.png", dp + @"\Resources\Brushes\Basic\Hypercolor", - @"subdirectory\brush_main.png"); - Assert.AreEqual("brush_main.png", withNamespace.m_uri); - } - - [Test] - public void TestCreateUniqueName() { - HashSet names = new HashSet(); - string Create(string name) => ExportUtils.CreateUniqueName(name, names); - Assert.AreEqual("main.png", Create("main.png")); - Assert.AreEqual("main_1.png", Create("main.png")); - Assert.AreEqual("main_1_1.png", Create("main_1.png")); // perverse - Assert.AreEqual("main_2.png", Create("main.png")); - - Assert.AreEqual("initialShadingGroup", Create("initialShadingGroup")); - Assert.AreEqual("initialShadingGroup_1", Create("initialShadingGroup")); - } -} } #endif diff --git a/Assets/Editor/ToolkitUtils.cs b/Assets/Editor/ToolkitUtils.cs index c62a0f8fa1..e41d0dc996 100644 --- a/Assets/Editor/ToolkitUtils.cs +++ b/Assets/Editor/ToolkitUtils.cs @@ -186,22 +186,24 @@ private static bool ExportBrushStrokesFbx_Enabled() } #if FBX_SUPPORTED - [MenuItem("Open Brush/Toolkit/Export FBX")] - private static void ExportBrushStrokesFbx() { - var current = SaveLoadScript.m_Instance.SceneFile; - string basename = (current.Valid) - ? Path.GetFileNameWithoutExtension(current.FullPath).Replace(" ", "_") - : "Untitled"; - - string directoryName = FileUtils.GenerateNonexistentFilename( - App.UserExportPath(), basename, ""); - if (!FileUtils.InitializeDirectoryWithUserError(directoryName, - "Failed to export")) { - return; - } - string fbxName = Path.Combine(directoryName, basename + ".fbx"); - ExportFbx.Export(fbxName, ExportFbx.kFbxAscii); - } + [MenuItem("Open Brush/Toolkit/Export FBX")] + private static void ExportBrushStrokesFbx() + { + var current = SaveLoadScript.m_Instance.SceneFile; + string basename = (current.Valid) + ? Path.GetFileNameWithoutExtension(current.FullPath).Replace(" ", "_") + : "Untitled"; + + string directoryName = FileUtils.GenerateNonexistentFilename( + App.UserExportPath(), basename, ""); + if (!FileUtils.InitializeDirectoryWithUserError(directoryName, + "Failed to export")) + { + return; + } + string fbxName = Path.Combine(directoryName, basename + ".fbx"); + ExportFbx.Export(fbxName, ExportFbx.kFbxAscii); + } #endif // Collects all brushes and their assets, and exports them into a folder that can be copied into into Tilt Brush Toolkit's Unity SDK diff --git a/Assets/Prefabs/Panels/LabsPanel.prefab b/Assets/Prefabs/Panels/LabsPanel.prefab index ef9d7be181..95ae0b3ae7 100644 --- a/Assets/Prefabs/Panels/LabsPanel.prefab +++ b/Assets/Prefabs/Panels/LabsPanel.prefab @@ -298,6 +298,7 @@ Transform: - {fileID: 4000011596321798} - {fileID: 6292014397156290862} - {fileID: 4000011251504288} + - {fileID: 1210818133549774434} - {fileID: 4000012282201364} - {fileID: 4000012490214276} - {fileID: 6291905350315219778} @@ -305,7 +306,6 @@ Transform: - {fileID: 4626429713668410} - {fileID: 4000012572946912} - {fileID: 4959811239207079844} - - {fileID: 1210818133549774434} - {fileID: 434412} - {fileID: 4000011486688576} - {fileID: 499404} @@ -1029,12 +1029,12 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1000010690061500} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: -0.415, y: -0.3, z: 0.05} + m_LocalPosition: {x: -0.207, y: -0.3, z: 0.05} m_LocalScale: {x: 0.35, y: 0.35, z: 0.35} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 10 + m_RootOrder: 11 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &33000013755556650 MeshFilter: @@ -1548,7 +1548,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!4 &4000012282201364 Transform: m_ObjectHideFlags: 0 @@ -1562,7 +1562,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 5 + m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &33000013414599442 MeshFilter: @@ -1835,7 +1835,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 6 + m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &33000012285989520 MeshFilter: @@ -2243,7 +2243,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 9 + m_RootOrder: 10 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &33062622632853984 MeshFilter: @@ -2387,12 +2387,12 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1016131236980122382} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: -0.3, z: 0.05} + m_LocalPosition: {x: 0.20799999, y: -0.3, z: 0.05} m_LocalScale: {x: 0.35, y: 0.35, z: 0.35} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 11 + m_RootOrder: 12 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &7459773723550717888 MeshFilter: @@ -2541,7 +2541,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 8 + m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &2078078264413487613 MeshFilter: @@ -2685,12 +2685,12 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4011871447704911063} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0.415, y: -0.3, z: 0.049999237} + m_LocalPosition: {x: 0.415, y: 0.15, z: 0.049999237} m_LocalScale: {x: 0.35, y: 0.35, z: 0.35} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 12 + m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &4510907067803236372 MeshFilter: @@ -3015,7 +3015,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 402684} - m_RootOrder: 7 + m_RootOrder: 8 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &6280936243828533384 MeshFilter: diff --git a/Assets/Prefabs/Panels/LabsPanel_Mobile.prefab b/Assets/Prefabs/Panels/LabsPanel_Mobile.prefab index 355e2b9fc4..ea2fc049ca 100644 --- a/Assets/Prefabs/Panels/LabsPanel_Mobile.prefab +++ b/Assets/Prefabs/Panels/LabsPanel_Mobile.prefab @@ -230,6 +230,9 @@ MonoBehaviour: m_PanelPopUpMap: - m_PopUpPrefab: {fileID: 167516, guid: e875cff6ab3f37347921daaab5f43b25, type: 3} m_Command: 9 + - m_PopUpPrefab: {fileID: 1758786797962018, guid: 04751ea8307825e4bb7657eb20f9bfc5, + type: 3} + m_Command: 15 m_PanelDescription: LABS_PANEL_DESCRIPTION m_LocalizedPanelDescription: m_TableReference: diff --git a/Assets/Resources/Brushes/Basic/Bubbles/Bubbles.shader b/Assets/Resources/Brushes/Basic/Bubbles/Bubbles.shader index 4d87c870e8..31c2bbc382 100644 --- a/Assets/Resources/Brushes/Basic/Bubbles/Bubbles.shader +++ b/Assets/Resources/Brushes/Basic/Bubbles/Bubbles.shader @@ -67,6 +67,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -99,6 +101,11 @@ Category { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.color = TbVertToSrgb(v.color); float birthTime = v.texcoord.w; float rotation = v.texcoord.z; diff --git a/Assets/Resources/Brushes/Basic/CelVinyl/CelVinyl.shader b/Assets/Resources/Brushes/Basic/CelVinyl/CelVinyl.shader index 054b3d7f1e..a98f8e5044 100644 --- a/Assets/Resources/Brushes/Basic/CelVinyl/CelVinyl.shader +++ b/Assets/Resources/Brushes/Basic/CelVinyl/CelVinyl.shader @@ -55,6 +55,8 @@ Shader "Brush/Special/CelVinyl" { float2 texcoord : TEXCOORD0; float4 color : COLOR; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -63,6 +65,8 @@ Shader "Brush/Special/CelVinyl" { float4 color : COLOR; uint id : TEXCOORD2; UNITY_FOG_COORDS(1) + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -71,6 +75,10 @@ Shader "Brush/Special/CelVinyl" { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; o.color = TbVertToNative(v.color); diff --git a/Assets/Resources/Brushes/Basic/ChromaticWave/ChromaticWave.shader b/Assets/Resources/Brushes/Basic/ChromaticWave/ChromaticWave.shader index 9e7b4de73b..885b53f48b 100644 --- a/Assets/Resources/Brushes/Basic/ChromaticWave/ChromaticWave.shader +++ b/Assets/Resources/Brushes/Basic/ChromaticWave/ChromaticWave.shader @@ -65,6 +65,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -73,6 +75,8 @@ Category { float2 texcoord : TEXCOORD0; float4 unbloomedColor : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -80,6 +84,11 @@ Category { PrepForOds(v.vertex); v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; o.color = bloomColor(v.color, _EmissionGain); diff --git a/Assets/Resources/Brushes/Basic/Comet/Comet.shader b/Assets/Resources/Brushes/Basic/Comet/Comet.shader index e20d64cdc8..e70e3bd4bc 100644 --- a/Assets/Resources/Brushes/Basic/Comet/Comet.shader +++ b/Assets/Resources/Brushes/Basic/Comet/Comet.shader @@ -69,6 +69,8 @@ Category { float3 normal : NORMAL; float3 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -76,6 +78,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; @@ -84,6 +88,10 @@ Category { PrepForOds(v.vertex); v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = TbVertToNative(v.color); diff --git a/Assets/Resources/Brushes/Basic/DanceFloor/DanceFloor.shader b/Assets/Resources/Brushes/Basic/DanceFloor/DanceFloor.shader index 53604fbd29..7f818d541d 100644 --- a/Assets/Resources/Brushes/Basic/DanceFloor/DanceFloor.shader +++ b/Assets/Resources/Brushes/Basic/DanceFloor/DanceFloor.shader @@ -66,6 +66,8 @@ Category { float4 texcoord1 : TEXCOORD1; float3 normal : NORMAL; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -74,6 +76,8 @@ Category { float2 texcoord : TEXCOORD0; float3 worldPos : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -82,6 +86,11 @@ Category { { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float4 worldPos = mul(unity_ObjectToWorld, v.vertex); float waveform = 0; diff --git a/Assets/Resources/Brushes/Basic/Dots/Dots.shader b/Assets/Resources/Brushes/Basic/Dots/Dots.shader index b12d61930c..b4a73ab6ea 100644 --- a/Assets/Resources/Brushes/Basic/Dots/Dots.shader +++ b/Assets/Resources/Brushes/Basic/Dots/Dots.shader @@ -66,6 +66,8 @@ Category { float2 texcoord : TEXCOORD0; float waveform : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -78,6 +80,11 @@ Category { { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float birthTime = v.texcoord.w; float rotation = v.texcoord.z; float halfSize = GetParticleHalfSize(v.corner.xyz, v.center, birthTime); diff --git a/Assets/Resources/Brushes/Basic/DoubleTaperedMarker/DoubleTaperedMarker.shader b/Assets/Resources/Brushes/Basic/DoubleTaperedMarker/DoubleTaperedMarker.shader index 381d714313..619ce865d4 100644 --- a/Assets/Resources/Brushes/Basic/DoubleTaperedMarker/DoubleTaperedMarker.shader +++ b/Assets/Resources/Brushes/Basic/DoubleTaperedMarker/DoubleTaperedMarker.shader @@ -53,6 +53,8 @@ Category { float2 texcoord0 : TEXCOORD0; float3 texcoord1 : TEXCOORD1; //per vert offset vector uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -61,6 +63,8 @@ Category { float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; UNITY_FOG_COORDS(1) + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -72,6 +76,11 @@ Category { // v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float envelope = sin(v.texcoord0.x * 3.14159); float widthMultiplier = 1 - envelope; v.vertex.xyz += -v.texcoord1 * widthMultiplier; diff --git a/Assets/Resources/Brushes/Basic/Electricity/Electricity.shader b/Assets/Resources/Brushes/Basic/Electricity/Electricity.shader index 6561fb53df..9b8cbf350d 100644 --- a/Assets/Resources/Brushes/Basic/Electricity/Electricity.shader +++ b/Assets/Resources/Brushes/Basic/Electricity/Electricity.shader @@ -51,6 +51,8 @@ CGINCLUDE float2 texcoord0 : TEXCOORD0; float3 texcoord1 : TEXCOORD1; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; sampler2D _MainTex; @@ -66,6 +68,8 @@ CGINCLUDE fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float3 displacement(float3 pos, float mod) { @@ -93,6 +97,11 @@ CGINCLUDE PrepForOds(v.vertex); v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float envelope = sin(v.texcoord0.x * (3.14159)); float envelopePow = (1-pow(1 - envelope, 10)); diff --git a/Assets/Resources/Brushes/Basic/Embers/Embers.shader b/Assets/Resources/Brushes/Basic/Embers/Embers.shader index 92a3ba98cf..a60fb85bb8 100644 --- a/Assets/Resources/Brushes/Basic/Embers/Embers.shader +++ b/Assets/Resources/Brushes/Basic/Embers/Embers.shader @@ -72,6 +72,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -118,6 +120,11 @@ Category { v2f vert (ParticleVertexWithSpread_t v) { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Used as a random-ish seed for various calculations float seed = v.color.a; float t01 = fmod(GetTime().y*_ScrollRate + seed * 10, 1); diff --git a/Assets/Resources/Brushes/Basic/Fire/Fire.shader b/Assets/Resources/Brushes/Basic/Fire/Fire.shader index de556841f9..92614d4a57 100644 --- a/Assets/Resources/Brushes/Basic/Fire/Fire.shader +++ b/Assets/Resources/Brushes/Basic/Fire/Fire.shader @@ -69,6 +69,8 @@ Category { #endif float3 worldPos : TEXCOORD1; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -81,6 +83,8 @@ Category { #endif float3 worldPos : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -98,6 +102,11 @@ Category { PrepForOds(v.vertex); v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(v.color, _EmissionGain); o.pos = UnityObjectToClipPos(v.vertex); diff --git a/Assets/Resources/Brushes/Basic/Highlighter/AdditiveCutout.shader b/Assets/Resources/Brushes/Basic/Highlighter/AdditiveCutout.shader index 66772356b8..e3b5bdbb9a 100644 --- a/Assets/Resources/Brushes/Basic/Highlighter/AdditiveCutout.shader +++ b/Assets/Resources/Brushes/Basic/Highlighter/AdditiveCutout.shader @@ -49,6 +49,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -56,6 +58,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -69,6 +73,11 @@ Category { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = TbVertToNative(v.color); diff --git a/Assets/Resources/Brushes/Basic/HyperGrid/HyperGrid.shader b/Assets/Resources/Brushes/Basic/HyperGrid/HyperGrid.shader index e047db147f..53a481f40b 100644 --- a/Assets/Resources/Brushes/Basic/HyperGrid/HyperGrid.shader +++ b/Assets/Resources/Brushes/Basic/HyperGrid/HyperGrid.shader @@ -67,6 +67,8 @@ Category { float2 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -74,6 +76,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -82,6 +86,11 @@ Category { { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Subtract out the Canvas space pose to keep the verts from popping around while // transforming (e.g. apply quantization in an immutable space). float4 worldPos = mul(unity_ObjectToWorld, v.vertex); diff --git a/Assets/Resources/Brushes/Basic/Plasma/Plasma.shader b/Assets/Resources/Brushes/Basic/Plasma/Plasma.shader index c187a31764..3e626479c4 100644 --- a/Assets/Resources/Brushes/Basic/Plasma/Plasma.shader +++ b/Assets/Resources/Brushes/Basic/Plasma/Plasma.shader @@ -74,6 +74,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -82,6 +84,8 @@ Category { float2 texcoord : TEXCOORD0; float3 worldPos : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -97,6 +101,11 @@ Category { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.vertex = UnityObjectToClipPos(v.vertex); o.color = v.color; diff --git a/Assets/Resources/Brushes/Basic/Rainbow/Rainbow.shader b/Assets/Resources/Brushes/Basic/Rainbow/Rainbow.shader index e64c0a3fb9..43b16c8e2f 100644 --- a/Assets/Resources/Brushes/Basic/Rainbow/Rainbow.shader +++ b/Assets/Resources/Brushes/Basic/Rainbow/Rainbow.shader @@ -60,6 +60,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -67,6 +69,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -78,6 +82,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color; @@ -96,7 +105,7 @@ Category { // Create parametric colors half4 tex = float4(0,0,0,1); half row_y = fmod(uvs.y,1); - + float time = frac( GetTime().z * 0.2 ) * 5; float rowOffset = floor( time ); diff --git a/Assets/Resources/Brushes/Basic/Smoke/Smoke.shader b/Assets/Resources/Brushes/Basic/Smoke/Smoke.shader index 3159d0e3ef..9028898b6b 100644 --- a/Assets/Resources/Brushes/Basic/Smoke/Smoke.shader +++ b/Assets/Resources/Brushes/Basic/Smoke/Smoke.shader @@ -61,6 +61,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -97,6 +99,11 @@ Category { { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float birthTime = v.texcoord.w; float rotation = v.texcoord.z; float halfSize = GetParticleHalfSize(v.corner.xyz, v.center, birthTime); diff --git a/Assets/Resources/Brushes/Basic/Snow/Snow.shader b/Assets/Resources/Brushes/Basic/Snow/Snow.shader index 08810ae3a5..23d506960e 100644 --- a/Assets/Resources/Brushes/Basic/Snow/Snow.shader +++ b/Assets/Resources/Brushes/Basic/Snow/Snow.shader @@ -69,6 +69,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -81,6 +83,11 @@ Category { v2f vert (ParticleVertexWithSpread_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.color = TbVertToSrgb(v.color); float birthTime = v.texcoord.w; float rotation = v.texcoord.z; diff --git a/Assets/Resources/Brushes/Basic/SoftHighlighter/SoftHighlighter.shader b/Assets/Resources/Brushes/Basic/SoftHighlighter/SoftHighlighter.shader index 564c1b6763..ab51e1163e 100644 --- a/Assets/Resources/Brushes/Basic/SoftHighlighter/SoftHighlighter.shader +++ b/Assets/Resources/Brushes/Basic/SoftHighlighter/SoftHighlighter.shader @@ -53,6 +53,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -60,6 +62,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float2 id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -70,6 +74,11 @@ Category { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); #ifdef AUDIO_REACTIVE v.color = TbVertToSrgb(v.color); diff --git a/Assets/Resources/Brushes/Basic/Stars/Stars.shader b/Assets/Resources/Brushes/Basic/Stars/Stars.shader index 9562ff7f45..6cd67e2369 100644 --- a/Assets/Resources/Brushes/Basic/Stars/Stars.shader +++ b/Assets/Resources/Brushes/Basic/Stars/Stars.shader @@ -70,6 +70,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (ParticleVertexWithSpread_t v) @@ -77,6 +79,11 @@ Category { v.color = TbVertToSrgb(v.color); const float PI = 3.14159265359; v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float birthTime = v.texcoord.w; float rotation = v.texcoord.z; float halfSize = GetParticleHalfSize(v.corner.xyz, v.center, birthTime); diff --git a/Assets/Resources/Brushes/Basic/Streamers/Streamers.shader b/Assets/Resources/Brushes/Basic/Streamers/Streamers.shader index bd1fed94e0..e680be938f 100644 --- a/Assets/Resources/Brushes/Basic/Streamers/Streamers.shader +++ b/Assets/Resources/Brushes/Basic/Streamers/Streamers.shader @@ -69,6 +69,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -77,6 +79,8 @@ Category { float2 texcoord : TEXCOORD0; float4 worldPos : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -91,6 +95,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); diff --git a/Assets/Resources/Brushes/Basic/Toon/Toon.shader b/Assets/Resources/Brushes/Basic/Toon/Toon.shader index 9047c33e34..9c27258d1d 100644 --- a/Assets/Resources/Brushes/Basic/Toon/Toon.shader +++ b/Assets/Resources/Brushes/Basic/Toon/Toon.shader @@ -46,6 +46,8 @@ CGINCLUDE float3 normal : NORMAL; float3 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -54,6 +56,8 @@ CGINCLUDE float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; UNITY_FOG_COORDS(1) + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vertInflate (appdata_t v, float inflate) @@ -61,6 +65,11 @@ CGINCLUDE PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float outlineEnabled = inflate; float radius = v.texcoord.z; inflate *= radius * .4; diff --git a/Assets/Resources/Brushes/Basic/TubeToonInverted/TubeToonInverted.shader b/Assets/Resources/Brushes/Basic/TubeToonInverted/TubeToonInverted.shader index 39961dab3c..ca74b914f7 100644 --- a/Assets/Resources/Brushes/Basic/TubeToonInverted/TubeToonInverted.shader +++ b/Assets/Resources/Brushes/Basic/TubeToonInverted/TubeToonInverted.shader @@ -41,6 +41,8 @@ CGINCLUDE float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -48,6 +50,8 @@ CGINCLUDE fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vertInflate (appdata_t v, float inflate) @@ -55,6 +59,11 @@ CGINCLUDE PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.xyz += v.normal.xyz * inflate; o.vertex = UnityObjectToClipPos(v.vertex); o.color = v.color; diff --git a/Assets/Resources/Brushes/Basic/VelvetInk/VelvetInk.shader b/Assets/Resources/Brushes/Basic/VelvetInk/VelvetInk.shader index 81882f26d7..05bc94c0d7 100644 --- a/Assets/Resources/Brushes/Basic/VelvetInk/VelvetInk.shader +++ b/Assets/Resources/Brushes/Basic/VelvetInk/VelvetInk.shader @@ -53,6 +53,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -60,6 +62,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -69,6 +73,11 @@ Category { PrepForOds(v.vertex); v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); #ifdef AUDIO_REACTIVE v.color = TbVertToSrgb(v.color); diff --git a/Assets/Resources/Brushes/Basic/Waveform/Waveform.shader b/Assets/Resources/Brushes/Basic/Waveform/Waveform.shader index ea9d76bc1e..39e57c8120 100644 --- a/Assets/Resources/Brushes/Basic/Waveform/Waveform.shader +++ b/Assets/Resources/Brushes/Basic/Waveform/Waveform.shader @@ -67,6 +67,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -75,6 +77,8 @@ Category { float2 texcoord : TEXCOORD0; float4 unbloomedColor : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -83,6 +87,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(v.color, _EmissionGain); diff --git a/Assets/Resources/Brushes/Basic/WaveformFFT/WaveformFFT.shader b/Assets/Resources/Brushes/Basic/WaveformFFT/WaveformFFT.shader index 167ab122a5..bb20e05d69 100644 --- a/Assets/Resources/Brushes/Basic/WaveformFFT/WaveformFFT.shader +++ b/Assets/Resources/Brushes/Basic/WaveformFFT/WaveformFFT.shader @@ -65,6 +65,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -73,6 +75,8 @@ Category { float2 texcoord : TEXCOORD0; float4 unbloomedColor : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -80,6 +84,11 @@ Category { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(v.color, _EmissionGain); diff --git a/Assets/Resources/Brushes/Basic/WaveformParticles/WaveformParticles.shader b/Assets/Resources/Brushes/Basic/WaveformParticles/WaveformParticles.shader index 8705457f60..7c9dbe044a 100644 --- a/Assets/Resources/Brushes/Basic/WaveformParticles/WaveformParticles.shader +++ b/Assets/Resources/Brushes/Basic/WaveformParticles/WaveformParticles.shader @@ -67,6 +67,8 @@ Category { float4 texcoord1 : TEXCOORD1; float3 tangent : TANGENT; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -76,6 +78,8 @@ Category { float3 worldPos : TEXCOORD1; float lifetime : TEXCOORD2; uint id : TEXCOORD3; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -85,6 +89,11 @@ Category { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float4 worldPos = mul(unity_ObjectToWorld, v.vertex); float3 perVertOffset = v.texcoord1.xyz; float lifetime = GetTime().y - v.texcoord1.w; diff --git a/Assets/Resources/Brushes/Basic/WaveformTube/WaveformTube.shader b/Assets/Resources/Brushes/Basic/WaveformTube/WaveformTube.shader index 4826982bcb..8c0de758bf 100644 --- a/Assets/Resources/Brushes/Basic/WaveformTube/WaveformTube.shader +++ b/Assets/Resources/Brushes/Basic/WaveformTube/WaveformTube.shader @@ -57,6 +57,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -64,6 +66,8 @@ Category { float4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -71,6 +75,11 @@ Category { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Resources/Brushes/Basic/Wireframe/Wireframe.shader b/Assets/Resources/Brushes/Basic/Wireframe/Wireframe.shader index e9834c3ede..b78381cb15 100644 --- a/Assets/Resources/Brushes/Basic/Wireframe/Wireframe.shader +++ b/Assets/Resources/Brushes/Basic/Wireframe/Wireframe.shader @@ -42,6 +42,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -49,6 +51,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -63,6 +67,10 @@ Category { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = v.texcoord; o.color = v.color; o.vertex = UnityObjectToClipPos(v.vertex); diff --git a/Assets/Resources/Brushes/Shared/Shaders/Additive.shader b/Assets/Resources/Brushes/Shared/Shaders/Additive.shader index cbf7ba1057..6d8bfbea6d 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Additive.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Additive.shader @@ -56,6 +56,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -63,6 +65,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float2 id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -72,6 +76,10 @@ Category { PrepForOds(v.vertex); v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); #ifdef AUDIO_REACTIVE o.color = musicReactiveColor(v.color, _BeatOutput.w); diff --git a/Assets/Resources/Brushes/Shared/Shaders/Bloom.shader b/Assets/Resources/Brushes/Shared/Shaders/Bloom.shader index e4139c7423..4dab78b80b 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Bloom.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Bloom.shader @@ -56,6 +56,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -63,6 +65,8 @@ Category { float4 color : COLOR; float2 texcoord : TEXCOORD0; float2 id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -70,6 +74,11 @@ Category { PrepForOds(v.vertex); v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(v.color, _EmissionGain); #ifdef AUDIO_REACTIVE diff --git a/Assets/Resources/Brushes/Shared/Shaders/Multiplicative.shader b/Assets/Resources/Brushes/Shared/Shaders/Multiplicative.shader index 9ce5f0b6bd..a35ba6f98f 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Multiplicative.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Multiplicative.shader @@ -44,6 +44,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -51,6 +53,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -64,6 +68,11 @@ Category { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color; diff --git a/Assets/Resources/Brushes/Shared/Shaders/Special/Faceted.shader b/Assets/Resources/Brushes/Shared/Shaders/Special/Faceted.shader index 4752170aef..369d7a4952 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Special/Faceted.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Special/Faceted.shader @@ -52,6 +52,8 @@ SubShader { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -60,12 +62,19 @@ SubShader { float2 texcoord : TEXCOORD0; float3 worldPos : TEXCOORD1; float2 id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.color = v.color; o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); diff --git a/Assets/Resources/Brushes/Shared/Shaders/Special/Intersection.shader b/Assets/Resources/Brushes/Shared/Shaders/Special/Intersection.shader index c20575062a..82a574e3ae 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Special/Intersection.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Special/Intersection.shader @@ -34,6 +34,7 @@ Shader "Brush/Special/Intersection" { #pragma fragment frag #pragma geometry geom +#include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/PackInt.cginc" @@ -45,6 +46,8 @@ Shader "Brush/Special/Intersection" { struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -55,12 +58,18 @@ Shader "Brush/Special/Intersection" { #if TILT_ENABLE_CONSERVATIVE_RASTER // Saves some overhead when unused. float4 aabb : TEXCOORD1; float4 clipPos : TEXCOORD2; -#endif + #endif + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.color = half4(0, 0, 0, 0); diff --git a/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionDownsample.shader b/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionDownsample.shader index 2d7529cabf..b65f91228a 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionDownsample.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionDownsample.shader @@ -48,6 +48,8 @@ Shader "Brush/Special/IntersectionDownsample" { { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f @@ -55,11 +57,18 @@ Shader "Brush/Special/IntersectionDownsample" { // WARNING: If an interpolation modifier is added to uv, code must be updated below. float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; diff --git a/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionNonGeomFallback.shader b/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionNonGeomFallback.shader index 4074f2b113..0853929f18 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionNonGeomFallback.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Special/IntersectionNonGeomFallback.shader @@ -33,23 +33,33 @@ Shader "Brush/Special/Intersection" { #pragma vertex vert #pragma fragment frag +#include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/PackInt.cginc" struct appdata_t { float4 vertex : POSITION; float4 triangleids : TEXCOORD4; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 triangleids : TEXCOORD4; half4 color : COLOR; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.color = half4(0, 0, 0, 0); o.triangleids = v.triangleids; diff --git a/Assets/Resources/Brushes/Shared/Shaders/Unlit.shader b/Assets/Resources/Brushes/Shared/Shaders/Unlit.shader index 8066649df7..318545b600 100644 --- a/Assets/Resources/Brushes/Shared/Shaders/Unlit.shader +++ b/Assets/Resources/Brushes/Shared/Shaders/Unlit.shader @@ -51,6 +51,8 @@ SubShader { float2 texcoord : TEXCOORD0; float4 color : COLOR; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -59,6 +61,8 @@ SubShader { float4 color : COLOR; float2 id : TEXCOORD2; UNITY_FOG_COORDS(1) + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -67,6 +71,10 @@ SubShader { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; o.id = (float2)v.id; diff --git a/Assets/Resources/X/Brushes/Digital/Digital.shader b/Assets/Resources/X/Brushes/Digital/Digital.shader index dc9d417150..a90dee5e81 100644 --- a/Assets/Resources/X/Brushes/Digital/Digital.shader +++ b/Assets/Resources/X/Brushes/Digital/Digital.shader @@ -59,6 +59,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -67,6 +69,8 @@ Category { float2 texcoord : TEXCOORD0; float2 st : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -78,6 +82,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color; diff --git a/Assets/Resources/X/Brushes/Drafting/Drafting.shader b/Assets/Resources/X/Brushes/Drafting/Drafting.shader index 75f4ac2a62..080e61e538 100644 --- a/Assets/Resources/X/Brushes/Drafting/Drafting.shader +++ b/Assets/Resources/X/Brushes/Drafting/Drafting.shader @@ -56,6 +56,8 @@ Shader "Brush/Special/Drafting" { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -63,12 +65,19 @@ Shader "Brush/Special/Drafting" { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color * _DraftingVisibility01; diff --git a/Assets/Resources/X/Brushes/Fairy/Fairy.shader b/Assets/Resources/X/Brushes/Fairy/Fairy.shader index 9689a55ec5..fcf9e2c165 100644 --- a/Assets/Resources/X/Brushes/Fairy/Fairy.shader +++ b/Assets/Resources/X/Brushes/Fairy/Fairy.shader @@ -63,6 +63,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -70,6 +72,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -81,6 +85,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color; diff --git a/Assets/Resources/X/Brushes/Fire 2/Fire2.shader b/Assets/Resources/X/Brushes/Fire 2/Fire2.shader index 03a15da8db..762d17f559 100644 --- a/Assets/Resources/X/Brushes/Fire 2/Fire2.shader +++ b/Assets/Resources/X/Brushes/Fire 2/Fire2.shader @@ -77,6 +77,8 @@ Category { #endif float3 worldPos : TEXCOORD1; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -89,6 +91,8 @@ Category { #endif float3 worldPos : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -104,9 +108,14 @@ Category { { PrepForOds(v.vertex); - + v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(v.color, _EmissionGain); o.vertex = UnityObjectToClipPos(v.vertex); @@ -126,7 +135,7 @@ Category { float procedural_line = 0; float flame_fade_mix = 0; - displacement = tex2D( _DisplaceTex, i.texcoord ).xy; + displacement = tex2D( _DisplaceTex, i.texcoord ).xy; displacement = displacement * 2.0 - 1.0; displacement *= _DisplacementIntensity; diff --git a/Assets/Resources/X/Brushes/Race/Race.shader b/Assets/Resources/X/Brushes/Race/Race.shader index 2a6f0e6343..5d540d2628 100644 --- a/Assets/Resources/X/Brushes/Race/Race.shader +++ b/Assets/Resources/X/Brushes/Race/Race.shader @@ -56,6 +56,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -63,6 +65,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -78,6 +82,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color; diff --git a/Assets/Resources/X/Brushes/Rain/Rain.shader b/Assets/Resources/X/Brushes/Rain/Rain.shader index 400c3ae7c2..16cb423c8e 100644 --- a/Assets/Resources/X/Brushes/Rain/Rain.shader +++ b/Assets/Resources/X/Brushes/Rain/Rain.shader @@ -83,6 +83,8 @@ Category { float2 texcoord : TEXCOORD0; float4 worldPos : TEXCOORD1; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; @@ -93,6 +95,10 @@ Category { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Inflate the tube outward to explode it into // strips - giving us negative space w/o as much overdraw. _Bulge = 2.25; diff --git a/Assets/Resources/X/Brushes/RisingBubbles/RisingBubbles.shader b/Assets/Resources/X/Brushes/RisingBubbles/RisingBubbles.shader index ea29da34d8..c1c65400f2 100644 --- a/Assets/Resources/X/Brushes/RisingBubbles/RisingBubbles.shader +++ b/Assets/Resources/X/Brushes/RisingBubbles/RisingBubbles.shader @@ -70,6 +70,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -102,6 +104,11 @@ Category { v2f vert (ParticleVertexWithSpread_t v) { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Used as a random-ish seed for various calculations float seed = v.color.a; float t01 = fmod(GetTime().y*_ScrollRate + seed * 10, 1); diff --git a/Assets/Resources/X/Brushes/Slice/Slice.shader b/Assets/Resources/X/Brushes/Slice/Slice.shader index 507eabbceb..e3e55b7a1b 100644 --- a/Assets/Resources/X/Brushes/Slice/Slice.shader +++ b/Assets/Resources/X/Brushes/Slice/Slice.shader @@ -48,6 +48,8 @@ Category { // float3 normal : NORMAL; float3 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -55,6 +57,8 @@ Category { // fixed4 color : COLOR; float3 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -67,6 +71,11 @@ Category { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; o.id = (float2)v.id; diff --git a/Assets/Resources/X/Brushes/Space/Space.shader b/Assets/Resources/X/Brushes/Space/Space.shader index 9ed756097f..22e6bb9016 100644 --- a/Assets/Resources/X/Brushes/Space/Space.shader +++ b/Assets/Resources/X/Brushes/Space/Space.shader @@ -61,6 +61,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -68,6 +70,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -83,6 +87,11 @@ Category { v.color = TbVertToSrgb(v.color); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = v.color; diff --git a/Assets/Resources/X/Brushes/Sparks/Sparks.shader b/Assets/Resources/X/Brushes/Sparks/Sparks.shader index 1a6b3cda64..6bb5d4b7bc 100644 --- a/Assets/Resources/X/Brushes/Sparks/Sparks.shader +++ b/Assets/Resources/X/Brushes/Sparks/Sparks.shader @@ -65,6 +65,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -72,6 +74,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -93,6 +97,10 @@ Category { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // This multiplier is a magic number but it's still not right. Is there a better // multiplciation for this (not using fmod) so I can count on the "lifetime" being contstant? /* diff --git a/Assets/Resources/X/Brushes/TaperedHueShift/TaperedHueShift.shader b/Assets/Resources/X/Brushes/TaperedHueShift/TaperedHueShift.shader index 2a9ff1e2eb..dadae29e9d 100644 --- a/Assets/Resources/X/Brushes/TaperedHueShift/TaperedHueShift.shader +++ b/Assets/Resources/X/Brushes/TaperedHueShift/TaperedHueShift.shader @@ -50,6 +50,8 @@ SubShader { float2 texcoord : TEXCOORD0; float4 color : COLOR; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -58,6 +60,8 @@ SubShader { float4 color : COLOR; uint id : TEXCOORD2; UNITY_FOG_COORDS(1) + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) @@ -66,6 +70,11 @@ SubShader { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; o.color = TbVertToNative(v.color); diff --git a/Assets/Resources/X/Brushes/Wind/Wind.shader b/Assets/Resources/X/Brushes/Wind/Wind.shader index efd78021e3..f31ced470f 100644 --- a/Assets/Resources/X/Brushes/Wind/Wind.shader +++ b/Assets/Resources/X/Brushes/Wind/Wind.shader @@ -64,6 +64,8 @@ Category { float3 normal : NORMAL; float2 texcoord : TEXCOORD0; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -71,6 +73,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; uint id : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; @@ -79,6 +83,10 @@ Category { PrepForOds(v.vertex); v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = TbVertToNative(v.color); o.vertex = UnityObjectToClipPos(v.vertex); diff --git a/Assets/Scripts/App.cs b/Assets/Scripts/App.cs index 00818da5b3..a21014eb25 100644 --- a/Assets/Scripts/App.cs +++ b/Assets/Scripts/App.cs @@ -508,6 +508,11 @@ void Awake() // See if this is the first time HasPlayedBefore = PlayerPrefs.GetInt(kPlayerPrefHasPlayedBefore, 0) == 1; +#if ZAPBOX_SUPPORTED + // TODO:Mikesky - fix zapbox support. + HasPlayedBefore = true; +#endif + // Copy files into Support directory CopySupportFiles(); diff --git a/Assets/Scripts/Export/Export.cs b/Assets/Scripts/Export/Export.cs index 47211c83df..1dfa97d8e3 100644 --- a/Assets/Scripts/Export/Export.cs +++ b/Assets/Scripts/Export/Export.cs @@ -119,7 +119,7 @@ public static void ExportScene() var progress = new Progress(); if (App.PlatformConfig.EnableExportJson) { progress.SetWork("json"); } #if FBX_SUPPORTED - if (App.PlatformConfig.EnableExportFbx) { progress.SetWork("fbx"); } + if (App.PlatformConfig.EnableExportFbx) { progress.SetWork("fbx"); } #endif #if USD_SUPPORTED if (App.PlatformConfig.EnableExportUsd) { progress.SetWork("usd"); } @@ -132,7 +132,7 @@ public static void ExportScene() progress.SetWork("wrl"); progress.SetWork("stl"); #if FBX_SUPPORTED - progress.SetWork("obj"); + progress.SetWork("obj"); #endif } if (App.PlatformConfig.EnableExportGlb) { progress.SetWork("glb"); } @@ -152,16 +152,17 @@ public static void ExportScene() progress.CompleteWork("json"); #if FBX_SUPPORTED - if (App.PlatformConfig.EnableExportFbx && - (filename = MakeExportPath(parent, basename, "fbx")) != null) - using (var unused = new AutoTimer("fbx export")) { - OverlayManager.m_Instance.UpdateProgress(0.3f); - ExportFbx.Export(filename, - App.UserConfig.Export.ExportBinaryFbx ? ExportFbx.kFbxBinary : ExportFbx.kFbxAscii, - App.UserConfig.Export.ExportFbxVersion); - OverlayManager.m_Instance.UpdateProgress(0.5f); - } - progress.CompleteWork("fbx"); + if (App.PlatformConfig.EnableExportFbx && + (filename = MakeExportPath(parent, basename, "fbx")) != null) + using (var unused = new AutoTimer("fbx export")) + { + OverlayManager.m_Instance.UpdateProgress(0.3f); + ExportFbx.Export(filename, + App.UserConfig.Export.ExportBinaryFbx ? ExportFbx.kFbxBinary : ExportFbx.kFbxAscii, + App.UserConfig.Export.ExportFbxVersion); + OverlayManager.m_Instance.UpdateProgress(0.5f); + } + progress.CompleteWork("fbx"); #endif #if USD_SUPPORTED @@ -206,13 +207,14 @@ public static void ExportScene() } #if FBX_SUPPORTED - if (Config.IsExperimental && - App.PlatformConfig.EnableExportFbx && - (filename = MakeExportPath(parent, basename, "obj")) != null) { - // This has never been tested with the new fbx export style and may not work - ExportFbx.Export(filename, ExportFbx.kObj); - progress.CompleteWork("obj"); - } + if (Config.IsExperimental && + App.PlatformConfig.EnableExportFbx && + (filename = MakeExportPath(parent, basename, "obj")) != null) + { + // This has never been tested with the new fbx export style and may not work + ExportFbx.Export(filename, ExportFbx.kObj); + progress.CompleteWork("obj"); + } #endif if (App.PlatformConfig.EnableExportGlb) diff --git a/Assets/Scripts/Export/ExportFbx.cs b/Assets/Scripts/Export/ExportFbx.cs index 6f80b9bdaa..da7be09396 100644 --- a/Assets/Scripts/Export/ExportFbx.cs +++ b/Assets/Scripts/Export/ExportFbx.cs @@ -23,615 +23,709 @@ using TiltBrushToolkit; using static TiltBrush.ExportUtils; -namespace TiltBrush { - -// Our old wrappers used an explicit FbxString; Unity's uses System.String -// instead of exposing FbxString. This papers over the difference. -class FbxString { - private string m_s; - public FbxString(string s) { m_s = s; } - - public static implicit operator string(FbxString fs) { - return fs.m_s; - } -} - -// Analagous to GlTF_Globals -- this is global export state needed by most functions. -class FbxExportGlobals : IDisposable { - public readonly string m_outputFile; - public readonly string m_outputDir; - public readonly string m_sanitizedFileName; - public FbxManager m_manager; - public FbxIOSettings m_ioSettings; - public FbxExporter m_exporter; - public FbxScene m_scene; - - private Dictionary m_createdMeshes = - new Dictionary(); - private Dictionary m_createdMaterials = - new Dictionary(); - private HashSet m_createdMaterialNames = new HashSet(); - public ExportFileReference.DisambiguationContext m_disambiguationContext = - new ExportFileReference.DisambiguationContext(); - - public FbxExportGlobals(string outputFile) { - m_outputFile = outputFile; - m_sanitizedFileName = System.Text.RegularExpressions.Regex.Replace( - Path.GetFileNameWithoutExtension(m_outputFile), - @"[^a-zA-Z0-9_]", "_"); - m_outputDir = Path.GetDirectoryName(outputFile); - m_manager = FbxManager.Create(); - m_ioSettings = FbxIOSettings.Create(m_manager, Globals.IOSROOT); - m_manager.SetIOSettings(m_ioSettings); - m_exporter = FbxExporter.Create(m_manager, ""); - } - - public void Dispose() { - if (m_exporter != null) { m_exporter.Destroy(); m_exporter = null; } - if (m_ioSettings != null) { m_ioSettings.Destroy(); m_ioSettings = null; } - if (m_manager != null) { m_manager.Destroy(); m_manager = null; } - } - - /// Memoized version of CreateFbxMesh - public FbxMesh GetOrCreateFbxMesh(ExportUtils.BaseMeshPayload payload) { - if (m_createdMeshes.TryGetValue(payload.geometry, out FbxMesh mesh)) { - return mesh; - } else { - // nb: this name is ignored by Unity, which names meshes after one of the nodes - // which uses that mesh. - FbxMesh newMesh = ExportFbx.CreateFbxMesh(this, payload.geometry, payload.geometryName); - m_createdMeshes[payload.geometry] = newMesh; - return newMesh; - } - } - - /// Memoized version of CreateFbxMaterial - /// Guarantees 1:1 correspondence between IEM, FbxMaterial, and FbxMaterial.name - public FbxSurfaceMaterial GetOrCreateFbxMaterial( - string meshNamespace, - IExportableMaterial exportableMaterial) { - // Unity's able to ensure a 1:1 correspondence between FBX materials and generated Unity - // materials. However, users like TBT who go through the OnAssignMaterialModel interface cannot - // distinguish between "two unique materials with the same name" and "one material being - // used multiple times". - // - // Since TBT can't detect reference-equality of FbxMaterial, we have to help it by - // making name-equality the same as reference-equality. IOW distinct materials need - // distinct names. - if (m_createdMaterials.TryGetValue(exportableMaterial, out FbxSurfaceMaterial mtl)) { - return mtl; - } else { - FbxSurfaceMaterial newMtl = ExportFbx.CreateFbxMaterial( - this, meshNamespace, exportableMaterial, m_createdMaterialNames); - m_createdMaterials[exportableMaterial] = newMtl; - return newMtl; - } - } -} - -public static class ExportFbx { - private const string kRelativeTextureDir = ""; - - public const string kFbxBinary = "FBX binary (*.fbx)"; - public const string kFbxAscii = "FBX ascii (*.fbx)"; - public const string kObj = "Alias OBJ (*.obj)"; - - public static Matrix4x4 FbxFromUnity { get; private set; } - public static Matrix4x4 UnityFromFbx { get; private set; } - - class ExportMesh { - public GeometryPool m_pool; - public List m_linearColor; - - // If geometry does not contain normals, colors, and/or uvs, dummy values - // will be added. - public ExportMesh(GeometryPool pool) { - m_pool = pool; - FbxUtils.ApplyFbxTexcoordHack(m_pool); - m_linearColor = ExportUtils.ConvertToLinearColorspace(m_pool.m_Colors); - - var layout = m_pool.Layout; - var numVerts = m_pool.m_Vertices.Count; - - // TODO: all this padding code seems super bogus; try to remove. - if (!layout.bUseNormals) { - var lst = m_pool.m_Normals; - lst.SetCount(numVerts); - for (int i = 0; i < numVerts; ++i) { lst[i] = Vector3.up; } - } - - if (!layout.bUseColors) { - var lst = m_linearColor; - lst.SetCount(numVerts); - for (int i = 0; i < numVerts; ++i) { lst[i] = Color.white; } - } - } - } - - static ExportFbx() { - Matrix4x4 fbxFromUnity = Matrix4x4.identity; - fbxFromUnity.m00 = -1; // Unity assumes .fbx files have a flipped x axis - FbxFromUnity = fbxFromUnity; - UnityFromFbx = FbxFromUnity.inverse; - } - - /// Main entry point - public static bool Export(string outputFile, string format, string fbxVersion = null) { - using (var G = new FbxExportGlobals(outputFile)) { - int fmt = G.m_manager.GetIOPluginRegistry().FindWriterIDByDescription(format); - if (!G.m_exporter.Initialize(outputFile, fmt, G.m_ioSettings)) { - OutputWindowScript.Error("FBX export failed", "Could not initialize exporter"); - return false; - } - if (!String.IsNullOrEmpty(fbxVersion)) { - G.m_exporter.SetFileExportVersion(new FbxString(fbxVersion)); - } - - G.m_scene = FbxScene.Create(G.m_manager, "scene"); - if (G.m_scene == null) { - OutputWindowScript.Error("FBX export failed", "Could not initialize scene"); - return false; - } - - String version = string.Format("{0}.{1}", App.Config.m_VersionNumber, - App.Config.m_BuildStamp); - FbxDocumentInfo info = FbxDocumentInfo.Create(G.m_manager, "DocInfo"); - info.Original_ApplicationVendor.Set(new FbxString("Icosa Gallery")); - info.Original_ApplicationName.Set(new FbxString(App.kAppDisplayName)); - info.Original_ApplicationVersion.Set(new FbxString(version)); - info.LastSaved_ApplicationVendor.Set(new FbxString("Icosa Gallery")); - info.LastSaved_ApplicationName.Set(new FbxString(App.kAppDisplayName)); - info.LastSaved_ApplicationVersion.Set(new FbxString(version)); - // The toolkit's FBX parser is too simple to be able to read anything but - // the UserData/Properties70 node, so add the extra info as a custom property - var stringType = info.Original_ApplicationVersion.GetPropertyDataType(); - var prop = FbxProperty.Create(info.Original, stringType, "RequiredToolkitVersion"); - prop.SetString(FbxUtils.kRequiredToolkitVersion); - - G.m_scene.SetDocumentInfo(info); - G.m_scene.GetGlobalSettings().SetSystemUnit(FbxSystemUnit.m); - - try { - WriteObjectsAndConnections2(G); - G.m_exporter.Export(G.m_scene); - } catch (InvalidOperationException e) { - OutputWindowScript.Error("FBX export failed", e.Message); - return false; - } catch (IOException e) { - OutputWindowScript.Error("FBX export failed", e.Message); - return false; - } - return true; - } - } - - // This writes out payload.xform - static FbxNode ExportMeshPayload_Global( - FbxExportGlobals G, BaseMeshPayload payload, FbxNode parentNode) { - // If these aren't unique, either FBX or Unity will uniquify them for us -- not sure which. - // So roll payload.id into the name. - FbxNode fbxNode = FbxNode.Create(G.m_manager, payload.nodeName); - fbxNode.SetLocalTransform(payload.xform); - fbxNode.SetNodeAttribute(G.GetOrCreateFbxMesh(payload)); - fbxNode.AddMaterial(G.GetOrCreateFbxMaterial( - payload.MeshNamespace, payload.exportableMaterial)); - - parentNode.AddChild(fbxNode); - return fbxNode; - } - - // This writes out the local xform, and requires that parentNode use payload.instanceXform - static void ExportMeshPayload_Local( - FbxExportGlobals G, ModelMeshPayload payload, FbxNode parentNode) { - // If these aren't unique, either FBX or Unity will uniquify them for us -- not sure which. - // So roll payload.id into the name. - FbxNode fbxNode = FbxNode.Create(G.m_manager, payload.nodeName); - fbxNode.SetLocalTransform(payload.localXform); - fbxNode.SetNodeAttribute(G.GetOrCreateFbxMesh(payload)); - fbxNode.AddMaterial(G.GetOrCreateFbxMaterial( - payload.MeshNamespace, payload.exportableMaterial)); - - parentNode.AddChild(fbxNode); - } - - internal static FbxSurfaceMaterial CreateFbxMaterial( - FbxExportGlobals G, string meshNamespace, IExportableMaterial exportableMaterial, - HashSet createdMaterialNames) { - string materialName; - if (exportableMaterial is BrushDescriptor) { - // Toolkit uses this guid (in "N" format) to look up a BrushDescriptor. - // See Toolkit's ModelImportSettings.GetDescriptorForStroke - materialName = $"{exportableMaterial.UniqueName:N}_{meshNamespace}_{exportableMaterial.DurableName}"; - } else if (exportableMaterial is DynamicExportableMaterial dem) { - // Comes from {fbx,obj,gltf,...} import from {Poly, Media Library} - // This is a customized version of a BrushDescriptor -- almost certainly - // Pbr{Blend,Opaque}{Double,Single}Sided with maybe an added texture and - // some of its params customized. - // TBT will merge the material created by Unity for this FbxMaterial with - // the premade material it has for the parent guid. - materialName = $"{dem.Parent.m_Guid:N}_{meshNamespace}_{dem.DurableName}"; - } else { - Debug.LogWarning($"Unknown class {exportableMaterial.GetType().Name}"); - materialName = $"{meshNamespace}_{exportableMaterial.DurableName}"; - } - // If only ExportFbx were a non-static class we could merge it with FbxExportGlobals - materialName = ExportUtils.CreateUniqueName(materialName, createdMaterialNames); +namespace TiltBrush +{ - FbxSurfaceLambert material = FbxSurfaceLambert.Create(G.m_scene, materialName); + // Our old wrappers used an explicit FbxString; Unity's uses System.String + // instead of exposing FbxString. This papers over the difference. + class FbxString + { + private string m_s; + public FbxString(string s) { m_s = s; } - material.Ambient.Set(new FbxDouble3(0, 0, 0)); - material.Diffuse.Set(new FbxDouble3(1.0, 1.0, 1.0)); - if (exportableMaterial.EmissiveFactor > 0) { - material.EmissiveFactor.Set(exportableMaterial.EmissiveFactor); - material.Emissive.Set(new FbxDouble3(1.0, 1.0, 1.0)); - } - if (exportableMaterial.BlendMode != ExportableMaterialBlendMode.None) { - var blendMode = FbxProperty.Create(material, Globals.FbxStringDT, "BlendMode"); - switch (exportableMaterial.BlendMode) { - case ExportableMaterialBlendMode.AlphaMask: - blendMode.SetString(new FbxString("AlphaMask")); - material.TransparencyFactor.Set(0.2); - break; - case ExportableMaterialBlendMode.AdditiveBlend: - blendMode.SetString(new FbxString("AdditiveBlend")); - break; - } + public static implicit operator string(FbxString fs) + { + return fs.m_s; + } } - // Export the texture - if (exportableMaterial.HasExportTexture()) { - // This is not perfectly unique, but it is good enough for fbx export - // better would be to use _ but that's ugly, and nobody uses - // the textures anyway, so... let's leave well enough alone for now. - string albedoTextureName = exportableMaterial.DurableName; - var fullTextureDir = Path.Combine(G.m_outputDir, kRelativeTextureDir); - if (!Directory.Exists(fullTextureDir)) { - if (!FileUtils.InitializeDirectoryWithUserError(fullTextureDir)) { - throw new IOException("Cannot write textures"); + // Analagous to GlTF_Globals -- this is global export state needed by most functions. + class FbxExportGlobals : IDisposable + { + public readonly string m_outputFile; + public readonly string m_outputDir; + public readonly string m_sanitizedFileName; + public FbxManager m_manager; + public FbxIOSettings m_ioSettings; + public FbxExporter m_exporter; + public FbxScene m_scene; + + private Dictionary m_createdMeshes = + new Dictionary(); + private Dictionary m_createdMaterials = + new Dictionary(); + private HashSet m_createdMaterialNames = new HashSet(); + public ExportFileReference.DisambiguationContext m_disambiguationContext = + new ExportFileReference.DisambiguationContext(); + + public FbxExportGlobals(string outputFile) + { + m_outputFile = outputFile; + m_sanitizedFileName = System.Text.RegularExpressions.Regex.Replace( + Path.GetFileNameWithoutExtension(m_outputFile), + @"[^a-zA-Z0-9_]", "_"); + m_outputDir = Path.GetDirectoryName(outputFile); + m_manager = FbxManager.Create(); + m_ioSettings = FbxIOSettings.Create(m_manager, Globals.IOSROOT); + m_manager.SetIOSettings(m_ioSettings); + m_exporter = FbxExporter.Create(m_manager, ""); } - } - string src = exportableMaterial.GetExportTextureFilename(); - var textureFileName = albedoTextureName + ".png"; - var textureFilePath = Path.Combine(fullTextureDir, textureFileName); - FileInfo srcInfo = new FileInfo(src); - if (srcInfo.Exists && !new FileInfo(textureFilePath).Exists) { - srcInfo.CopyTo(textureFilePath); - } - - FbxFileTexture texture = FbxFileTexture.Create(G.m_scene, albedoTextureName + "_texture"); - texture.SetFileName(textureFilePath); - texture.SetTextureUse(FbxTexture.ETextureUse.eStandard); - texture.SetMappingType(FbxTexture.EMappingType.eUV); - texture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); - texture.UVSet.Set(new FbxString("uv0")); - material.Diffuse.ConnectSrcObject(texture); - material.TransparentColor.ConnectSrcObject(texture); - } else { - foreach (var kvp in exportableMaterial.TextureUris) { - string parameterName = kvp.Key; - string textureUri = kvp.Value; - if (ExportFileReference.IsHttp(textureUri)) { - // fbx can't deal with http references to textures - continue; + + public void Dispose() + { + if (m_exporter != null) { m_exporter.Destroy(); m_exporter = null; } + if (m_ioSettings != null) { m_ioSettings.Destroy(); m_ioSettings = null; } + if (m_manager != null) { m_manager.Destroy(); m_manager = null; } } - ExportFileReference fileRef = ExportFileReference.GetOrCreateSafeLocal( - G.m_disambiguationContext, textureUri, exportableMaterial.UriBase, - $"{meshNamespace}_{Path.GetFileName(textureUri)}"); - AddTextureToMaterial(G, fileRef, material, parameterName); - } - } - return material; - } - - // Pass: - // parameterName - - // used for the FbxTexture name. Can be something arbitrary since as far as I know, - // the texture node's name is unused by importers. - private static void AddTextureToMaterial( - FbxExportGlobals G, - ExportFileReference fileRef, - FbxSurfaceLambert fbxMaterial, - string parameterName) { - Debug.Assert(File.Exists(fileRef.m_originalLocation)); - - var destPath = Path.Combine(G.m_outputDir, fileRef.m_uri); - if (!File.Exists(destPath)) { - if (!FileUtils.InitializeDirectoryWithUserError(Path.GetDirectoryName(destPath))) { - return; - } - File.Copy(fileRef.m_originalLocation, destPath); - } - // It's kind of weird that the parameter name is used for the texture node's name, - // but as far as I can tell nobody cares about that name, so whatever. - FbxFileTexture fbxTexture = FbxFileTexture.Create(G.m_scene, parameterName); - fbxTexture.SetFileName(destPath); - fbxTexture.SetTextureUse(FbxTexture.ETextureUse.eStandard); - fbxTexture.SetMappingType(FbxTexture.EMappingType.eUV); - fbxTexture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); - fbxTexture.UVSet.Set(new FbxString("uv0")); - // It's also weird that we only ever assign to the Diffuse slot. - // Shouldn't we be looking at the parameter name and assigning to Diffuse, Normal, etc - // based on what we see? - // TODO: check - fbxMaterial.Diffuse.ConnectSrcObject(fbxTexture); - fbxMaterial.TransparentColor.ConnectSrcObject(fbxTexture); - } - - // Returns the root, or a node right under the root. - // Either way, the transform stack is guaranteed to be identity. - static FbxNode GetGroupNode(FbxManager manager, FbxScene scene, UInt32 group) { - FbxNode root = scene.GetRootNode(); - if (group == 0) { - return root; - } - string childName = $"group_{group}"; - FbxNode child = root.FindChild(childName, false); - if (child == null) { - child = FbxNode.Create(manager, childName); - root.AddChild(child); - } - return child; - } - - static void SetLocalTransform(this FbxNode node, TrTransform xf) { - node.LclTranslation.Set(new FbxDouble3(xf.translation.x, xf.translation.y, xf.translation.z)); - node.LclRotation.Set(XYZEulerFromQuaternion(xf.rotation)); - node.LclScaling.Set(new FbxDouble3(xf.scale, xf.scale, xf.scale)); - } - - static void SetLocalTransform(this FbxNode node, Matrix4x4 xf) { - node.SetLocalTransform(TrTransform.FromMatrix4x4(xf)); - } - - // outputFile must be a full path. - static void WriteObjectsAndConnections2(FbxExportGlobals G) { - var payload = ExportCollector.GetExportPayload( - AxisConvention.kFbxAccordingToUnity, - includeLocalMediaContent: true); - - // Write out each brush entry's geometry. - foreach (var brushMeshPayload in payload.groups.SelectMany(g => g.brushMeshes)) { - // This code used to not set the transform; check that it didn't cause issues - Debug.Assert(brushMeshPayload.xform.isIdentity); - FbxNode parentNode = GetGroupNode(G.m_manager, G.m_scene, brushMeshPayload.group); - ExportMeshPayload_Global(G, brushMeshPayload, parentNode); - } + /// Memoized version of CreateFbxMesh + public FbxMesh GetOrCreateFbxMesh(ExportUtils.BaseMeshPayload payload) + { + if (m_createdMeshes.TryGetValue(payload.geometry, out FbxMesh mesh)) + { + return mesh; + } + else + { + // nb: this name is ignored by Unity, which names meshes after one of the nodes + // which uses that mesh. + FbxMesh newMesh = ExportFbx.CreateFbxMesh(this, payload.geometry, payload.geometryName); + m_createdMeshes[payload.geometry] = newMesh; + return newMesh; + } + } - // Models with exportable meshes. - foreach (var sameInstance in payload.modelMeshes.GroupBy(m => (m.model, m.modelId))) { - var modelMeshPayloads = sameInstance.ToList(); - if (modelMeshPayloads.Count == 0) { continue; } - - // All of these pieces will come from the same Widget and therefore will have - // the same group id, root transform, etc - var first = modelMeshPayloads[0]; - FbxNode parentParentNode = GetGroupNode(G.m_manager, G.m_scene, first.group); - string rootNodeName = $"model_{first.model.GetExportName()}_{first.modelId}"; - if (modelMeshPayloads.Count == 1 && first.localXform.isIdentity) { - // Condense the two nodes into one; give the top-level node the same name - // it would have had had it been multi-level. - FbxNode newNode = ExportMeshPayload_Global(G, first, parentParentNode); - newNode.SetName(rootNodeName); - } else { - FbxNode parentNode = FbxNode.Create(G.m_manager, rootNodeName); - parentNode.SetLocalTransform(first.parentXform); - parentParentNode.AddChild(parentNode); - foreach (var modelMeshPayload in modelMeshPayloads) { - ExportMeshPayload_Local(G, modelMeshPayload, parentNode); + /// Memoized version of CreateFbxMaterial + /// Guarantees 1:1 correspondence between IEM, FbxMaterial, and FbxMaterial.name + public FbxSurfaceMaterial GetOrCreateFbxMaterial( + string meshNamespace, + IExportableMaterial exportableMaterial) + { + // Unity's able to ensure a 1:1 correspondence between FBX materials and generated Unity + // materials. However, users like TBT who go through the OnAssignMaterialModel interface cannot + // distinguish between "two unique materials with the same name" and "one material being + // used multiple times". + // + // Since TBT can't detect reference-equality of FbxMaterial, we have to help it by + // making name-equality the same as reference-equality. IOW distinct materials need + // distinct names. + if (m_createdMaterials.TryGetValue(exportableMaterial, out FbxSurfaceMaterial mtl)) + { + return mtl; + } + else + { + FbxSurfaceMaterial newMtl = ExportFbx.CreateFbxMaterial( + this, meshNamespace, exportableMaterial, m_createdMaterialNames); + m_createdMaterials[exportableMaterial] = newMtl; + return newMtl; + } } - } } - foreach (ImageQuadPayload meshPayload in payload.imageQuads) { - FbxNode groupNode = GetGroupNode(G.m_manager, G.m_scene, meshPayload.group); - ExportMeshPayload_Global(G, meshPayload, groupNode); - } + public static class ExportFbx + { + private const string kRelativeTextureDir = ""; + + public const string kFbxBinary = "FBX binary (*.fbx)"; + public const string kFbxAscii = "FBX ascii (*.fbx)"; + public const string kObj = "Alias OBJ (*.obj)"; + + public static Matrix4x4 FbxFromUnity { get; private set; } + public static Matrix4x4 UnityFromFbx { get; private set; } + + class ExportMesh + { + public GeometryPool m_pool; + public List m_linearColor; + + // If geometry does not contain normals, colors, and/or uvs, dummy values + // will be added. + public ExportMesh(GeometryPool pool) + { + m_pool = pool; + FbxUtils.ApplyFbxTexcoordHack(m_pool); + m_linearColor = ExportUtils.ConvertToLinearColorspace(m_pool.m_Colors); + + var layout = m_pool.Layout; + var numVerts = m_pool.m_Vertices.Count; + + // TODO: all this padding code seems super bogus; try to remove. + if (!layout.bUseNormals) + { + var lst = m_pool.m_Normals; + lst.SetCount(numVerts); + for (int i = 0; i < numVerts; ++i) { lst[i] = Vector3.up; } + } + + if (!layout.bUseColors) + { + var lst = m_linearColor; + lst.SetCount(numVerts); + for (int i = 0; i < numVerts; ++i) { lst[i] = Color.white; } + } + } + } - // Things that can only be exported as transforms (videos, images, models, ...) - foreach (var referenceThing in payload.referenceThings) { - FbxNode node = FbxNode.Create(G.m_manager, "reference_" + referenceThing.name); - node.SetLocalTransform(referenceThing.xform); - GetGroupNode(G.m_manager, G.m_scene, referenceThing.group).AddChild(node); - } - } - - public static FbxDouble3 XYZEulerFromQuaternion(Quaternion rotation) { - // Unity wrappers don't have FbxVector4::SetXYZ(FbxQuaternion) to convert quat -> xyz euler. - // We can abuse FbxAMatrix to do the same thing. - - FbxQuaternion fbxQuaternion = new FbxQuaternion(rotation.x, rotation.y, rotation.z, rotation.w); - // We're using the FBX API to do the conversion to XYZ eulers. - var mat = new FbxAMatrix(); - mat.SetIdentity(); - mat.SetQ(fbxQuaternion); - // "The returned rotation vector is in Euler angle and the rotation order is XYZ." - FbxVector4 v4 = mat.GetR(); - return new FbxDouble3(v4.X, v4.Y, v4.Z); - } - - // For use only by FbxExportGlobals. - internal static FbxMesh CreateFbxMesh(FbxExportGlobals G, GeometryPool pool, string poolName) { - FbxMesh fbxMesh = FbxMesh.Create(G.m_manager, poolName); - - ExportMesh mesh = new ExportMesh(pool); - int nVerts = mesh.m_pool.m_Vertices.Count; - fbxMesh.InitControlPoints(nVerts); - - unsafe { - fixed (Vector3* f = mesh.m_pool.m_Vertices.GetBackingArray()) { - Globals.SetControlPoints(fbxMesh, (IntPtr)f); - } - } + static ExportFbx() + { + Matrix4x4 fbxFromUnity = Matrix4x4.identity; + fbxFromUnity.m00 = -1; // Unity assumes .fbx files have a flipped x axis + FbxFromUnity = fbxFromUnity; + UnityFromFbx = FbxFromUnity.inverse; + } - List triangles = mesh.m_pool.m_Tris; - // Not available in Unity's wrappers - // fbxMesh.ReservePolygonCount(triangles.Count / 3); - // fbxMesh.ReservePolygonVertexCount(triangles.Count); - for (int i = 0; i < triangles.Count; i += 3) { - fbxMesh.BeginPolygon(-1 /* Material */, -1 /* Texture */, -1 /* Group */, false /* Legacy */); - fbxMesh.AddPolygon(triangles[i]); - fbxMesh.AddPolygon(triangles[i+1]); - fbxMesh.AddPolygon(triangles[i+2]); - fbxMesh.EndPolygon(); - } + /// Main entry point + public static bool Export(string outputFile, string format, string fbxVersion = null) + { + using (var G = new FbxExportGlobals(outputFile)) + { + int fmt = G.m_manager.GetIOPluginRegistry().FindWriterIDByDescription(format); + if (!G.m_exporter.Initialize(outputFile, fmt, G.m_ioSettings)) + { + OutputWindowScript.Error("FBX export failed", "Could not initialize exporter"); + return false; + } + if (!String.IsNullOrEmpty(fbxVersion)) + { + G.m_exporter.SetFileExportVersion(new FbxString(fbxVersion)); + } + + G.m_scene = FbxScene.Create(G.m_manager, "scene"); + if (G.m_scene == null) + { + OutputWindowScript.Error("FBX export failed", "Could not initialize scene"); + return false; + } + + String version = string.Format("{0}.{1}", App.Config.m_VersionNumber, + App.Config.m_BuildStamp); + FbxDocumentInfo info = FbxDocumentInfo.Create(G.m_manager, "DocInfo"); + info.Original_ApplicationVendor.Set(new FbxString("Icosa Gallery")); + info.Original_ApplicationName.Set(new FbxString(App.kAppDisplayName)); + info.Original_ApplicationVersion.Set(new FbxString(version)); + info.LastSaved_ApplicationVendor.Set(new FbxString("Icosa Gallery")); + info.LastSaved_ApplicationName.Set(new FbxString(App.kAppDisplayName)); + info.LastSaved_ApplicationVersion.Set(new FbxString(version)); + // The toolkit's FBX parser is too simple to be able to read anything but + // the UserData/Properties70 node, so add the extra info as a custom property + var stringType = info.Original_ApplicationVersion.GetPropertyDataType(); + var prop = FbxProperty.Create(info.Original, stringType, "RequiredToolkitVersion"); + prop.SetString(FbxUtils.kRequiredToolkitVersion); + + G.m_scene.SetDocumentInfo(info); + G.m_scene.GetGlobalSettings().SetSystemUnit(FbxSystemUnit.m); + + try + { + WriteObjectsAndConnections2(G); + G.m_exporter.Export(G.m_scene); + } + catch (InvalidOperationException e) + { + OutputWindowScript.Error("FBX export failed", e.Message); + return false; + } + catch (IOException e) + { + OutputWindowScript.Error("FBX export failed", e.Message); + return false; + } + return true; + } + } - FbxLayer layer0 = fbxMesh.GetLayer(0); - if (layer0 == null) { - fbxMesh.CreateLayer(); - layer0 = fbxMesh.GetLayer(0); - } + // This writes out payload.xform + static FbxNode ExportMeshPayload_Global( + FbxExportGlobals G, BaseMeshPayload payload, FbxNode parentNode) + { + // If these aren't unique, either FBX or Unity will uniquify them for us -- not sure which. + // So roll payload.id into the name. + FbxNode fbxNode = FbxNode.Create(G.m_manager, payload.nodeName); + fbxNode.SetLocalTransform(payload.xform); + fbxNode.SetNodeAttribute(G.GetOrCreateFbxMesh(payload)); + fbxNode.AddMaterial(G.GetOrCreateFbxMaterial( + payload.MeshNamespace, payload.exportableMaterial)); + + parentNode.AddChild(fbxNode); + return fbxNode; + } - var layerElementNormal = FbxLayerElementNormal.Create(fbxMesh, "normals"); - layerElementNormal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); - layerElementNormal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); - CopyToFbx(layerElementNormal.GetDirectArray(), mesh.m_pool.m_Normals); - layer0.SetNormals(layerElementNormal); - - var layerElementColor = FbxLayerElementVertexColor.Create(fbxMesh, "color"); - layerElementColor.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); - layerElementColor.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); - CopyToFbx(layerElementColor.GetDirectArray(), mesh.m_linearColor); - layer0.SetVertexColors(layerElementColor); - - var layerElementTangent = FbxLayerElementTangent.Create(fbxMesh, "tangents"); - layerElementTangent.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); - layerElementTangent.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); - CopyToFbx(layerElementTangent.GetDirectArray(), mesh.m_pool.m_Tangents); - layer0.SetTangents(layerElementTangent); - - // Compute and export binormals since Unity's FBX importer won't import the tangents without - // them, even though they're not used. - var layerElementBinormal = FbxLayerElementBinormal.Create(fbxMesh, "binormals"); - layerElementBinormal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); - layerElementBinormal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); - var binormals = mesh.m_pool.m_Tangents - .Select( (tan, idx) => { - var b3 = Vector3.Cross(tan, mesh.m_pool.m_Normals[idx]) * tan.w; - return new Vector4(b3.x, b3.y, b3.z, 1); - } ) - .ToList(); - CopyToFbx(layerElementBinormal.GetDirectArray(), binormals); - layer0.SetBinormals(layerElementBinormal); - - var layerElementMaterial = FbxLayerElementMaterial.Create(fbxMesh, "materials"); - layerElementMaterial.SetMappingMode(FbxLayerElement.EMappingMode.eAllSame); - layer0.SetMaterials(layerElementMaterial); - - // Export everything up to the last uvset containing data - // even if some intermediate uvsets have no data. - // Otherwise Unity will get the uvset numbering wrong on import - - List> uvSets = DemuxTexcoords(mesh.m_pool); - for (int i = 0; i < uvSets.Count; i++) { - FbxLayer layerN = fbxMesh.GetLayer(i); - while (layerN == null) { - fbxMesh.CreateLayer(); - layerN = fbxMesh.GetLayer(i); - } - var layerElementUV = FbxLayerElementUV.Create(fbxMesh, String.Format("uv{0}", i)); - layerElementUV.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); - layerElementUV.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); - - List uvSet = uvSets[i]; - if (uvSet == null) { - // Do nothing - // Replicates what the old fbx export code did; seems to work fine - } else { - Debug.Assert(uvSet.Count == nVerts); - CopyToFbx(layerElementUV.GetDirectArray(), uvSet); - } - - layerN.SetUVs(layerElementUV, FbxLayerElement.EType.eTextureDiffuse); - } - return fbxMesh; - } - - static void CopyToFbx(FbxLayerElementArrayTemplateFbxColor fbx, List unity) { - fbx.SetCount(unity.Count); - unsafe { - fixed (void* ptr = unity.GetBackingArray()) { - Globals.CopyColorToFbxColor(fbx, (IntPtr)ptr); - } - } - } - - static void CopyToFbx(FbxLayerElementArrayTemplateFbxVector2 fbx, List unity) { - fbx.SetCount(unity.Count); - unsafe { - fixed (void* ptr = unity.GetBackingArray()) { - Globals.CopyVector2ToFbxVector2(fbx, (IntPtr)ptr); - } - } - } - - static void CopyToFbx(FbxLayerElementArrayTemplateFbxVector4 fbx, List unity) { - fbx.SetCount(unity.Count); - unsafe { - fixed (void* ptr = unity.GetBackingArray()) { - Globals.CopyVector3ToFbxVector4(fbx, (IntPtr)ptr); - } - } - } - - static void CopyToFbx(FbxLayerElementArrayTemplateFbxVector4 fbx, List unity) { - fbx.SetCount(unity.Count); - unsafe { - fixed (void* ptr = unity.GetBackingArray()) { - Globals.CopyVector4ToFbxVector4(fbx, (IntPtr)ptr); - } - } - } - - // Fbx only supports 2-channel texcoord data; turn (up to) 2 float4s - // into (up to) 4 float2s. - // - // The resulting List will have no nulls at the end, but may have some - // gaps with missing data. - static List> DemuxTexcoords(GeometryPool pool) { - var allSets = new List>(); - { - List tmpXy, tmpZw; - DemuxTexcoord(pool, pool.Layout.texcoord0.size, pool.m_Texcoord0, out tmpXy, out tmpZw); - allSets.Add(tmpXy); - allSets.Add(tmpZw); - DemuxTexcoord(pool, pool.Layout.texcoord1.size, pool.m_Texcoord1, out tmpXy, out tmpZw); - allSets.Add(tmpXy); - allSets.Add(tmpZw); - } - // Remove unused sets from the end - while (allSets.Count > 0 && allSets[allSets.Count-1] == null) { - allSets.RemoveAt(allSets.Count-1); - } - return allSets; - } - - // Copy a 4-channel texcoord into 2 2-channel texcoords. - // If the source isn't 4-channel, one or both lists may be left empty. - static void DemuxTexcoord(GeometryPool pool, int uvSize, GeometryPool.TexcoordData texcoordData, - out List destXy, out List destZw) { - destXy = null; - destZw = null; - switch (uvSize) { - case 0: - break; - case 2: - destXy = texcoordData.v2; - break; - case 3: - destXy = new List(texcoordData.v3.Select(v3 => new Vector2(v3.x, v3.y))); - destZw = new List(texcoordData.v3.Select(v3 => new Vector2(v3.z, 0))); - break; - case 4: - destXy = new List(texcoordData.v4.Select(v4 => new Vector2(v4.x, v4.y))); - destZw = new List(texcoordData.v4.Select(v4 => new Vector2(v4.z, v4.w))); - break; - default: - Debug.Assert(false); - break; - } - } + // This writes out the local xform, and requires that parentNode use payload.instanceXform + static void ExportMeshPayload_Local( + FbxExportGlobals G, ModelMeshPayload payload, FbxNode parentNode) + { + // If these aren't unique, either FBX or Unity will uniquify them for us -- not sure which. + // So roll payload.id into the name. + FbxNode fbxNode = FbxNode.Create(G.m_manager, payload.nodeName); + fbxNode.SetLocalTransform(payload.localXform); + fbxNode.SetNodeAttribute(G.GetOrCreateFbxMesh(payload)); + fbxNode.AddMaterial(G.GetOrCreateFbxMaterial( + payload.MeshNamespace, payload.exportableMaterial)); + + parentNode.AddChild(fbxNode); + } + + internal static FbxSurfaceMaterial CreateFbxMaterial( + FbxExportGlobals G, string meshNamespace, IExportableMaterial exportableMaterial, + HashSet createdMaterialNames) + { + string materialName; + if (exportableMaterial is BrushDescriptor) + { + // Toolkit uses this guid (in "N" format) to look up a BrushDescriptor. + // See Toolkit's ModelImportSettings.GetDescriptorForStroke + materialName = $"{exportableMaterial.UniqueName:N}_{meshNamespace}_{exportableMaterial.DurableName}"; + } + else if (exportableMaterial is DynamicExportableMaterial dem) + { + // Comes from {fbx,obj,gltf,...} import from {Poly, Media Library} + // This is a customized version of a BrushDescriptor -- almost certainly + // Pbr{Blend,Opaque}{Double,Single}Sided with maybe an added texture and + // some of its params customized. + // TBT will merge the material created by Unity for this FbxMaterial with + // the premade material it has for the parent guid. + materialName = $"{dem.Parent.m_Guid:N}_{meshNamespace}_{dem.DurableName}"; + } + else + { + Debug.LogWarning($"Unknown class {exportableMaterial.GetType().Name}"); + materialName = $"{meshNamespace}_{exportableMaterial.DurableName}"; + } + // If only ExportFbx were a non-static class we could merge it with FbxExportGlobals + materialName = ExportUtils.CreateUniqueName(materialName, createdMaterialNames); + + FbxSurfaceLambert material = FbxSurfaceLambert.Create(G.m_scene, materialName); + + material.Ambient.Set(new FbxDouble3(0, 0, 0)); + material.Diffuse.Set(new FbxDouble3(1.0, 1.0, 1.0)); + if (exportableMaterial.EmissiveFactor > 0) + { + material.EmissiveFactor.Set(exportableMaterial.EmissiveFactor); + material.Emissive.Set(new FbxDouble3(1.0, 1.0, 1.0)); + } + if (exportableMaterial.BlendMode != ExportableMaterialBlendMode.None) + { + var blendMode = FbxProperty.Create(material, Globals.FbxStringDT, "BlendMode"); + switch (exportableMaterial.BlendMode) + { + case ExportableMaterialBlendMode.AlphaMask: + blendMode.SetString(new FbxString("AlphaMask")); + material.TransparencyFactor.Set(0.2); + break; + case ExportableMaterialBlendMode.AdditiveBlend: + blendMode.SetString(new FbxString("AdditiveBlend")); + break; + } + } + + // Export the texture + if (exportableMaterial.HasExportTexture()) + { + // This is not perfectly unique, but it is good enough for fbx export + // better would be to use _ but that's ugly, and nobody uses + // the textures anyway, so... let's leave well enough alone for now. + string albedoTextureName = exportableMaterial.DurableName; + var fullTextureDir = Path.Combine(G.m_outputDir, kRelativeTextureDir); + if (!Directory.Exists(fullTextureDir)) + { + if (!FileUtils.InitializeDirectoryWithUserError(fullTextureDir)) + { + throw new IOException("Cannot write textures"); + } + } + string src = exportableMaterial.GetExportTextureFilename(); + var textureFileName = albedoTextureName + ".png"; + var textureFilePath = Path.Combine(fullTextureDir, textureFileName); + FileInfo srcInfo = new FileInfo(src); + if (srcInfo.Exists && !new FileInfo(textureFilePath).Exists) + { + srcInfo.CopyTo(textureFilePath); + } + + FbxFileTexture texture = FbxFileTexture.Create(G.m_scene, albedoTextureName + "_texture"); + texture.SetFileName(textureFilePath); + texture.SetTextureUse(FbxTexture.ETextureUse.eStandard); + texture.SetMappingType(FbxTexture.EMappingType.eUV); + texture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); + texture.UVSet.Set(new FbxString("uv0")); + material.Diffuse.ConnectSrcObject(texture); + material.TransparentColor.ConnectSrcObject(texture); + } + else + { + foreach (var kvp in exportableMaterial.TextureUris) + { + string parameterName = kvp.Key; + string textureUri = kvp.Value; + if (ExportFileReference.IsHttp(textureUri)) + { + // fbx can't deal with http references to textures + continue; + } + ExportFileReference fileRef = ExportFileReference.GetOrCreateSafeLocal( + G.m_disambiguationContext, textureUri, exportableMaterial.UriBase, + $"{meshNamespace}_{Path.GetFileName(textureUri)}"); + AddTextureToMaterial(G, fileRef, material, parameterName); + } + } + return material; + } + + // Pass: + // parameterName - + // used for the FbxTexture name. Can be something arbitrary since as far as I know, + // the texture node's name is unused by importers. + private static void AddTextureToMaterial( + FbxExportGlobals G, + ExportFileReference fileRef, + FbxSurfaceLambert fbxMaterial, + string parameterName) + { + Debug.Assert(File.Exists(fileRef.m_originalLocation)); + + var destPath = Path.Combine(G.m_outputDir, fileRef.m_uri); + if (!File.Exists(destPath)) + { + if (!FileUtils.InitializeDirectoryWithUserError(Path.GetDirectoryName(destPath))) + { + return; + } + File.Copy(fileRef.m_originalLocation, destPath); + } + + // It's kind of weird that the parameter name is used for the texture node's name, + // but as far as I can tell nobody cares about that name, so whatever. + FbxFileTexture fbxTexture = FbxFileTexture.Create(G.m_scene, parameterName); + fbxTexture.SetFileName(destPath); + fbxTexture.SetTextureUse(FbxTexture.ETextureUse.eStandard); + fbxTexture.SetMappingType(FbxTexture.EMappingType.eUV); + fbxTexture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); + fbxTexture.UVSet.Set(new FbxString("uv0")); + // It's also weird that we only ever assign to the Diffuse slot. + // Shouldn't we be looking at the parameter name and assigning to Diffuse, Normal, etc + // based on what we see? + // TODO: check + fbxMaterial.Diffuse.ConnectSrcObject(fbxTexture); + fbxMaterial.TransparentColor.ConnectSrcObject(fbxTexture); + } + + // Returns the root, or a node right under the root. + // Either way, the transform stack is guaranteed to be identity. + static FbxNode GetGroupNode(FbxManager manager, FbxScene scene, UInt32 group) + { + FbxNode root = scene.GetRootNode(); + if (group == 0) + { + return root; + } + string childName = $"group_{group}"; + FbxNode child = root.FindChild(childName, false); + if (child == null) + { + child = FbxNode.Create(manager, childName); + root.AddChild(child); + } + return child; + } + + static void SetLocalTransform(this FbxNode node, TrTransform xf) + { + node.LclTranslation.Set(new FbxDouble3(xf.translation.x, xf.translation.y, xf.translation.z)); + node.LclRotation.Set(XYZEulerFromQuaternion(xf.rotation)); + node.LclScaling.Set(new FbxDouble3(xf.scale, xf.scale, xf.scale)); + } + + static void SetLocalTransform(this FbxNode node, Matrix4x4 xf) + { + node.SetLocalTransform(TrTransform.FromMatrix4x4(xf)); + } + + // outputFile must be a full path. + static void WriteObjectsAndConnections2(FbxExportGlobals G) + { + var payload = ExportCollector.GetExportPayload( + AxisConvention.kFbxAccordingToUnity, + includeLocalMediaContent: true); + + // Write out each brush entry's geometry. + foreach (var brushMeshPayload in payload.groups.SelectMany(g => g.brushMeshes)) + { + // This code used to not set the transform; check that it didn't cause issues + Debug.Assert(brushMeshPayload.xform.isIdentity); + FbxNode parentNode = GetGroupNode(G.m_manager, G.m_scene, brushMeshPayload.group); + ExportMeshPayload_Global(G, brushMeshPayload, parentNode); + } + + // Models with exportable meshes. + foreach (var sameInstance in payload.modelMeshes.GroupBy(m => (m.model, m.modelId))) + { + var modelMeshPayloads = sameInstance.ToList(); + if (modelMeshPayloads.Count == 0) { continue; } + + // All of these pieces will come from the same Widget and therefore will have + // the same group id, root transform, etc + var first = modelMeshPayloads[0]; + FbxNode parentParentNode = GetGroupNode(G.m_manager, G.m_scene, first.group); + string rootNodeName = $"model_{first.model.GetExportName()}_{first.modelId}"; + if (modelMeshPayloads.Count == 1 && first.localXform.isIdentity) + { + // Condense the two nodes into one; give the top-level node the same name + // it would have had had it been multi-level. + FbxNode newNode = ExportMeshPayload_Global(G, first, parentParentNode); + newNode.SetName(rootNodeName); + } + else + { + FbxNode parentNode = FbxNode.Create(G.m_manager, rootNodeName); + parentNode.SetLocalTransform(first.parentXform); + parentParentNode.AddChild(parentNode); + foreach (var modelMeshPayload in modelMeshPayloads) + { + ExportMeshPayload_Local(G, modelMeshPayload, parentNode); + } + } + } + + foreach (ImageQuadPayload meshPayload in payload.imageQuads) + { + FbxNode groupNode = GetGroupNode(G.m_manager, G.m_scene, meshPayload.group); + ExportMeshPayload_Global(G, meshPayload, groupNode); + } + + // Things that can only be exported as transforms (videos, images, models, ...) + foreach (var referenceThing in payload.referenceThings) + { + FbxNode node = FbxNode.Create(G.m_manager, "reference_" + referenceThing.name); + node.SetLocalTransform(referenceThing.xform); + GetGroupNode(G.m_manager, G.m_scene, referenceThing.group).AddChild(node); + } + } + + public static FbxDouble3 XYZEulerFromQuaternion(Quaternion rotation) + { + // Unity wrappers don't have FbxVector4::SetXYZ(FbxQuaternion) to convert quat -> xyz euler. + // We can abuse FbxAMatrix to do the same thing. + + FbxQuaternion fbxQuaternion = new FbxQuaternion(rotation.x, rotation.y, rotation.z, rotation.w); + // We're using the FBX API to do the conversion to XYZ eulers. + var mat = new FbxAMatrix(); + mat.SetIdentity(); + mat.SetQ(fbxQuaternion); + // "The returned rotation vector is in Euler angle and the rotation order is XYZ." + FbxVector4 v4 = mat.GetR(); + return new FbxDouble3(v4.X, v4.Y, v4.Z); + } + + // For use only by FbxExportGlobals. + internal static FbxMesh CreateFbxMesh(FbxExportGlobals G, GeometryPool pool, string poolName) + { + FbxMesh fbxMesh = FbxMesh.Create(G.m_manager, poolName); + + ExportMesh mesh = new ExportMesh(pool); + int nVerts = mesh.m_pool.m_Vertices.Count; + fbxMesh.InitControlPoints(nVerts); + + unsafe + { + fixed (Vector3* f = mesh.m_pool.m_Vertices.GetBackingArray()) + { + Globals.SetControlPoints(fbxMesh, (IntPtr)f); + } + } + + List triangles = mesh.m_pool.m_Tris; + // Not available in Unity's wrappers + // fbxMesh.ReservePolygonCount(triangles.Count / 3); + // fbxMesh.ReservePolygonVertexCount(triangles.Count); + for (int i = 0; i < triangles.Count; i += 3) + { + fbxMesh.BeginPolygon(-1 /* Material */, -1 /* Texture */, -1 /* Group */, false /* Legacy */); + fbxMesh.AddPolygon(triangles[i]); + fbxMesh.AddPolygon(triangles[i + 1]); + fbxMesh.AddPolygon(triangles[i + 2]); + fbxMesh.EndPolygon(); + } + + FbxLayer layer0 = fbxMesh.GetLayer(0); + if (layer0 == null) + { + fbxMesh.CreateLayer(); + layer0 = fbxMesh.GetLayer(0); + } + + var layerElementNormal = FbxLayerElementNormal.Create(fbxMesh, "normals"); + layerElementNormal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); + layerElementNormal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); + CopyToFbx(layerElementNormal.GetDirectArray(), mesh.m_pool.m_Normals); + layer0.SetNormals(layerElementNormal); + + var layerElementColor = FbxLayerElementVertexColor.Create(fbxMesh, "color"); + layerElementColor.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); + layerElementColor.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); + CopyToFbx(layerElementColor.GetDirectArray(), mesh.m_linearColor); + layer0.SetVertexColors(layerElementColor); + + var layerElementTangent = FbxLayerElementTangent.Create(fbxMesh, "tangents"); + layerElementTangent.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); + layerElementTangent.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); + CopyToFbx(layerElementTangent.GetDirectArray(), mesh.m_pool.m_Tangents); + layer0.SetTangents(layerElementTangent); + + // Compute and export binormals since Unity's FBX importer won't import the tangents without + // them, even though they're not used. + var layerElementBinormal = FbxLayerElementBinormal.Create(fbxMesh, "binormals"); + layerElementBinormal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); + layerElementBinormal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); + var binormals = mesh.m_pool.m_Tangents + .Select((tan, idx) => + { + var b3 = Vector3.Cross(tan, mesh.m_pool.m_Normals[idx]) * tan.w; + return new Vector4(b3.x, b3.y, b3.z, 1); + }) + .ToList(); + CopyToFbx(layerElementBinormal.GetDirectArray(), binormals); + layer0.SetBinormals(layerElementBinormal); + + var layerElementMaterial = FbxLayerElementMaterial.Create(fbxMesh, "materials"); + layerElementMaterial.SetMappingMode(FbxLayerElement.EMappingMode.eAllSame); + layer0.SetMaterials(layerElementMaterial); + + // Export everything up to the last uvset containing data + // even if some intermediate uvsets have no data. + // Otherwise Unity will get the uvset numbering wrong on import + + List> uvSets = DemuxTexcoords(mesh.m_pool); + for (int i = 0; i < uvSets.Count; i++) + { + FbxLayer layerN = fbxMesh.GetLayer(i); + while (layerN == null) + { + fbxMesh.CreateLayer(); + layerN = fbxMesh.GetLayer(i); + } + var layerElementUV = FbxLayerElementUV.Create(fbxMesh, String.Format("uv{0}", i)); + layerElementUV.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); + layerElementUV.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); + + List uvSet = uvSets[i]; + if (uvSet == null) + { + // Do nothing + // Replicates what the old fbx export code did; seems to work fine + } + else + { + Debug.Assert(uvSet.Count == nVerts); + CopyToFbx(layerElementUV.GetDirectArray(), uvSet); + } + + layerN.SetUVs(layerElementUV, FbxLayerElement.EType.eTextureDiffuse); + } + return fbxMesh; + } + + static void CopyToFbx(FbxLayerElementArrayTemplateFbxColor fbx, List unity) + { + fbx.SetCount(unity.Count); + unsafe + { + fixed (void* ptr = unity.GetBackingArray()) + { + Globals.CopyColorToFbxColor(fbx, (IntPtr)ptr); + } + } + } + + static void CopyToFbx(FbxLayerElementArrayTemplateFbxVector2 fbx, List unity) + { + fbx.SetCount(unity.Count); + unsafe + { + fixed (void* ptr = unity.GetBackingArray()) + { + Globals.CopyVector2ToFbxVector2(fbx, (IntPtr)ptr); + } + } + } + + static void CopyToFbx(FbxLayerElementArrayTemplateFbxVector4 fbx, List unity) + { + fbx.SetCount(unity.Count); + unsafe + { + fixed (void* ptr = unity.GetBackingArray()) + { + Globals.CopyVector3ToFbxVector4(fbx, (IntPtr)ptr); + } + } + } + + static void CopyToFbx(FbxLayerElementArrayTemplateFbxVector4 fbx, List unity) + { + fbx.SetCount(unity.Count); + unsafe + { + fixed (void* ptr = unity.GetBackingArray()) + { + Globals.CopyVector4ToFbxVector4(fbx, (IntPtr)ptr); + } + } + } + + // Fbx only supports 2-channel texcoord data; turn (up to) 2 float4s + // into (up to) 4 float2s. + // + // The resulting List will have no nulls at the end, but may have some + // gaps with missing data. + static List> DemuxTexcoords(GeometryPool pool) + { + var allSets = new List>(); + { + List tmpXy, tmpZw; + DemuxTexcoord(pool, pool.Layout.texcoord0.size, pool.m_Texcoord0, out tmpXy, out tmpZw); + allSets.Add(tmpXy); + allSets.Add(tmpZw); + DemuxTexcoord(pool, pool.Layout.texcoord1.size, pool.m_Texcoord1, out tmpXy, out tmpZw); + allSets.Add(tmpXy); + allSets.Add(tmpZw); + } + // Remove unused sets from the end + while (allSets.Count > 0 && allSets[allSets.Count - 1] == null) + { + allSets.RemoveAt(allSets.Count - 1); + } + return allSets; + } + + // Copy a 4-channel texcoord into 2 2-channel texcoords. + // If the source isn't 4-channel, one or both lists may be left empty. + static void DemuxTexcoord(GeometryPool pool, int uvSize, GeometryPool.TexcoordData texcoordData, + out List destXy, out List destZw) + { + destXy = null; + destZw = null; + switch (uvSize) + { + case 0: + break; + case 2: + destXy = texcoordData.v2; + break; + case 3: + destXy = new List(texcoordData.v3.Select(v3 => new Vector2(v3.x, v3.y))); + destZw = new List(texcoordData.v3.Select(v3 => new Vector2(v3.z, 0))); + break; + case 4: + destXy = new List(texcoordData.v4.Select(v4 => new Vector2(v4.x, v4.y))); + destZw = new List(texcoordData.v4.Select(v4 => new Vector2(v4.z, v4.w))); + break; + default: + Debug.Assert(false); + break; + } + } -} + } } // namespace TiltBrush #endif diff --git a/Assets/Scripts/Export/FbxUtils.cs b/Assets/Scripts/Export/FbxUtils.cs index 76be7e069d..e28d6c7c2e 100644 --- a/Assets/Scripts/Export/FbxUtils.cs +++ b/Assets/Scripts/Export/FbxUtils.cs @@ -55,61 +55,69 @@ public static void ApplyFbxTexcoordHack(GeometryPool pool) } #if FBX_SUPPORTED - // FbxDouble3 - - public static Vector3 ToUVector3(this FbxDouble3 d) { - return new Vector3((float)d.X, (float)d.Y, (float)d.Z); - } - - // FbxVector4 - - public static Vector3 ToUVector3(this FbxVector4 d) { - return new Vector3((float)d.X, (float)d.Y, (float)d.Z); - } - - public static Vector4 ToUVector4(this FbxVector4 d) { - return new Vector4((float)d.X, (float)d.Y, (float)d.Z, (float)d.W); - } - - // FbxDouble4 - - public static Vector3 ToUVector3(this FbxDouble4 d) { - return new Vector3((float)d.X, (float)d.Y, (float)d.Z); - } - - public static Vector4 ToUVector4(this FbxDouble4 d) { - return new Vector4((float)d.X, (float)d.Y, (float)d.Z, (float)d.W); - } - - // FbxQuaternion - - public static Quaternion ToUQuaternion(this FbxQuaternion fbx) { - var q = new Quaternion(); - // the indexing order of FbxQuaternion is undocumented; w=3 - // was determined empirically. - q.x = (float)fbx.GetAt(0); - q.y = (float)fbx.GetAt(1); - q.z = (float)fbx.GetAt(2); - q.w = (float)fbx.GetAt(3); - return q; - } - - public static FbxQuaternion ToFbxQuaternion(this Quaternion q) { - return new FbxQuaternion(q.x, q.y, q.z, q.w); - } - - // FbxAMatrix - - /// Does not do any coordinate-convention switching. - public static void ToTRS( - this FbxAMatrix input, - out Vector3 translation, - out Quaternion rotation, - out Vector3 scale) { - translation = input.GetT().ToUVector3(); - rotation = input.GetQ().ToUQuaternion(); - scale = input.GetS().ToUVector3(); - } + // FbxDouble3 + + public static Vector3 ToUVector3(this FbxDouble3 d) + { + return new Vector3((float)d.X, (float)d.Y, (float)d.Z); + } + + // FbxVector4 + + public static Vector3 ToUVector3(this FbxVector4 d) + { + return new Vector3((float)d.X, (float)d.Y, (float)d.Z); + } + + public static Vector4 ToUVector4(this FbxVector4 d) + { + return new Vector4((float)d.X, (float)d.Y, (float)d.Z, (float)d.W); + } + + // FbxDouble4 + + public static Vector3 ToUVector3(this FbxDouble4 d) + { + return new Vector3((float)d.X, (float)d.Y, (float)d.Z); + } + + public static Vector4 ToUVector4(this FbxDouble4 d) + { + return new Vector4((float)d.X, (float)d.Y, (float)d.Z, (float)d.W); + } + + // FbxQuaternion + + public static Quaternion ToUQuaternion(this FbxQuaternion fbx) + { + var q = new Quaternion(); + // the indexing order of FbxQuaternion is undocumented; w=3 + // was determined empirically. + q.x = (float)fbx.GetAt(0); + q.y = (float)fbx.GetAt(1); + q.z = (float)fbx.GetAt(2); + q.w = (float)fbx.GetAt(3); + return q; + } + + public static FbxQuaternion ToFbxQuaternion(this Quaternion q) + { + return new FbxQuaternion(q.x, q.y, q.z, q.w); + } + + // FbxAMatrix + + /// Does not do any coordinate-convention switching. + public static void ToTRS( + this FbxAMatrix input, + out Vector3 translation, + out Quaternion rotation, + out Vector3 scale) + { + translation = input.GetT().ToUVector3(); + rotation = input.GetQ().ToUQuaternion(); + scale = input.GetS().ToUVector3(); + } #endif } diff --git a/Assets/Scripts/Export/ImportMaterialCollector.cs b/Assets/Scripts/Export/ImportMaterialCollector.cs index 3676b737c4..c3eb7ae532 100644 --- a/Assets/Scripts/Export/ImportMaterialCollector.cs +++ b/Assets/Scripts/Export/ImportMaterialCollector.cs @@ -67,29 +67,32 @@ public void AddSvgIem(Material unityMaterial) } #if FBX_SUPPORTED - // Used for FBX imports - public void Add( - Material unityMaterial, - bool transparent, string baseColorUri, FbxSurfaceLambert fbxMaterial) { - if (baseColorUri != null) { - Debug.Assert(File.Exists(Path.Combine(m_AssetLocation, baseColorUri))); - } + // Used for FBX imports + public void Add( + Material unityMaterial, + bool transparent, string baseColorUri, FbxSurfaceLambert fbxMaterial) + { + if (baseColorUri != null) + { + Debug.Assert(File.Exists(Path.Combine(m_AssetLocation, baseColorUri))); + } - TbtSettings.PbrMaterialInfo pbrInfo = transparent - ? TbtSettings.Instance.m_PbrBlendDoubleSided - : TbtSettings.Instance.m_PbrOpaqueDoubleSided; - - m_MaterialToIem.Add( - unityMaterial, - new DynamicExportableMaterial( - parent: pbrInfo.descriptor, - durableName: fbxMaterial.GetName(), - uniqueName: MakeDeterministicUniqueName(m_numAdded++, fbxMaterial.GetName()), - uriBase: m_AssetLocation) { - BaseColorFactor = unityMaterial.GetColor("_Color"), - BaseColorTex = baseColorUri, - }); - } + TbtSettings.PbrMaterialInfo pbrInfo = transparent + ? TbtSettings.Instance.m_PbrBlendDoubleSided + : TbtSettings.Instance.m_PbrOpaqueDoubleSided; + + m_MaterialToIem.Add( + unityMaterial, + new DynamicExportableMaterial( + parent: pbrInfo.descriptor, + durableName: fbxMaterial.GetName(), + uniqueName: MakeDeterministicUniqueName(m_numAdded++, fbxMaterial.GetName()), + uriBase: m_AssetLocation) + { + BaseColorFactor = unityMaterial.GetColor("_Color"), + BaseColorTex = baseColorUri, + }); + } #endif // Used for GLTFast diff --git a/Assets/Scripts/FbxReader.cs b/Assets/Scripts/FbxReader.cs index 1990608537..a5f4f36da7 100644 --- a/Assets/Scripts/FbxReader.cs +++ b/Assets/Scripts/FbxReader.cs @@ -24,580 +24,681 @@ using FbxLayerElementArray_int = Autodesk.Fbx.FbxLayerElementArrayTemplateInt; using FbxLayerElementArray_FbxVector4 = Autodesk.Fbx.FbxLayerElementArrayTemplateFbxVector4; using FbxLayerElementArray_FbxVector2 = Autodesk.Fbx.FbxLayerElementArrayTemplateFbxVector2; -namespace TiltBrush { - -/** - * Read models into Unity meshes using the FBX SDK. - * - * TODO: - * - Separate out loading from building unity objects so that it can be multi-threaded. - */ -public class FbxReader { - public const int MAX_VERTS_PER_MESH = 65534; - - private readonly Material m_standardMaterial; - private readonly Material m_transparentMaterial; - private readonly string m_path; // Full path to file - private readonly string m_dir; // directory of file - private readonly List m_warnings = new List(); - private readonly ImportMaterialCollector m_collector; - - private List warnings => m_warnings; - - public FbxReader(string path) { - m_standardMaterial = ModelCatalog.m_Instance.m_ObjLoaderStandardMaterial; - m_transparentMaterial = ModelCatalog.m_Instance.m_ObjLoaderTransparentMaterial; - m_path = path; - m_dir = Path.GetDirectoryName(path); - m_collector = new ImportMaterialCollector(m_dir, m_path); - } - - public (GameObject, List warnings, ImportMaterialCollector) Import() { - FbxManager fbxManager = FbxManager.Create(); - FbxIOSettings ioSettings = FbxIOSettings.Create(fbxManager, Globals.IOSROOT); - fbxManager.SetIOSettings(ioSettings); - FbxImporter fbxImporter = FbxImporter.Create(fbxManager, ""); - if (!fbxImporter.Initialize(m_path, -1, ioSettings)) { - warnings.Add("Failed to initialize FBX importer"); - return (null, warnings, null); - } - FbxScene scene = FbxScene.Create(fbxManager, "scene"); - fbxImporter.Import(scene); - - FbxNode root = scene.GetRootNode(); - SetPivots(root); - root.ConvertPivotAnimationRecursive(null, FbxNode.EPivotSet.eDestinationPivot, 30); - long totalVerts = GetTotalVerts(root); - long completedVerts = 0; - - float fbxUnitToTiltUnit; { - var unit = scene.GetGlobalSettings().GetSystemUnit(); - if (Path.GetExtension(m_path).ToLower() == ".obj") { - // Obj doesn't specify units. We'd rather assume m, but fbx assumes cm. - unit = FbxSystemUnit.m; - } - fbxUnitToTiltUnit = (float)unit.GetConversionFactorTo(FbxSystemUnit.m) - * App.METERS_TO_UNITS; - } +namespace TiltBrush +{ + + /** + * Read models into Unity meshes using the FBX SDK. + * + * TODO: + * - Separate out loading from building unity objects so that it can be multi-threaded. + */ + public class FbxReader + { + public const int MAX_VERTS_PER_MESH = 65534; + + private readonly Material m_standardMaterial; + private readonly Material m_transparentMaterial; + private readonly string m_path; // Full path to file + private readonly string m_dir; // directory of file + private readonly List m_warnings = new List(); + private readonly ImportMaterialCollector m_collector; + + private List warnings => m_warnings; + + public FbxReader(string path) + { + m_standardMaterial = ModelCatalog.m_Instance.m_ObjLoaderStandardMaterial; + m_transparentMaterial = ModelCatalog.m_Instance.m_ObjLoaderTransparentMaterial; + m_path = path; + m_dir = Path.GetDirectoryName(path); + m_collector = new ImportMaterialCollector(m_dir, m_path); + } - GameObject go = ImportNodes( - root, fbxUnitToTiltUnit, ref completedVerts, totalVerts); - Debug.Assert(completedVerts == totalVerts); - fbxImporter.Destroy(); - ioSettings.Destroy(); - fbxManager.Destroy(); - - return (go, warnings.Distinct().ToList(), m_collector); - } - - private static long GetTotalVerts(FbxNode node) { - FbxNodeAttribute a = node.GetNodeAttribute(); - int nChildren = node.GetChildCount(); - long vertCount = 0; - if (a != null) { - var attrType = a.GetAttributeType(); - if (attrType == FbxNodeAttribute.EType.eMesh) { - FbxMesh fbxMesh = node.GetMesh(); - fbxMesh.SplitPoints(); - vertCount = fbxMesh.GetControlPointsCount(); - } - } - for (int i = 0; i < nChildren; i++) { - vertCount += GetTotalVerts(node.GetChild(i)); - } - return vertCount; - } - - private GameObject ImportNodes( - FbxNode node, float fbxUnitToTiltUnit, - ref long completedVerts, long totalVerts) { - FbxNodeAttribute a = node.GetNodeAttribute(); - int nChildren = node.GetChildCount(); - - GameObject go = null; - if (a != null) { - var attrType = a.GetAttributeType(); - if (attrType == FbxNodeAttribute.EType.eMesh) { - go = ImportMesh( - node, fbxUnitToTiltUnit, - ref completedVerts, totalVerts); - } else if (attrType == FbxNodeAttribute.EType.eNurbs || - attrType == FbxNodeAttribute.EType.eSubDiv || - attrType == FbxNodeAttribute.EType.eNurbsSurface) { - warnings.Add("Ignoring non-mesh geometry"); - } - } + public (GameObject, List warnings, ImportMaterialCollector) Import() + { + FbxManager fbxManager = FbxManager.Create(); + FbxIOSettings ioSettings = FbxIOSettings.Create(fbxManager, Globals.IOSROOT); + fbxManager.SetIOSettings(ioSettings); + FbxImporter fbxImporter = FbxImporter.Create(fbxManager, ""); + if (!fbxImporter.Initialize(m_path, -1, ioSettings)) + { + warnings.Add("Failed to initialize FBX importer"); + return (null, warnings, null); + } + FbxScene scene = FbxScene.Create(fbxManager, "scene"); + fbxImporter.Import(scene); + + FbxNode root = scene.GetRootNode(); + SetPivots(root); + root.ConvertPivotAnimationRecursive(null, FbxNode.EPivotSet.eDestinationPivot, 30); + long totalVerts = GetTotalVerts(root); + long completedVerts = 0; + + float fbxUnitToTiltUnit; + { + var unit = scene.GetGlobalSettings().GetSystemUnit(); + if (Path.GetExtension(m_path).ToLower() == ".obj") + { + // Obj doesn't specify units. We'd rather assume m, but fbx assumes cm. + unit = FbxSystemUnit.m; + } + fbxUnitToTiltUnit = (float)unit.GetConversionFactorTo(FbxSystemUnit.m) + * App.METERS_TO_UNITS; + } - for (int i = 0; i < nChildren; i++) { - GameObject child = ImportNodes( - node.GetChild(i), fbxUnitToTiltUnit, - ref completedVerts, totalVerts); - if (child != null) { - if (go == null) { - go = new GameObject("Node"); + GameObject go = ImportNodes( + root, fbxUnitToTiltUnit, ref completedVerts, totalVerts); + Debug.Assert(completedVerts == totalVerts); + fbxImporter.Destroy(); + ioSettings.Destroy(); + fbxManager.Destroy(); + + return (go, warnings.Distinct().ToList(), m_collector); } - child.transform.parent = go.transform; - } - } - if (go != null) { - ApplyTransform(node, go.transform, fbxUnitToTiltUnit); - } - return go; - } - - // Currently this always creates a new material, but - // TODO: Cache materials for reuse across meshes - (Material mat, float alpha) CreateMaterial(FbxSurfaceMaterial fbxMaterial) { - FbxSurfaceLambert l = FbxSurfaceLambert.fromMaterial(fbxMaterial); - // Watch out for corrupt or unknown materials - if (l == null) { - return (UObject.Instantiate(m_standardMaterial), 1f); - } + private static long GetTotalVerts(FbxNode node) + { + FbxNodeAttribute a = node.GetNodeAttribute(); + int nChildren = node.GetChildCount(); + long vertCount = 0; + if (a != null) + { + var attrType = a.GetAttributeType(); + if (attrType == FbxNodeAttribute.EType.eMesh) + { + FbxMesh fbxMesh = node.GetMesh(); + fbxMesh.SplitPoints(); + vertCount = fbxMesh.GetControlPointsCount(); + } + } + for (int i = 0; i < nChildren; i++) + { + vertCount += GetTotalVerts(node.GetChild(i)); + } + return vertCount; + } - // We only use the red channel from the transparency color - Vector3 tc = l.TransparentColor.Get().ToUVector3(); - float alpha = 1 - tc.x * (float)l.TransparencyFactor.Get(); - Vector3 diffuse = l.Diffuse.Get().ToUVector3(); - diffuse *= (float)l.DiffuseFactor.Get(); - Vector3 emission = l.Emissive.Get().ToUVector3(); - emission *= (float)l.EmissiveFactor.Get(); - bool transparent = (alpha < 1); - - Material mat = UObject.Instantiate(transparent ? m_transparentMaterial : m_standardMaterial); - mat.SetColor("_Color", new Color(diffuse.x, diffuse.y, diffuse.z, Mathf.Min(1f, alpha))); - mat.SetColor("_EmissionColor", new Color(emission.x, emission.y, emission.z)); - - string baseColorUri = null; - if (l.Diffuse.GetSrcObjectCount() > 0) { - baseColorUri = LoadTexture(l.Diffuse, mat, "_MainTex", true); - } - if (l.NormalMap.GetSrcObjectCount() > 0) { - LoadTexture(l.NormalMap, mat, "_BumpMap", false); - mat.EnableKeyword("_NORMALMAP"); - } + private GameObject ImportNodes( + FbxNode node, float fbxUnitToTiltUnit, + ref long completedVerts, long totalVerts) + { + FbxNodeAttribute a = node.GetNodeAttribute(); + int nChildren = node.GetChildCount(); + + GameObject go = null; + if (a != null) + { + var attrType = a.GetAttributeType(); + if (attrType == FbxNodeAttribute.EType.eMesh) + { + go = ImportMesh( + node, fbxUnitToTiltUnit, + ref completedVerts, totalVerts); + } + else if (attrType == FbxNodeAttribute.EType.eNurbs || + attrType == FbxNodeAttribute.EType.eSubDiv || + attrType == FbxNodeAttribute.EType.eNurbsSurface) + { + warnings.Add("Ignoring non-mesh geometry"); + } + } - m_collector.Add(mat, transparent, baseColorUri, l); + for (int i = 0; i < nChildren; i++) + { + GameObject child = ImportNodes( + node.GetChild(i), fbxUnitToTiltUnit, + ref completedVerts, totalVerts); + if (child != null) + { + if (go == null) + { + go = new GameObject("Node"); + } + child.transform.parent = go.transform; + } + } - return (mat, alpha); - } + if (go != null) + { + ApplyTransform(node, go.transform, fbxUnitToTiltUnit); + } + return go; + } - private GameObject ImportMesh( - FbxNode node, float fbxUnitToTiltUnit, - ref long completedVerts, long totalVerts) { - FbxMesh fbxMesh = node.GetMesh(); + // Currently this always creates a new material, but + // TODO: Cache materials for reuse across meshes + (Material mat, float alpha) CreateMaterial(FbxSurfaceMaterial fbxMaterial) + { + FbxSurfaceLambert l = FbxSurfaceLambert.fromMaterial(fbxMaterial); + // Watch out for corrupt or unknown materials + if (l == null) + { + return (UObject.Instantiate(m_standardMaterial), 1f); + } - Debug.Assert(totalVerts != 0); - // fbxMesh.SplitPoints(); + // We only use the red channel from the transparency color + Vector3 tc = l.TransparentColor.Get().ToUVector3(); + float alpha = 1 - tc.x * (float)l.TransparencyFactor.Get(); + Vector3 diffuse = l.Diffuse.Get().ToUVector3(); + diffuse *= (float)l.DiffuseFactor.Get(); + Vector3 emission = l.Emissive.Get().ToUVector3(); + emission *= (float)l.EmissiveFactor.Get(); + bool transparent = (alpha < 1); + + Material mat = UObject.Instantiate(transparent ? m_transparentMaterial : m_standardMaterial); + mat.SetColor("_Color", new Color(diffuse.x, diffuse.y, diffuse.z, Mathf.Min(1f, alpha))); + mat.SetColor("_EmissionColor", new Color(emission.x, emission.y, emission.z)); + + string baseColorUri = null; + if (l.Diffuse.GetSrcObjectCount() > 0) + { + baseColorUri = LoadTexture(l.Diffuse, mat, "_MainTex", true); + } + if (l.NormalMap.GetSrcObjectCount() > 0) + { + LoadTexture(l.NormalMap, mat, "_BumpMap", false); + mat.EnableKeyword("_NORMALMAP"); + } - // fbxMesh must call SplitPoints before this. A non-zero total vert count is a proxy for - // fbxMesh.SplitPoints() having previously been called through GetTotalVerts() - int nVerts = fbxMesh.GetControlPointsCount(); + m_collector.Add(mat, transparent, baseColorUri, l); - fbxMesh.ComputeBBox(); + return (mat, alpha); + } - // Note that converting coordinate systems may cause some of the "max" components - // to actually be min, and vice versa. Thus we simply encapsulate the 2 points. - Bounds b; { - Vector3 va = ToUnityPosition(fbxMesh.BBoxMin.Get()) * fbxUnitToTiltUnit; - Vector3 vb = ToUnityPosition(fbxMesh.BBoxMax.Get()) * fbxUnitToTiltUnit; - b = new Bounds(va, Vector3.zero); - b.Encapsulate(vb); - } + private GameObject ImportMesh( + FbxNode node, float fbxUnitToTiltUnit, + ref long completedVerts, long totalVerts) + { + FbxMesh fbxMesh = node.GetMesh(); + + Debug.Assert(totalVerts != 0); + // fbxMesh.SplitPoints(); + + // fbxMesh must call SplitPoints before this. A non-zero total vert count is a proxy for + // fbxMesh.SplitPoints() having previously been called through GetTotalVerts() + int nVerts = fbxMesh.GetControlPointsCount(); + + fbxMesh.ComputeBBox(); + + // Note that converting coordinate systems may cause some of the "max" components + // to actually be min, and vice versa. Thus we simply encapsulate the 2 points. + Bounds b; + { + Vector3 va = ToUnityPosition(fbxMesh.BBoxMin.Get()) * fbxUnitToTiltUnit; + Vector3 vb = ToUnityPosition(fbxMesh.BBoxMax.Get()) * fbxUnitToTiltUnit; + b = new Bounds(va, Vector3.zero); + b.Encapsulate(vb); + } - Vector3[] verts = new Vector3[nVerts]; - unsafe { - fixed (Vector3* f = verts) { - Globals.GetControlPoints(fbxMesh, (IntPtr)f); - } - } - for (int i = 0; i < nVerts; i++) { - verts[i] = ExportFbx.UnityFromFbx.MultiplyVector(verts[i]) * fbxUnitToTiltUnit; - } + Vector3[] verts = new Vector3[nVerts]; + unsafe + { + fixed (Vector3* f = verts) + { + Globals.GetControlPoints(fbxMesh, (IntPtr)f); + } + } + for (int i = 0; i < nVerts; i++) + { + verts[i] = ExportFbx.UnityFromFbx.MultiplyVector(verts[i]) * fbxUnitToTiltUnit; + } - Vector3[] normals = null; - bool degenerateNormals = false; - Vector2[] uvs = null; - FbxLayerElementArray_int materialIndices = null; - - if (fbxMesh.GetLayerCount() > 0) { - FbxLayer layer = fbxMesh.GetLayer(0); - - // Normals - FbxLayerElementNormal layerElementNormal = layer.GetNormals(); - if (layerElementNormal != null) { - if (layerElementNormal.GetMappingMode() == FbxLayerElement.EMappingMode.eByControlPoint) { - FbxLayerElementArray_FbxVector4 fbxNormals = layerElementNormal.GetDirectArray(); - int n = fbxNormals.GetCount(); - normals = new Vector3[n]; - unsafe { - fixed(Vector3* f = normals) { - Globals.CopyFbxVector4ToVector3(fbxNormals, (IntPtr)f); - } - } - for (int i = 0; i < n; i++) { - // Models from Blocks can have zero'd normals; in this case we ignore them and have - // Unity compute them. - if (normals[i] == Vector3.zero) { - degenerateNormals = true; - break; - } - normals[i] = ExportFbx.UnityFromFbx.MultiplyVector(normals[i]); - } - if (!degenerateNormals && - layerElementNormal.GetReferenceMode() - == FbxLayerElement.EReferenceMode.eIndexToDirect) { - Vector3[] vNormals = new Vector3[nVerts]; - FbxLayerElementArray_int indices = layerElementNormal.GetIndexArray(); - for (int j = 0; j < nVerts; j++) { - int i = indices.GetAt(j); - if (i < 0 || i > normals.Length) { - Debug.Log("Bad FBX normals index"); - continue; - } - vNormals[j] = normals[i]; - } - normals = vNormals; - } - } else { - warnings.Add("Can only import per-vertex normals"); - } - } - - // UVs - FbxLayerElementUV layerElementUV = layer.GetUVs(); - if (layerElementUV != null) { - if (layerElementUV.GetMappingMode() == FbxLayerElement.EMappingMode.eByControlPoint) { - FbxLayerElementArray_FbxVector2 uv = layerElementUV.GetDirectArray(); - int nUVs = uv.GetCount(); - uvs = new Vector2[nUVs]; - unsafe { - fixed(Vector2 *f = uvs) { - Globals.CopyFbxVector2ToVector2(uv, (IntPtr)f); - } - } - if (layerElementUV.GetReferenceMode() == FbxLayerElement.EReferenceMode.eIndexToDirect) { - Vector2[] vUvs = new Vector2[nVerts]; - FbxLayerElementArray_int indices = layerElementUV.GetIndexArray(); - for (int j = 0; j < nVerts; j++) { - int i = indices.GetAt(j); - if (i < 0 || i > uvs.Length) { - Debug.Log("Bad FBX UVs index"); - } - vUvs[j] = uvs[i]; - } - uvs = vUvs; - } - } - } - - FbxLayerElementMaterial layerElementMaterial = layer.GetMaterials(); - if (layerElementMaterial != null - && layerElementMaterial.GetMappingMode() == FbxLayerElement.EMappingMode.eByPolygon) { - materialIndices = layerElementMaterial.GetIndexArray(); - } - - // Warn about layers we don't support -- requires sdk support for holes - // if (layer.GetHole() != null) { - // warnings.Add("Ignoring unsupported holes"); - // } - } + Vector3[] normals = null; + bool degenerateNormals = false; + Vector2[] uvs = null; + FbxLayerElementArray_int materialIndices = null; + + if (fbxMesh.GetLayerCount() > 0) + { + FbxLayer layer = fbxMesh.GetLayer(0); + + // Normals + FbxLayerElementNormal layerElementNormal = layer.GetNormals(); + if (layerElementNormal != null) + { + if (layerElementNormal.GetMappingMode() == FbxLayerElement.EMappingMode.eByControlPoint) + { + FbxLayerElementArray_FbxVector4 fbxNormals = layerElementNormal.GetDirectArray(); + int n = fbxNormals.GetCount(); + normals = new Vector3[n]; + unsafe + { + fixed (Vector3* f = normals) + { + Globals.CopyFbxVector4ToVector3(fbxNormals, (IntPtr)f); + } + } + for (int i = 0; i < n; i++) + { + // Models from Blocks can have zero'd normals; in this case we ignore them and have + // Unity compute them. + if (normals[i] == Vector3.zero) + { + degenerateNormals = true; + break; + } + normals[i] = ExportFbx.UnityFromFbx.MultiplyVector(normals[i]); + } + if (!degenerateNormals && + layerElementNormal.GetReferenceMode() + == FbxLayerElement.EReferenceMode.eIndexToDirect) + { + Vector3[] vNormals = new Vector3[nVerts]; + FbxLayerElementArray_int indices = layerElementNormal.GetIndexArray(); + for (int j = 0; j < nVerts; j++) + { + int i = indices.GetAt(j); + if (i < 0 || i > normals.Length) + { + Debug.Log("Bad FBX normals index"); + continue; + } + vNormals[j] = normals[i]; + } + normals = vNormals; + } + } + else + { + warnings.Add("Can only import per-vertex normals"); + } + } + + // UVs + FbxLayerElementUV layerElementUV = layer.GetUVs(); + if (layerElementUV != null) + { + if (layerElementUV.GetMappingMode() == FbxLayerElement.EMappingMode.eByControlPoint) + { + FbxLayerElementArray_FbxVector2 uv = layerElementUV.GetDirectArray(); + int nUVs = uv.GetCount(); + uvs = new Vector2[nUVs]; + unsafe + { + fixed (Vector2* f = uvs) + { + Globals.CopyFbxVector2ToVector2(uv, (IntPtr)f); + } + } + if (layerElementUV.GetReferenceMode() == FbxLayerElement.EReferenceMode.eIndexToDirect) + { + Vector2[] vUvs = new Vector2[nVerts]; + FbxLayerElementArray_int indices = layerElementUV.GetIndexArray(); + for (int j = 0; j < nVerts; j++) + { + int i = indices.GetAt(j); + if (i < 0 || i > uvs.Length) + { + Debug.Log("Bad FBX UVs index"); + } + vUvs[j] = uvs[i]; + } + uvs = vUvs; + } + } + } + + FbxLayerElementMaterial layerElementMaterial = layer.GetMaterials(); + if (layerElementMaterial != null + && layerElementMaterial.GetMappingMode() == FbxLayerElement.EMappingMode.eByPolygon) + { + materialIndices = layerElementMaterial.GetIndexArray(); + } + + // Warn about layers we don't support -- requires sdk support for holes + // if (layer.GetHole() != null) { + // warnings.Add("Ignoring unsupported holes"); + // } + } - // Materials - List mats = new List(); - bool allTransparent = true; - for (int i = 0; i < node.GetMaterialCount(); i++) { - var (mat, alpha) = CreateMaterial(node.GetMaterial(i)); - mats.Add(mat); - allTransparent &= (alpha == 0); - } + // Materials + List mats = new List(); + bool allTransparent = true; + for (int i = 0; i < node.GetMaterialCount(); i++) + { + var (mat, alpha) = CreateMaterial(node.GetMaterial(i)); + mats.Add(mat); + allTransparent &= (alpha == 0); + } - if (allTransparent) { - warnings.Add("All textures are transparent\nAll materials set to full opacity"); - foreach (Material m in mats) { - var matColor = m.GetColor("_Color"); - matColor.a = 1f; - m.SetColor("_Color", matColor); - } - } + if (allTransparent) + { + warnings.Add("All textures are transparent\nAll materials set to full opacity"); + foreach (Material m in mats) + { + var matColor = m.GetColor("_Color"); + matColor.a = 1f; + m.SetColor("_Color", matColor); + } + } - if (mats.Count == 0) { - // Default material - mats.Add(UnityEngine.Object.Instantiate(m_standardMaterial)); - } + if (mats.Count == 0) + { + // Default material + mats.Add(UnityEngine.Object.Instantiate(m_standardMaterial)); + } - // Polygons - List[] triangles = new List[mats.Count]; - for (int i = 0; i < triangles.Length; i++) { - triangles[i] = new List(); - } - int nPolys = fbxMesh.GetPolygonCount(); - for (int i = 0; i < nPolys; i++) { - int submesh = 0; - if (materialIndices != null) { - submesh = materialIndices.GetAt(i); - if (submesh > mats.Count) { - Debug.Log("Bad FBX material index"); - continue; + // Polygons + List[] triangles = new List[mats.Count]; + for (int i = 0; i < triangles.Length; i++) + { + triangles[i] = new List(); + } + int nPolys = fbxMesh.GetPolygonCount(); + for (int i = 0; i < nPolys; i++) + { + int submesh = 0; + if (materialIndices != null) + { + submesh = materialIndices.GetAt(i); + if (submesh > mats.Count) + { + Debug.Log("Bad FBX material index"); + continue; + } + } + int polySize = fbxMesh.GetPolygonSize(i); + int i0 = fbxMesh.GetPolygonVertex(i, 0); + // Convert to triangle fans + for (int j = 2; j < polySize; j++) + { + triangles[submesh].Add(i0); + triangles[submesh].Add(fbxMesh.GetPolygonVertex(i, j)); + triangles[submesh].Add(fbxMesh.GetPolygonVertex(i, j - 1)); + } + } + + // Create meshes + GameObject parent = new GameObject("Mesh"); + + if (nVerts <= MAX_VERTS_PER_MESH) + { + Mesh mesh = new Mesh(); + mesh.vertices = verts; + if (uvs != null) + { + mesh.uv = uvs; + } + mesh.subMeshCount = triangles.Length; + for (int i = 0; i < triangles.Length; i++) + { + mesh.SetTriangles(triangles[i], i); + } + if (!degenerateNormals && normals != null) + { + mesh.normals = normals; + } + else + { + mesh.RecalculateNormals(); + } + mesh.bounds = b; + parent.AddComponent().mesh = mesh; + parent.AddComponent().materials = mats.ToArray(); + if (mats.All(m => m.GetColor("_Color").a < 1)) + { + parent.GetComponent().shadowCastingMode = + UnityEngine.Rendering.ShadowCastingMode.Off; + } + } + else + { + // Split into subobjects by material, and then split those into multiple meshes if required. + List v = new List(); + List n = new List(); + List uv = new List(); + List t = new List(); + Dictionary map = new Dictionary(); + + int iTri = 0; + int nTris = triangles.Aggregate(0, (sum, elt) => sum + elt.Count); + + for (int i = 0; i < mats.Count; i++) + { + for (int j = 0; j < triangles[i].Count; j += 3) + { + if (v.Count > MAX_VERTS_PER_MESH - 3) + { + CreateSubmesh(v, n, uv, t, mats[i]).transform.parent = parent.transform; + v.Clear(); + n.Clear(); + uv.Clear(); + t.Clear(); + map.Clear(); + + float delta = ((float)(j + iTri) / nTris) * ((float)nVerts / totalVerts); + OverlayManager.m_Instance.UpdateProgress((float)completedVerts / totalVerts + delta); + } + // map it + for (int k = 0; k < 3; k++) + { + int p = triangles[i][j + k]; + int index; + if (map.ContainsKey(p)) + { + index = map[p]; + } + else + { + if (p > verts.Length) + { + Debug.Log("Bad triangle index building FBX submesh"); + continue; + } + v.Add(verts[p]); + if (normals != null) + { + n.Add(normals[p]); + } + if (uvs != null) + { + uv.Add(uvs[p]); + } + index = v.Count - 1; + map.Add(p, index); + } + t.Add(index); + } + } + // Make object + CreateSubmesh(v, n, uv, t, mats[i]).transform.parent = parent.transform; + v.Clear(); + n.Clear(); + uv.Clear(); + t.Clear(); + map.Clear(); + + iTri += triangles[i].Count; + float progressDelta = (float)iTri / nTris * (float)nVerts / totalVerts; + OverlayManager.m_Instance.UpdateProgress((float)completedVerts / totalVerts + progressDelta); + } + } + completedVerts += nVerts; + OverlayManager.m_Instance.UpdateProgress((float)completedVerts / totalVerts); + + var bc = parent.gameObject.AddComponent(); + bc.center = b.center; + bc.size = b.size; + return parent; } - } - int polySize = fbxMesh.GetPolygonSize(i); - int i0 = fbxMesh.GetPolygonVertex(i, 0); - // Convert to triangle fans - for (int j = 2; j < polySize; j++) { - triangles[submesh].Add(i0); - triangles[submesh].Add(fbxMesh.GetPolygonVertex(i, j)); - triangles[submesh].Add(fbxMesh.GetPolygonVertex(i, j - 1)); - } - } - // Create meshes - GameObject parent = new GameObject("Mesh"); - - if (nVerts <= MAX_VERTS_PER_MESH) { - Mesh mesh = new Mesh(); - mesh.vertices = verts; - if (uvs != null) { - mesh.uv = uvs; - } - mesh.subMeshCount = triangles.Length; - for (int i = 0; i < triangles.Length; i++) { - mesh.SetTriangles(triangles[i], i); - } - if (!degenerateNormals && normals != null) { - mesh.normals = normals; - } else { - mesh.RecalculateNormals(); - } - mesh.bounds = b; - parent.AddComponent().mesh = mesh; - parent.AddComponent().materials = mats.ToArray(); - if (mats.All(m => m.GetColor("_Color").a < 1)) { - parent.GetComponent().shadowCastingMode = - UnityEngine.Rendering.ShadowCastingMode.Off; - } - } else { - // Split into subobjects by material, and then split those into multiple meshes if required. - List v = new List(); - List n = new List(); - List uv = new List(); - List t = new List(); - Dictionary map = new Dictionary(); - - int iTri = 0; - int nTris = triangles.Aggregate(0, (sum, elt) => sum + elt.Count); - - for (int i = 0; i < mats.Count; i++) { - for (int j = 0; j < triangles[i].Count; j += 3) { - if (v.Count > MAX_VERTS_PER_MESH - 3) { - CreateSubmesh(v, n, uv, t, mats[i]).transform.parent = parent.transform; - v.Clear(); - n.Clear(); - uv.Clear(); - t.Clear(); - map.Clear(); - - float delta = ((float)(j + iTri) / nTris) * ((float)nVerts / totalVerts); - OverlayManager.m_Instance.UpdateProgress((float)completedVerts / totalVerts + delta); - } - // map it - for (int k = 0; k < 3; k++) { - int p = triangles[i][j + k]; - int index; - if (map.ContainsKey(p)) { - index = map[p]; - } else { - if (p > verts.Length) { - Debug.Log("Bad triangle index building FBX submesh"); - continue; - } - v.Add(verts[p]); - if (normals != null) { - n.Add(normals[p]); - } - if (uvs != null) { - uv.Add(uvs[p]); - } - index = v.Count - 1; - map.Add(p, index); - } - t.Add(index); - } + static private void ApplyTransform(FbxNode node, Transform transform, float fbxUnitToTiltUnit) + { + FbxAMatrix am = + node.EvaluateLocalTransform(new FbxTime(), FbxNode.EPivotSet.eDestinationPivot); + + Vector3 unityTranslation, unityScale; + Quaternion unityRotation; + { + Vector3 fbxTranslation, fbxScale; + Quaternion fbxRotation; + am.ToTRS(out fbxTranslation, out fbxRotation, out fbxScale); + ExportUtils.ChangeBasis(fbxTranslation, fbxRotation, fbxScale, + out unityTranslation, out unityRotation, out unityScale, + ExportFbx.UnityFromFbx, ExportFbx.FbxFromUnity); + unityTranslation *= fbxUnitToTiltUnit; + } + transform.localPosition = unityTranslation; + transform.localScale = unityScale; + transform.localRotation = unityRotation; } - // Make object - CreateSubmesh(v, n, uv, t, mats[i]).transform.parent = parent.transform; - v.Clear(); - n.Clear(); - uv.Clear(); - t.Clear(); - map.Clear(); - - iTri += triangles[i].Count; - float progressDelta = (float)iTri / nTris * (float)nVerts / totalVerts; - OverlayManager.m_Instance.UpdateProgress((float)completedVerts / totalVerts + progressDelta); - } - } - completedVerts += nVerts; - OverlayManager.m_Instance.UpdateProgress((float)completedVerts / totalVerts); - var bc = parent.gameObject.AddComponent(); - bc.center = b.center; - bc.size = b.size; - return parent; - } + static private GameObject CreateSubmesh(List v, List n, List uv, + List t, Material m) + { + GameObject go = new GameObject("Submesh", typeof(MeshFilter), typeof(MeshRenderer)); + Mesh mesh = new Mesh(); + mesh.vertices = v.ToArray(); + mesh.triangles = t.ToArray(); + if (uv.Count > 0) + { + mesh.uv = uv.ToArray(); + } + if (n.Count > 0) + { + mesh.normals = n.ToArray(); + } + else + { + mesh.RecalculateNormals(); + } + go.GetComponent().mesh = mesh; + go.GetComponent().material = m; + if (m.GetColor("_Color").a < 1) + { + go.GetComponent().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; + } + return go; + } - static private void ApplyTransform(FbxNode node, Transform transform, float fbxUnitToTiltUnit) { - FbxAMatrix am = - node.EvaluateLocalTransform(new FbxTime(), FbxNode.EPivotSet.eDestinationPivot); + static private void SetPivots(FbxNode node) + { + node.SetPivotState(FbxNode.EPivotSet.eSourcePivot, FbxNode.EPivotState.ePivotActive); + node.SetPivotState(FbxNode.EPivotSet.eDestinationPivot, FbxNode.EPivotState.ePivotActive); + + FbxVector4 zero = new FbxVector4(0, 0, 0); + FbxVector4 one = new FbxVector4(1, 1, 1); + node.SetPostRotation(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetPreRotation(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetRotationOffset(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetScalingOffset(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetRotationPivot(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetScalingPivot(FbxNode.EPivotSet.eDestinationPivot, zero); + + node.SetRotationOrder(FbxNode.EPivotSet.eDestinationPivot, FbxEuler.EOrder.eOrderXYZ); + + node.SetGeometricTranslation(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetGeometricRotation(FbxNode.EPivotSet.eDestinationPivot, zero); + node.SetGeometricScaling(FbxNode.EPivotSet.eDestinationPivot, one); + + node.SetQuaternionInterpolation(FbxNode.EPivotSet.eDestinationPivot, + node.GetQuaternionInterpolation(FbxNode.EPivotSet.eSourcePivot)); + for (int i = 0; i < node.GetChildCount(); i++) + { + SetPivots(node.GetChild(i)); + } + } - Vector3 unityTranslation, unityScale; - Quaternion unityRotation; - { - Vector3 fbxTranslation, fbxScale; - Quaternion fbxRotation; - am.ToTRS(out fbxTranslation, out fbxRotation, out fbxScale); - ExportUtils.ChangeBasis(fbxTranslation, fbxRotation, fbxScale, - out unityTranslation, out unityRotation, out unityScale, - ExportFbx.UnityFromFbx, ExportFbx.FbxFromUnity); - unityTranslation *= fbxUnitToTiltUnit; - } - transform.localPosition = unityTranslation; - transform.localScale = unityScale; - transform.localRotation = unityRotation; - } - - static private GameObject CreateSubmesh(List v, List n, List uv, - List t, Material m) { - GameObject go = new GameObject("Submesh", typeof(MeshFilter), typeof(MeshRenderer)); - Mesh mesh = new Mesh(); - mesh.vertices = v.ToArray(); - mesh.triangles = t.ToArray(); - if (uv.Count > 0) { - mesh.uv = uv.ToArray(); - } - if (n.Count > 0) { - mesh.normals = n.ToArray(); - } else { - mesh.RecalculateNormals(); - } - go.GetComponent().mesh = mesh; - go.GetComponent().material = m; - if (m.GetColor("_Color").a < 1) { - go.GetComponent().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; - } - return go; - } - - static private void SetPivots(FbxNode node) { - node.SetPivotState(FbxNode.EPivotSet.eSourcePivot, FbxNode.EPivotState.ePivotActive); - node.SetPivotState(FbxNode.EPivotSet.eDestinationPivot, FbxNode.EPivotState.ePivotActive); - - FbxVector4 zero = new FbxVector4(0, 0, 0); - FbxVector4 one = new FbxVector4(1, 1, 1); - node.SetPostRotation(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetPreRotation(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetRotationOffset(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetScalingOffset(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetRotationPivot(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetScalingPivot(FbxNode.EPivotSet.eDestinationPivot, zero); - - node.SetRotationOrder(FbxNode.EPivotSet.eDestinationPivot, FbxEuler.EOrder.eOrderXYZ); - - node.SetGeometricTranslation(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetGeometricRotation(FbxNode.EPivotSet.eDestinationPivot, zero); - node.SetGeometricScaling(FbxNode.EPivotSet.eDestinationPivot, one); - - node.SetQuaternionInterpolation(FbxNode.EPivotSet.eDestinationPivot, - node.GetQuaternionInterpolation(FbxNode.EPivotSet.eSourcePivot)); - for (int i = 0; i < node.GetChildCount(); i++) { - SetPivots(node.GetChild(i)); - } - } - - // Makes path relative, if possible. - // If not possible or if path is already relative, returns it unchanged. - // Propagates nulls. - private static string MakePathRelative(string path, string relativeTo) { - if (!Path.IsPathRooted(path)) { return path; } - relativeTo = relativeTo.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - // It's actually not an easy thing to do to make a path relative, but this works - if (path.ToLowerInvariant().StartsWith(relativeTo.ToLowerInvariant())) { - return path.Substring(relativeTo.Length + 1); - } else { - return path; - } - } - - // Returns a path to the referenced texture, or null - // The path will be relative to the fbx, if possible - private string GetValidTextureFile(FbxFileTexture fbxTexture) { - string relative = fbxTexture.GetRelativeFileName(); - string rooted = fbxTexture.GetFileName(); - - if (!string.IsNullOrEmpty(relative)) { - string absolute = Path.Combine(m_dir, relative); - if (File.Exists(absolute)) { - return relative; - } - } + // Makes path relative, if possible. + // If not possible or if path is already relative, returns it unchanged. + // Propagates nulls. + private static string MakePathRelative(string path, string relativeTo) + { + if (!Path.IsPathRooted(path)) { return path; } + relativeTo = relativeTo.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + // It's actually not an easy thing to do to make a path relative, but this works + if (path.ToLowerInvariant().StartsWith(relativeTo.ToLowerInvariant())) + { + return path.Substring(relativeTo.Length + 1); + } + else + { + return path; + } + } - if (string.IsNullOrEmpty(rooted)) { - return null; - } - if (File.Exists(rooted)) { - return rooted; - } + // Returns a path to the referenced texture, or null + // The path will be relative to the fbx, if possible + private string GetValidTextureFile(FbxFileTexture fbxTexture) + { + string relative = fbxTexture.GetRelativeFileName(); + string rooted = fbxTexture.GetFileName(); + + if (!string.IsNullOrEmpty(relative)) + { + string absolute = Path.Combine(m_dir, relative); + if (File.Exists(absolute)) + { + return relative; + } + } - // Look in the same directory as the model. - // I think this code is largely superseded by using GetRelativeFileName(). - { - string madeUpRelative = Path.GetFileName(rooted); - string absolute = Path.Combine(m_dir, madeUpRelative); - if (File.Exists(absolute)) { - return madeUpRelative; - } - } + if (string.IsNullOrEmpty(rooted)) + { + return null; + } + if (File.Exists(rooted)) + { + return rooted; + } - warnings.Add($"Texture not found: {relative ?? rooted}"); - return null; - } - - // Returns path to the loaded texture, or null on failure. - // The path will be relative to the fbx, if possible - private string LoadTexture( - FbxPropertyDouble3 property, Material mat, string target, - bool compress = true) { - FbxFileTexture fbxTexture = property.GetSrcObject_FileTexture(); - if (fbxTexture == null) { return null; } - string maybeRelative = MakePathRelative(GetValidTextureFile(fbxTexture), m_dir); - if (maybeRelative == null) { return null; } - string ext = Path.GetExtension(maybeRelative).ToLower(); - if (! (ext == ".jpg" || ext == ".jpeg" || ext == ".png")) { - warnings.Add($"Unsupported texture type: {ext}"); - return null; - } - if (!mat.HasProperty(target)) { - warnings.Add($"mat has no property {target}, not assigning {maybeRelative}"); - } + // Look in the same directory as the model. + // I think this code is largely superseded by using GetRelativeFileName(). + { + string madeUpRelative = Path.GetFileName(rooted); + string absolute = Path.Combine(m_dir, madeUpRelative); + if (File.Exists(absolute)) + { + return madeUpRelative; + } + } + + warnings.Add($"Texture not found: {relative ?? rooted}"); + return null; + } - Texture2D texture = new Texture2D(2, 2); - texture.LoadImage(File.ReadAllBytes(Path.Combine(m_dir, maybeRelative))); - texture.Apply(); - if (compress) { - texture.Compress(false); + // Returns path to the loaded texture, or null on failure. + // The path will be relative to the fbx, if possible + private string LoadTexture( + FbxPropertyDouble3 property, Material mat, string target, + bool compress = true) + { + FbxFileTexture fbxTexture = property.GetSrcObject_FileTexture(); + if (fbxTexture == null) { return null; } + string maybeRelative = MakePathRelative(GetValidTextureFile(fbxTexture), m_dir); + if (maybeRelative == null) { return null; } + string ext = Path.GetExtension(maybeRelative).ToLower(); + if (!(ext == ".jpg" || ext == ".jpeg" || ext == ".png")) + { + warnings.Add($"Unsupported texture type: {ext}"); + return null; + } + if (!mat.HasProperty(target)) + { + warnings.Add($"mat has no property {target}, not assigning {maybeRelative}"); + } + + Texture2D texture = new Texture2D(2, 2); + texture.LoadImage(File.ReadAllBytes(Path.Combine(m_dir, maybeRelative))); + texture.Apply(); + if (compress) + { + texture.Compress(false); + } + mat.SetTexture(target, texture); + return maybeRelative; + } + + // Converts to Vector3 and applies coordinate system conversion + static private Vector3 ToUnityPosition(FbxDouble3 d) + { + Vector3 fbxStyle = d.ToUVector3(); + // MultiplyPoint and MultiplyVector both work, since coordinate + // conversion matrices are 3x3 + return ExportFbx.UnityFromFbx.MultiplyVector(fbxStyle); + } } - mat.SetTexture(target, texture); - return maybeRelative; - } - - // Converts to Vector3 and applies coordinate system conversion - static private Vector3 ToUnityPosition(FbxDouble3 d) { - Vector3 fbxStyle = d.ToUVector3(); - // MultiplyPoint and MultiplyVector both work, since coordinate - // conversion matrices are 3x3 - return ExportFbx.UnityFromFbx.MultiplyVector(fbxStyle); - } -} } // namespace TiltBrush #endif diff --git a/Assets/Scripts/GUI/PanelManager.cs b/Assets/Scripts/GUI/PanelManager.cs index 2a54a398b3..974d45e909 100644 --- a/Assets/Scripts/GUI/PanelManager.cs +++ b/Assets/Scripts/GUI/PanelManager.cs @@ -2325,8 +2325,9 @@ public bool IsAffectedByCollision(PanelData data) public void OpenPanel(BasePanel.PanelType type, TrTransform trSpawnXf, bool forced = false) { - if ((type != BasePanel.PanelType.SketchSurface && type != BasePanel.PanelType.Color && - type != BasePanel.PanelType.Brush) || forced) + if ((type != BasePanel.PanelType.SketchSurface + && type != BasePanel.PanelType.Color + && type != BasePanel.PanelType.Brush) || forced) { TrTransform xfSpawn = trSpawnXf; xfSpawn.scale = 0.0f; diff --git a/Assets/Scripts/Model.cs b/Assets/Scripts/Model.cs index 5069bd6501..4c6b505b1f 100644 --- a/Assets/Scripts/Model.cs +++ b/Assets/Scripts/Model.cs @@ -502,19 +502,22 @@ GameObject LoadFbx(List warningsOut) m_LoadError = new LoadError("fbx not supported"); return null; #else - try { - var reader = new FbxReader(m_Location.AbsolutePath); - var (gameObject, warnings, collector) = reader.Import(); - warningsOut.AddRange(warnings); - m_ImportMaterialCollector = collector; - m_AllowExport = (m_ImportMaterialCollector != null); - return gameObject; - } catch (Exception ex) { - m_LoadError = new LoadError("Invalid data", ex.Message); - m_AllowExport = false; - Debug.LogException(ex); - return null; - } + try + { + var reader = new FbxReader(m_Location.AbsolutePath); + var (gameObject, warnings, collector) = reader.Import(); + warningsOut.AddRange(warnings); + m_ImportMaterialCollector = collector; + m_AllowExport = (m_ImportMaterialCollector != null); + return gameObject; + } + catch (Exception ex) + { + m_LoadError = new LoadError("Invalid data", ex.Message); + m_AllowExport = false; + Debug.LogException(ex); + return null; + } #endif } diff --git a/Assets/Scripts/OverlayManager.cs b/Assets/Scripts/OverlayManager.cs index 59e5a15347..9c7a4a6686 100644 --- a/Assets/Scripts/OverlayManager.cs +++ b/Assets/Scripts/OverlayManager.cs @@ -133,7 +133,8 @@ void Update() break; case OverlayState.Hidden: case OverlayState.Visible: - default: break; + default: + break; } } diff --git a/Assets/Scripts/PointerManager.cs b/Assets/Scripts/PointerManager.cs index e78c76b7f2..11a02c2be6 100644 --- a/Assets/Scripts/PointerManager.cs +++ b/Assets/Scripts/PointerManager.cs @@ -1470,16 +1470,7 @@ void CheckGestures() nextShape = StraightEdgeGuideScript.Shape.Circle; break; case StraightEdgeGuideScript.Shape.Circle: - { - if (App.Config.IsMobileHardware) - { - nextShape = StraightEdgeGuideScript.Shape.Line; - } - else - { - nextShape = StraightEdgeGuideScript.Shape.Sphere; - } - } + nextShape = StraightEdgeGuideScript.Shape.Sphere; break; case StraightEdgeGuideScript.Shape.Sphere: nextShape = StraightEdgeGuideScript.Shape.Line; diff --git a/Assets/Scripts/Rendering/RenderWrapper.cs b/Assets/Scripts/Rendering/RenderWrapper.cs index ab57c3141b..965fb62b6b 100644 --- a/Assets/Scripts/Rendering/RenderWrapper.cs +++ b/Assets/Scripts/Rendering/RenderWrapper.cs @@ -23,6 +23,12 @@ #pragma warning disable 649, 414 #endif +// TODO:Mikesky - For some reason, offscreen rendering to m_hdrTarget is losing depth on XR. +// Unity's docs say this should be fine, so it may be a Unity bug. +// Investigate if this is fixed in newer Unity versions +// The temp fix is to no longer cull primary camera, and only display the offscreen render during +// a recording session, which is very rare and not likely to be using depth. + namespace TiltBrush { @@ -200,9 +206,12 @@ void OnPreCull() // Store the clear and culling mask to restore after rendering. m_cameraClearFlags = srcCam.clearFlags; m_cameraCullingMask = srcCam.cullingMask; - srcCam.cullingMask = 0; - srcCam.clearFlags = CameraClearFlags.Nothing; srcCam.allowHDR = GetTargetFormat() != RenderTextureFormat.ARGB32; + + // TODO:Mikesky - See top of file. + // srcCam.cullingMask = 0; + // srcCam.clearFlags = CameraClearFlags.Nothing; + #endif if (ReadBackTextures != null && m_readbackTextureFrame != Time.frameCount) @@ -456,7 +465,8 @@ public void OnRenderImage(RenderTexture source, RenderTexture destination) } else { - Graphics.Blit(m_hdrTarget, destination); + // TODO:Mikesky - See top of file. + Graphics.Blit(source, destination); // Generate the outline mask for later use in the post fx chain if (m_StencilToMaskMaterial) { @@ -469,9 +479,10 @@ public void OnRenderImage(RenderTexture source, RenderTexture destination) // Only need the selection mask if the selection effect is enabled if (App.Instance.SelectionEffect.RenderHighlight()) { - Graphics.Blit(m_hdrTarget, destination); - Graphics.Blit(destination, m_hdrTarget, m_StencilToMaskMaterial); - Graphics.Blit(m_hdrTarget, m_MaskTarget); + // TODO:Mikesky - See top of file. + Graphics.Blit(source, destination); + Graphics.Blit(destination, source, m_StencilToMaskMaterial); + Graphics.Blit(source, m_MaskTarget); } } } diff --git a/Assets/Scripts/Rendering/Selection/StencilToMask.shader b/Assets/Scripts/Rendering/Selection/StencilToMask.shader index a0ea55277d..bb532b5894 100644 --- a/Assets/Scripts/Rendering/Selection/StencilToMask.shader +++ b/Assets/Scripts/Rendering/Selection/StencilToMask.shader @@ -14,10 +14,6 @@ Shader "Hidden/StencilToMask" { - Properties - { - _MainTex ("Texture", 2D) = "white" {} - } SubShader { // No culling or depth @@ -41,24 +37,31 @@ Shader "Hidden/StencilToMask" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } - sampler2D _MainTex; - fixed4 frag (v2f i) : SV_Target { fixed4 col = float4(1,1,1,1); @@ -85,24 +88,31 @@ Shader "Hidden/StencilToMask" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } - sampler2D _MainTex; - fixed4 frag (v2f i) : SV_Target { fixed4 col = float4(0,0,0,1); diff --git a/Assets/Scripts/Util/SerializableGuid.cs b/Assets/Scripts/Util/SerializableGuid.cs index 14622975a5..19fe869c2f 100644 --- a/Assets/Scripts/Util/SerializableGuid.cs +++ b/Assets/Scripts/Util/SerializableGuid.cs @@ -22,7 +22,7 @@ namespace TiltBrush { #if UNITY_EDITOR -// See http://docs.unity3d.com/ScriptReference/PropertyDrawer.html + // See http://docs.unity3d.com/ScriptReference/PropertyDrawer.html [CustomPropertyDrawer(typeof(SerializableGuid))] public class SerializableGuidDrawer : PropertyDrawer { diff --git a/Assets/Scripts/VrSdk.cs b/Assets/Scripts/VrSdk.cs index 048265d48e..fabe5ecf1a 100644 --- a/Assets/Scripts/VrSdk.cs +++ b/Assets/Scripts/VrSdk.cs @@ -273,6 +273,8 @@ void OnDestroy() Application.onBeforeRender -= OnNewPoses; InputDevices.deviceConnected -= OnUnityXRDeviceConnected; InputDevices.deviceDisconnected -= OnUnityXRDeviceDisconnected; + XRGeneralSettings.Instance?.Manager?.StopSubsystems(); + XRGeneralSettings.Instance?.Manager?.DeinitializeLoader(); } } diff --git a/Assets/Scripts/WidgetManager.cs b/Assets/Scripts/WidgetManager.cs index dc7a5254d3..0b9d043c3c 100644 --- a/Assets/Scripts/WidgetManager.cs +++ b/Assets/Scripts/WidgetManager.cs @@ -14,7 +14,6 @@ using System; using System.Linq; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEngine; namespace TiltBrush diff --git a/Assets/Shaders/AmbientGrid.shader b/Assets/Shaders/AmbientGrid.shader index 78baec1337..9e33207c96 100644 --- a/Assets/Shaders/AmbientGrid.shader +++ b/Assets/Shaders/AmbientGrid.shader @@ -51,6 +51,8 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -58,6 +60,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float viewdist : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -68,6 +72,10 @@ Category { PrepForOds(v.vertex); v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.color = v.color; diff --git a/Assets/Shaders/AngleIndicator.shader b/Assets/Shaders/AngleIndicator.shader index 286d6fe3dd..102f7a7262 100644 --- a/Assets/Shaders/AngleIndicator.shader +++ b/Assets/Shaders/AngleIndicator.shader @@ -41,17 +41,25 @@ Category { fixed4 color : COLOR; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float3 uv : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + }; v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float age = _Time.y; o.vertex = UnityObjectToClipPos(v.vertex); diff --git a/Assets/Shaders/AssetLoading.shader b/Assets/Shaders/AssetLoading.shader index cc4b0a94c5..31e70458a3 100644 --- a/Assets/Shaders/AssetLoading.shader +++ b/Assets/Shaders/AssetLoading.shader @@ -43,16 +43,24 @@ SubShader { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); return o; diff --git a/Assets/Shaders/AudioReactiveBrushIcon.shader b/Assets/Shaders/AudioReactiveBrushIcon.shader index f00b098a0c..bccc066cad 100644 --- a/Assets/Shaders/AudioReactiveBrushIcon.shader +++ b/Assets/Shaders/AudioReactiveBrushIcon.shader @@ -26,6 +26,8 @@ Shader "Custom/AudioReactiveBrushIcon" { CGPROGRAM #pragma vertex vert #pragma fragment frag + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" sampler2D _MainTex; @@ -36,16 +38,25 @@ Shader "Custom/AudioReactiveBrushIcon" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.xyz += v.vertex.xyz * _BeatOutput.x * .1; o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; diff --git a/Assets/Shaders/AudioReactiveIcon.shader b/Assets/Shaders/AudioReactiveIcon.shader index f633e7a3dd..de023e43a3 100644 --- a/Assets/Shaders/AudioReactiveIcon.shader +++ b/Assets/Shaders/AudioReactiveIcon.shader @@ -30,6 +30,8 @@ Shader "Custom/AudioReactiveIcon" { #pragma target 3.0 #pragma multi_compile __ AUDIO_REACTIVE #pragma multi_compile __ HDR_EMULATED HDR_SIMPLE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/Hdr.cginc" @@ -42,16 +44,25 @@ Shader "Custom/AudioReactiveIcon" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + #ifdef AUDIO_REACTIVE v.vertex.xyz += v.vertex.xyz * .2; v.vertex.z += -.2; diff --git a/Assets/Shaders/Blended.shader b/Assets/Shaders/Blended.shader index 594665ce46..c809cd60c1 100644 --- a/Assets/Shaders/Blended.shader +++ b/Assets/Shaders/Blended.shader @@ -41,12 +41,16 @@ Category { fixed4 color : COLOR; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -55,6 +59,10 @@ Category { { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); #ifdef AUDIO_REACTIVE o.color = musicReactiveColor(v.color, _BeatOutput.w); diff --git a/Assets/Shaders/BlitDownsample.shader b/Assets/Shaders/BlitDownsample.shader index 0acb1d81b3..58cafd612a 100644 --- a/Assets/Shaders/BlitDownsample.shader +++ b/Assets/Shaders/BlitDownsample.shader @@ -38,27 +38,38 @@ Shader "Hidden/BlitDownsample" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv * _Scale; return o; } - sampler2D _MainTex; + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); fixed4 frag (v2f i) : SV_Target { - return tex2D(_MainTex, i.uv); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); } ENDCG } diff --git a/Assets/Shaders/BlitLdrPmaOverlay.shader b/Assets/Shaders/BlitLdrPmaOverlay.shader index ac9aa82de4..08bf5868c2 100644 --- a/Assets/Shaders/BlitLdrPmaOverlay.shader +++ b/Assets/Shaders/BlitLdrPmaOverlay.shader @@ -36,22 +36,30 @@ Shader "Custom/BlitLdrPmaOverlay" { struct v2f { float4 pos : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata_img v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy); return o; } - sampler2D _MainTex; - sampler2D _OverlayTex; + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_OverlayTex); float4 _OverlayUvRange; float4 frag(v2f i) : COLOR { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // Get the original color. - float4 mainTex = tex2D(_MainTex, i.uv); + float4 mainTex = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); // Calculate the overlay's texture coordinates. float2 uvMin = _OverlayUvRange.xy; @@ -60,7 +68,7 @@ Shader "Custom/BlitLdrPmaOverlay" { float2 overlayUV = saturate((i.uv - uvMin) / uvSize); // Get the overlay color. - float4 overlayTex = tex2D(_OverlayTex, overlayUV); + float4 overlayTex = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_OverlayTex, overlayUV); // Composite the result. return (1.0f - overlayTex.a) * saturate(mainTex) + overlayTex; diff --git a/Assets/Shaders/BlitLinearToGamma.shader b/Assets/Shaders/BlitLinearToGamma.shader index 858be19730..31e0f7b45a 100644 --- a/Assets/Shaders/BlitLinearToGamma.shader +++ b/Assets/Shaders/BlitLinearToGamma.shader @@ -31,21 +31,29 @@ ZTest Always Cull Off ZWrite Off Fog { Mode Off } //Rendering settings struct v2f { float4 pos : POSITION; half2 uv : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; //Our Vertex Shader v2f vert (appdata_img v){ v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos (v.vertex); o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord.xy); return o; } - sampler2D _MainTex; //Reference in Pass is necessary to let us use this variable in shaders + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Reference in Pass is necessary to let us use this variable in shaders //Our Fragment Shader fixed4 frag (v2f i) : COLOR{ - fixed4 tex = tex2D(_MainTex, i.uv); //Get the orginal rendered color + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + fixed4 tex = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Get the orginal rendered color return pow(tex, 1.0/2.2); } ENDCG diff --git a/Assets/Shaders/BlitToCompute.shader b/Assets/Shaders/BlitToCompute.shader index 158eadf608..52e4b07bbd 100644 --- a/Assets/Shaders/BlitToCompute.shader +++ b/Assets/Shaders/BlitToCompute.shader @@ -36,29 +36,40 @@ Shader "Hidden/BlitToCompute" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } - sampler2D _MainTex; + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); float4 _MainTex_TexelSize; RWStructuredBuffer _CaptureBuffer : register(u1); fixed4 frag (v2f i) : SV_Target { - float4 c = tex2D(_MainTex, i.uv); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + + float4 c = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); float4 cOut = c; // Make sure to ignore non-zero alpha. diff --git a/Assets/Shaders/BlitWatermark.shader b/Assets/Shaders/BlitWatermark.shader index e527b97dff..9a82fda400 100644 --- a/Assets/Shaders/BlitWatermark.shader +++ b/Assets/Shaders/BlitWatermark.shader @@ -32,21 +32,29 @@ Blend SrcAlpha OneMinusSrcAlpha // Alpha blending struct v2f { float4 pos : POSITION; half2 uv : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; //Our Vertex Shader v2f vert (appdata_img v){ v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos (v.vertex); o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord.xy); return o; } - sampler2D _MainTex; //Reference in Pass is necessary to let us use this variable in shaders + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Reference in Pass is necessary to let us use this variable in shaders //Our Fragment Shader fixed4 frag (v2f i) : COLOR{ - fixed4 tex = tex2D(_MainTex, i.uv); //Get the orginal rendered color + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + fixed4 tex = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Get the orginal rendered color return tex; } ENDCG diff --git a/Assets/Shaders/BrowserButton.shader b/Assets/Shaders/BrowserButton.shader index 45e5bd8aa8..2745d4ee94 100644 --- a/Assets/Shaders/BrowserButton.shader +++ b/Assets/Shaders/BrowserButton.shader @@ -28,6 +28,8 @@ Shader "Custom/BrowserButton" { #pragma vertex vert #pragma fragment frag #pragma multi_compile __ HDR_EMULATED HDR_SIMPLE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/Hdr.cginc" @@ -39,16 +41,25 @@ Shader "Custom/BrowserButton" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + if (_Activated) v.vertex.xyz += float3(0,0,-0.1); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; diff --git a/Assets/Shaders/CircularProgress.shader b/Assets/Shaders/CircularProgress.shader index a81bc47384..ae77d00607 100644 --- a/Assets/Shaders/CircularProgress.shader +++ b/Assets/Shaders/CircularProgress.shader @@ -44,12 +44,16 @@ Shader "Unlit/CircularProgress" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; float _Progress; @@ -62,6 +66,11 @@ Shader "Unlit/CircularProgress" v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; diff --git a/Assets/Shaders/ColorPicker_hl_s.shader b/Assets/Shaders/ColorPicker_hl_s.shader index 21e9990f98..2109955536 100644 --- a/Assets/Shaders/ColorPicker_hl_s.shader +++ b/Assets/Shaders/ColorPicker_hl_s.shader @@ -20,8 +20,9 @@ Properties { } CGINCLUDE + #include "UnityCG.cginc" #include "Assets/Shaders/Include/ColorSpace.cginc" - #include "Assets/Shaders/Include/Hdr.cginc" + #include "Assets/Shaders/Include/Hdr.cginc" float _Slider01; fixed4 _Color; @@ -29,11 +30,15 @@ CGINCLUDE float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float4 tangent : TANGENT; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 texcoord : TEXCOORD0; float4 pos : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; ENDCG @@ -58,6 +63,11 @@ SubShader { v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.z += v.vertex.z + 0.05; o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; @@ -83,6 +93,11 @@ SubShader { v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; diff --git a/Assets/Shaders/ColorPicker_hs_l.shader b/Assets/Shaders/ColorPicker_hs_l.shader index 25628a3f1d..5516c23903 100644 --- a/Assets/Shaders/ColorPicker_hs_l.shader +++ b/Assets/Shaders/ColorPicker_hs_l.shader @@ -20,8 +20,10 @@ Properties { } CGINCLUDE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/ColorSpace.cginc" - #include "Assets/Shaders/Include/Hdr.cginc" + #include "Assets/Shaders/Include/Hdr.cginc" float _Slider01; fixed4 _Color; @@ -29,11 +31,15 @@ CGINCLUDE float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float4 tangent : TANGENT; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 texcoord : TEXCOORD0; float4 pos : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; ENDCG @@ -56,6 +62,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.z += v.vertex.z + 0.05; o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; @@ -82,6 +93,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; diff --git a/Assets/Shaders/ColorPicker_hs_logv.shader b/Assets/Shaders/ColorPicker_hs_logv.shader index 844d0a2a37..7680839273 100644 --- a/Assets/Shaders/ColorPicker_hs_logv.shader +++ b/Assets/Shaders/ColorPicker_hs_logv.shader @@ -19,8 +19,9 @@ Properties { _Slider01 ("Slider", Range(0,1)) = 0.5 } CGINCLUDE + #include "UnityCG.cginc" #include "Assets/Shaders/Include/ColorSpace.cginc" - #include "Assets/Shaders/Include/Hdr.cginc" + #include "Assets/Shaders/Include/Hdr.cginc" float _Slider01; fixed4 _Color; @@ -28,11 +29,15 @@ CGINCLUDE float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float4 tangent : TANGENT; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 texcoord : TEXCOORD0; float4 pos : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; ENDCG @@ -56,6 +61,11 @@ SubShader { v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.z += v.vertex.z + 0.05; o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; @@ -85,6 +95,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; diff --git a/Assets/Shaders/ColorPicker_sl_h.shader b/Assets/Shaders/ColorPicker_sl_h.shader index 19586d096f..bac7eb3eb9 100644 --- a/Assets/Shaders/ColorPicker_sl_h.shader +++ b/Assets/Shaders/ColorPicker_sl_h.shader @@ -20,8 +20,9 @@ Properties { } CGINCLUDE + #include "UnityCG.cginc" #include "Assets/Shaders/Include/ColorSpace.cginc" - #include "Assets/Shaders/Include/Hdr.cginc" + #include "Assets/Shaders/Include/Hdr.cginc" float _Slider01; fixed4 _Color; @@ -29,11 +30,15 @@ CGINCLUDE float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float4 tangent : TANGENT; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 texcoord : TEXCOORD0; float4 pos : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; ENDCG @@ -57,6 +62,11 @@ SubShader { v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.z += v.vertex.z + 0.05; o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; @@ -80,6 +90,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; diff --git a/Assets/Shaders/ColorPicker_sv_h.shader b/Assets/Shaders/ColorPicker_sv_h.shader index 762bdb07dc..80797ce02e 100644 --- a/Assets/Shaders/ColorPicker_sv_h.shader +++ b/Assets/Shaders/ColorPicker_sv_h.shader @@ -20,8 +20,9 @@ Properties { } CGINCLUDE + #include "UnityCG.cginc" #include "Assets/Shaders/Include/ColorSpace.cginc" - #include "Assets/Shaders/Include/Hdr.cginc" + #include "Assets/Shaders/Include/Hdr.cginc" float _Slider01; fixed4 _Color; @@ -29,11 +30,15 @@ CGINCLUDE float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float4 tangent : TANGENT; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 texcoord : TEXCOORD0; float4 pos : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; ENDCG @@ -57,6 +62,11 @@ SubShader { v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.vertex.z += v.vertex.z + 0.05; o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; @@ -80,6 +90,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; diff --git a/Assets/Shaders/ControllerXRay.shader b/Assets/Shaders/ControllerXRay.shader index 62aae24a4a..463e6a9dab 100644 --- a/Assets/Shaders/ControllerXRay.shader +++ b/Assets/Shaders/ControllerXRay.shader @@ -48,17 +48,26 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; v2f vert (appdata_t v) { v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = UnityObjectToClipPos(v.vertex); return o; } diff --git a/Assets/Shaders/DefaultMaterialPreview.shader b/Assets/Shaders/DefaultMaterialPreview.shader index baba359209..d43cd67c85 100644 --- a/Assets/Shaders/DefaultMaterialPreview.shader +++ b/Assets/Shaders/DefaultMaterialPreview.shader @@ -41,11 +41,15 @@ Category { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -53,6 +57,11 @@ Category { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); return o; diff --git a/Assets/Shaders/FixDistortion.shader b/Assets/Shaders/FixDistortion.shader index d09b2f7a1d..24ada22a3b 100644 --- a/Assets/Shaders/FixDistortion.shader +++ b/Assets/Shaders/FixDistortion.shader @@ -47,10 +47,17 @@ Shader "Custom/FixDistortion" { float4 position : SV_POSITION; float2 uv : TEXCOORD0; float4 worldPos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; fragment_input vert(appdata_img v) { fragment_input o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(fragment_input, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.position = UnityObjectToClipPos(v.vertex); o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord); o.worldPos = mul(unity_ObjectToWorld, v.vertex); diff --git a/Assets/Shaders/FixDistortionAndReveal.shader b/Assets/Shaders/FixDistortionAndReveal.shader index 668b9d26a4..f476fb043f 100644 --- a/Assets/Shaders/FixDistortionAndReveal.shader +++ b/Assets/Shaders/FixDistortionAndReveal.shader @@ -61,10 +61,17 @@ Shader "Custom/FixDistortionAndReveal" { float4 position : SV_POSITION; float2 uv : TEXCOORD0; float4 worldPos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; fragment_input vert(appdata_img v) { fragment_input o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(fragment_input, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.position = UnityObjectToClipPos(v.vertex); o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord); o.worldPos = mul(unity_ObjectToWorld, v.vertex + float4(_LocalSpaceOffset,0,0,0)); diff --git a/Assets/Shaders/FlatLit.shader b/Assets/Shaders/FlatLit.shader index 35652ad6c1..c2b3aa1c37 100644 --- a/Assets/Shaders/FlatLit.shader +++ b/Assets/Shaders/FlatLit.shader @@ -58,6 +58,8 @@ SubShader { float2 uv : TEXCOORD0; float4 color : Color; uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -68,10 +70,17 @@ SubShader { float4 color : TEXCOORD3; float2 id : TEXCOORD4; SHADOW_COORDS(5) + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw; o.pos = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex); diff --git a/Assets/Shaders/FogDensity.shader b/Assets/Shaders/FogDensity.shader index b65ff5afa0..acf6072614 100644 --- a/Assets/Shaders/FogDensity.shader +++ b/Assets/Shaders/FogDensity.shader @@ -50,12 +50,16 @@ Shader "Custom/FogDensity" { float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vertInflate (appdata_t v, float currentSliceIndex) { @@ -63,6 +67,11 @@ Shader "Custom/FogDensity" { float ratioMultiplier = -.5; v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.tangent.w = 1.0; float totalNumSlices = 5; float ratio = (currentSliceIndex / (totalNumSlices - 1)); diff --git a/Assets/Shaders/FullScreenOverlay.shader b/Assets/Shaders/FullScreenOverlay.shader index 6f96c191a9..827366cc48 100644 --- a/Assets/Shaders/FullScreenOverlay.shader +++ b/Assets/Shaders/FullScreenOverlay.shader @@ -36,10 +36,14 @@ Shader "Unlit/FullScreenOverlay" struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -47,6 +51,11 @@ Shader "Unlit/FullScreenOverlay" v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); return o; } diff --git a/Assets/Shaders/GpuText.shader b/Assets/Shaders/GpuText.shader index af4ba85f16..c12fbedc8e 100644 --- a/Assets/Shaders/GpuText.shader +++ b/Assets/Shaders/GpuText.shader @@ -38,12 +38,16 @@ Shader "Unlit/GpuText" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -57,6 +61,11 @@ Shader "Unlit/GpuText" v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; diff --git a/Assets/Shaders/GrabHighlightMask.shader b/Assets/Shaders/GrabHighlightMask.shader index 5926bfa812..d89b712127 100644 --- a/Assets/Shaders/GrabHighlightMask.shader +++ b/Assets/Shaders/GrabHighlightMask.shader @@ -47,20 +47,28 @@ Category { struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); return o; } void frag (v2f i, out fixed4 col : SV_Target) { - col = float4(1,1,1,1); + col = float4(1,1,1,1); } ENDCG } diff --git a/Assets/Shaders/GrabHighlightUnmask.shader b/Assets/Shaders/GrabHighlightUnmask.shader index f07ec6d42e..8058033739 100644 --- a/Assets/Shaders/GrabHighlightUnmask.shader +++ b/Assets/Shaders/GrabHighlightUnmask.shader @@ -47,20 +47,29 @@ Category { struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = UnityObjectToClipPos(v.vertex); return o; } void frag (v2f i, out fixed4 col : SV_Target) { - col = float4(1,1,1,1); + col = float4(1,1,1,1); } ENDCG } diff --git a/Assets/Shaders/GripPulse.shader b/Assets/Shaders/GripPulse.shader index 8ac30876d5..29e1f217c4 100644 --- a/Assets/Shaders/GripPulse.shader +++ b/Assets/Shaders/GripPulse.shader @@ -30,10 +30,14 @@ Shader "Custom/GripPulse" { struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -41,6 +45,11 @@ Shader "Custom/GripPulse" { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); return o; } diff --git a/Assets/Shaders/GroundPlaneOverlay.shader b/Assets/Shaders/GroundPlaneOverlay.shader index 4c00fbeaef..659d8c56a6 100644 --- a/Assets/Shaders/GroundPlaneOverlay.shader +++ b/Assets/Shaders/GroundPlaneOverlay.shader @@ -38,11 +38,15 @@ Shader "Unlit/GroundPlaneOverlay" struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float3 worldPosition : COLOR; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -52,6 +56,11 @@ Shader "Unlit/GroundPlaneOverlay" v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.worldPosition = mul(unity_ObjectToWorld, v.vertex).xyz; return o; diff --git a/Assets/Shaders/HighlightPulse.shader b/Assets/Shaders/HighlightPulse.shader index be77bf5658..5d2837b2ee 100644 --- a/Assets/Shaders/HighlightPulse.shader +++ b/Assets/Shaders/HighlightPulse.shader @@ -34,11 +34,15 @@ Shader "Custom/HighlightPulse" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -50,6 +54,11 @@ Shader "Custom/HighlightPulse" { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Shaders/Include/Particles.cginc b/Assets/Shaders/Include/Particles.cginc index 3a6c7e205b..9704f2b7b6 100644 --- a/Assets/Shaders/Include/Particles.cginc +++ b/Assets/Shaders/Include/Particles.cginc @@ -52,6 +52,8 @@ struct ParticleVertexWithSpread_t { float4 texcoord : TEXCOORD0; // xy: texcoord z: rotation w: birth time float3 origin : TEXCOORD1; // pos: location of the knot (particle "sprays" from this) uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; // } NOTOOLKIT // TOOLKIT: #define ParticleVertexWithSpread_t ParticleVertex_t @@ -64,6 +66,8 @@ struct ParticleVertex_t { fixed4 color : COLOR; float4 texcoord : TEXCOORD0; // xy: texcoord z: rotation w: birth time uint id : SV_VertexID; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; // Rotates the corner of a square quad centered at the origin diff --git a/Assets/Shaders/LightWidget.shader b/Assets/Shaders/LightWidget.shader index 0d2a7d5c41..6fb89f2427 100644 --- a/Assets/Shaders/LightWidget.shader +++ b/Assets/Shaders/LightWidget.shader @@ -41,14 +41,23 @@ Shader "Custom/LightWidget" { struct Input { float4 vertex : POSITION; float3 normal : NORMAL; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float4 posWorld : TEXCOORD0; float3 normalDir : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; + v2f vert (Input v) { - v2f o = (v2f)0; + v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // Smash along the z axis based on a 0-1 ratio v.vertex.z = v.vertex.z - v.vertex.z * _FlattenAmount; diff --git a/Assets/Shaders/LinearGradient.shader b/Assets/Shaders/LinearGradient.shader index b8bb218321..05546c3e2b 100644 --- a/Assets/Shaders/LinearGradient.shader +++ b/Assets/Shaders/LinearGradient.shader @@ -31,21 +31,31 @@ Shader "Custom/LinearGradient" { #pragma vertex vert #pragma fragment frag + #include "UnityCG.cginc" + struct vertexIn { float4 pos : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 modelpos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(vertexIn input) { v2f output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_OUTPUT(v2f, output); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + output.pos = UnityObjectToClipPos(input.pos); output.uv = input.uv; output.modelpos = input.pos; diff --git a/Assets/Shaders/LinearGradientPreview.shader b/Assets/Shaders/LinearGradientPreview.shader index f1f02ed101..c43e82bd76 100644 --- a/Assets/Shaders/LinearGradientPreview.shader +++ b/Assets/Shaders/LinearGradientPreview.shader @@ -34,21 +34,31 @@ Shader "Custom/LinearGradientPreview" { #pragma vertex vert #pragma fragment frag + #include "UnityCG.cginc" + struct vertexIn { float4 pos : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 modelpos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(vertexIn input) { v2f output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_OUTPUT(v2f, output); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + output.pos = UnityObjectToClipPos(input.pos); output.uv = input.uv; output.modelpos = input.pos; diff --git a/Assets/Shaders/MobileDiffuse.shader b/Assets/Shaders/MobileDiffuse.shader index fae28d454f..d074e9229e 100644 --- a/Assets/Shaders/MobileDiffuse.shader +++ b/Assets/Shaders/MobileDiffuse.shader @@ -47,6 +47,8 @@ Shader "TiltBrush/MobileDiffuse" { float2 uv1 : TEXCOORD1; half3 normal : NORMAL; float4 color : COLOR; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -56,6 +58,8 @@ Shader "TiltBrush/MobileDiffuse" { half3 worldNormal : NORMAL; UNITY_FOG_COORDS(2) SHADOW_COORDS(3) // put shadows data into TEXCOORD3 + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -67,6 +71,10 @@ Shader "TiltBrush/MobileDiffuse" { v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.uv0 = TRANSFORM_TEX(v.uv0, _MainTex); o.uv1 = TRANSFORM_TEX(v.uv1, _LightMap); diff --git a/Assets/Shaders/ModelGhost.shader b/Assets/Shaders/ModelGhost.shader index 504978cbea..3c9141d245 100644 --- a/Assets/Shaders/ModelGhost.shader +++ b/Assets/Shaders/ModelGhost.shader @@ -13,68 +13,72 @@ // limitations under the License. Shader "Custom/ModelGhost" { -Properties { - _Color ("Color", Color) = (1, 1, 1, 1) -} + Properties { + _Color ("Color", Color) = (1, 1, 1, 1) + } -Category { - SubShader { + Category { + SubShader { - Tags{ "Queue" = "Overlay" "IgnoreProjector" = "True" "RenderType" = "Transparent" } + Tags{ "Queue" = "Overlay" "IgnoreProjector" = "True" "RenderType" = "Transparent" } - Pass { + Pass { - //Blend SrcAlpha OneMinusSrcAlpha, Zero One - Blend One One - Lighting Off Cull Back ZTest Always ZWrite Off Fog { Mode Off } + //Blend SrcAlpha OneMinusSrcAlpha, Zero One + Blend One One + Lighting Off Cull Back ZTest Always ZWrite Off Fog { Mode Off } - CGPROGRAM - #pragma vertex vert - #pragma fragment frag - #pragma target 3.0 + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 3.0 + #include "UnityCG.cginc" + #include "Assets/Shaders/Include/Brush.cginc" + #include "Assets/Shaders/Include/ColorSpace.cginc" - #include "UnityCG.cginc" - #include "Assets/Shaders/Include/Brush.cginc" - #include "Assets/Shaders/Include/ColorSpace.cginc" + struct appdata_t { + float4 vertex : POSITION; + fixed4 color : COLOR; + float3 normal : NORMAL; - struct appdata_t { - float4 vertex : POSITION; - fixed4 color : COLOR; - float3 normal : NORMAL; - }; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; - struct v2f { - float4 vertex : POSITION; - float3 viewDir : TEXCOORD0; - float3 normal : NORMAL; + struct v2f { + float4 vertex : POSITION; + float3 viewDir : TEXCOORD0; + float3 normal : NORMAL; - }; + UNITY_VERTEX_OUTPUT_STEREO + }; - uniform float4 _Color; + uniform float4 _Color; - v2f vert (appdata_t v) { - v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); - o.viewDir = normalize(ObjSpaceViewDir(v.vertex)); - o.normal = normalize(v.normal); - return o; - } + v2f vert (appdata_t v) { + v2f o; - fixed4 frag (v2f i) : COLOR { - float facingRatio = saturate(dot(i.viewDir, i.normal)); - facingRatio = 1-facingRatio; - float4 outColor = _Color * facingRatio; - outColor.w = 1; - return outColor; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); - } - ENDCG + o.vertex = UnityObjectToClipPos(v.vertex); + o.viewDir = normalize(ObjSpaceViewDir(v.vertex)); + o.normal = normalize(v.normal); + return o; + } + + fixed4 frag (v2f i) : COLOR { + float facingRatio = saturate(dot(i.viewDir, i.normal)); + facingRatio = 1-facingRatio; + float4 outColor = _Color * facingRatio; + outColor.w = 1; + return outColor; + } + ENDCG + } } } -} - -Fallback "Unlit/Diffuse" - + Fallback "Unlit/Diffuse" } diff --git a/Assets/Shaders/NewSketchButton.shader b/Assets/Shaders/NewSketchButton.shader index 4db765de14..e3243e19bc 100644 --- a/Assets/Shaders/NewSketchButton.shader +++ b/Assets/Shaders/NewSketchButton.shader @@ -49,12 +49,16 @@ Shader "Custom/NewSketchButton" { float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vertInflate (appdata_t v, float currentSliceIndex) { @@ -62,6 +66,11 @@ Shader "Custom/NewSketchButton" { float ratioMultiplier = .5; v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.tangent.w = 1.0; float totalNumSlices = 5; float ratio = (currentSliceIndex / (totalNumSlices - 1)); diff --git a/Assets/Shaders/Panel.shader b/Assets/Shaders/Panel.shader index 717ecff25a..f979e7c48f 100644 --- a/Assets/Shaders/Panel.shader +++ b/Assets/Shaders/Panel.shader @@ -34,12 +34,16 @@ SubShader { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float4 wpos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -49,6 +53,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.wpos = mul(unity_ObjectToWorld, v.vertex); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Shaders/PanelButton.shader b/Assets/Shaders/PanelButton.shader index ff220e0f53..8e2e775b68 100644 --- a/Assets/Shaders/PanelButton.shader +++ b/Assets/Shaders/PanelButton.shader @@ -27,6 +27,8 @@ Shader "Custom/PanelButton" { #pragma vertex vert #pragma fragment frag #pragma multi_compile __ HDR_EMULATED HDR_SIMPLE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/Hdr.cginc" @@ -38,16 +40,25 @@ Shader "Custom/PanelButton" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + if (_Activated) v.vertex.xyz += float3(0,0,-.2); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = float4(v.texcoord.xy, 0, _PanelMipmapBias); diff --git a/Assets/Shaders/PanelButtonCutout.shader b/Assets/Shaders/PanelButtonCutout.shader index d68b65eb19..739517b6bb 100644 --- a/Assets/Shaders/PanelButtonCutout.shader +++ b/Assets/Shaders/PanelButtonCutout.shader @@ -29,6 +29,8 @@ Shader "Custom/PanelButtonCutout" { #pragma vertex vert #pragma fragment frag #pragma multi_compile __ HDR_EMULATED HDR_SIMPLE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/Hdr.cginc" @@ -42,16 +44,25 @@ Shader "Custom/PanelButtonCutout" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + if (_Activated) v.vertex.xyz += float3(0,0,-.2); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = float4(v.texcoord.xy, 0, _PanelMipmapBias); diff --git a/Assets/Shaders/PanelButton_Atlas.shader b/Assets/Shaders/PanelButton_Atlas.shader index 5f9c5f275e..3a954c88cf 100644 --- a/Assets/Shaders/PanelButton_Atlas.shader +++ b/Assets/Shaders/PanelButton_Atlas.shader @@ -40,16 +40,25 @@ Shader "Custom/PanelButton_Atlas" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = float4(v.texcoord.xy, 0, _PanelMipmapBias); return o; diff --git a/Assets/Shaders/PanelButton_AtlasActive.shader b/Assets/Shaders/PanelButton_AtlasActive.shader index b661a3e761..044f6c8c59 100644 --- a/Assets/Shaders/PanelButton_AtlasActive.shader +++ b/Assets/Shaders/PanelButton_AtlasActive.shader @@ -44,16 +44,25 @@ Shader "Custom/PanelButton_AtlasActive" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = float4(v.texcoord.xy, 0, _PanelMipmapBias); return o; diff --git a/Assets/Shaders/ParticleDustBokeh.shader b/Assets/Shaders/ParticleDustBokeh.shader index ea1ba76b81..9137a5a2e9 100644 --- a/Assets/Shaders/ParticleDustBokeh.shader +++ b/Assets/Shaders/ParticleDustBokeh.shader @@ -45,6 +45,8 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -52,6 +54,8 @@ Category { fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float bokeh : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -60,6 +64,10 @@ Category { { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); float4 viewPos = mul(UNITY_MATRIX_MV, v.vertex); diff --git a/Assets/Shaders/Pcx/Point.shader b/Assets/Shaders/Pcx/Point.shader index d9cf0fa56f..3f185ee628 100644 --- a/Assets/Shaders/Pcx/Point.shader +++ b/Assets/Shaders/Pcx/Point.shader @@ -72,6 +72,11 @@ Shader "Point Cloud/Point" #endif Varyings o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(Varyings, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.position = UnityObjectToClipPos(pos); o.color = col; #ifdef _DISTANCE_ON diff --git a/Assets/Shaders/PinCushionItem.shader b/Assets/Shaders/PinCushionItem.shader index a6c09c5013..4e2d537faa 100644 --- a/Assets/Shaders/PinCushionItem.shader +++ b/Assets/Shaders/PinCushionItem.shader @@ -27,6 +27,8 @@ Shader "Custom/PinCushionItem" { #pragma vertex vert #pragma fragment frag #pragma multi_compile __ HDR_EMULATED HDR_SIMPLE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" #include "Assets/Shaders/Include/Hdr.cginc" @@ -38,17 +40,25 @@ Shader "Custom/PinCushionItem" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Smash inward along Z axis based on 0-1 ratio v.vertex.z = v.vertex.z * _Activated - v.vertex.z; diff --git a/Assets/Shaders/PolyAssetThumbnail.shader b/Assets/Shaders/PolyAssetThumbnail.shader index ecaa43723d..ee9cab5277 100644 --- a/Assets/Shaders/PolyAssetThumbnail.shader +++ b/Assets/Shaders/PolyAssetThumbnail.shader @@ -40,21 +40,29 @@ Shader "Custom/PolyAssetThumbnail" { struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { + v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); v.uv -= 0.5; // Adjust UVs of 1:1 mesh for Poly's 4:3 image format v.uv.x /= 1.333; v.uv += 0.5; - - v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; diff --git a/Assets/Shaders/ProfileIcon.shader b/Assets/Shaders/ProfileIcon.shader index 50a5efa72a..c1f0141851 100644 --- a/Assets/Shaders/ProfileIcon.shader +++ b/Assets/Shaders/ProfileIcon.shader @@ -35,12 +35,16 @@ Shader "Custom/ProfileIcon" { { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; fixed4 _Color; @@ -53,6 +57,11 @@ Shader "Custom/ProfileIcon" { v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; diff --git a/Assets/Shaders/ReferenceImage.shader b/Assets/Shaders/ReferenceImage.shader index ac40a51571..86e9d992e1 100644 --- a/Assets/Shaders/ReferenceImage.shader +++ b/Assets/Shaders/ReferenceImage.shader @@ -47,14 +47,23 @@ Shader "Custom/ReferenceImage" { struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { + v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); v.uv -= 0.5; @@ -70,7 +79,6 @@ Shader "Custom/ReferenceImage" { v.uv += 0.5; - v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; diff --git a/Assets/Shaders/SharingState.shader b/Assets/Shaders/SharingState.shader index 0fbb40ded8..38467aefc3 100644 --- a/Assets/Shaders/SharingState.shader +++ b/Assets/Shaders/SharingState.shader @@ -45,17 +45,25 @@ SubShader { float4 vertex : POSITION; float3 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Hold animation 'til _Ratio < 0 if (_Ratio == 0) { duration = 0.0f; diff --git a/Assets/Shaders/SketchbookButton.shader b/Assets/Shaders/SketchbookButton.shader index 34e4c473a2..25b74d5ec7 100644 --- a/Assets/Shaders/SketchbookButton.shader +++ b/Assets/Shaders/SketchbookButton.shader @@ -46,22 +46,31 @@ Shader "Custom/SketchbookButton" { float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float4 color : COLOR; float4 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vertInflate (appdata_t v, float currentSliceIndex) { - float ratioMultiplier = .5; - + v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + v.tangent.w = 1.0; float totalNumSlices = 5; float ratio = (currentSliceIndex / (totalNumSlices - 1)); + float ratioMultiplier = .5; v.vertex.z -= ratioMultiplier * ratio * _Distance; totalNumSlices = 5; diff --git a/Assets/Shaders/Skybox.shader b/Assets/Shaders/Skybox.shader index 459a69a4df..60fca876ba 100644 --- a/Assets/Shaders/Skybox.shader +++ b/Assets/Shaders/Skybox.shader @@ -49,16 +49,25 @@ SubShader { struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float3 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + float4 quatConjugate = float4(-_SkyboxRotation.x, -_SkyboxRotation.y, -_SkyboxRotation.z, _SkyboxRotation.w); o.vertex = UnityObjectToClipPos(quat_mult(_SkyboxRotation, quat_mult(v.vertex, quatConjugate))); o.texcoord = v.vertex; diff --git a/Assets/Shaders/SnapGrid3D.shader b/Assets/Shaders/SnapGrid3D.shader index a43ce07c0b..cfb0bf8dba 100644 --- a/Assets/Shaders/SnapGrid3D.shader +++ b/Assets/Shaders/SnapGrid3D.shader @@ -76,12 +76,16 @@ Shader "Custom/Grid3D" uint id : SV_VERTEXID; float4 vertex : POSITION; float4 pos : TEXCOORD2; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float4 pos : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO }; float3 calcQuadVertex(uint vtx_idx) // face 0:x 1:y 2:z @@ -120,6 +124,11 @@ Shader "Custom/Grid3D" v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + uint vtx_per_quad = 6; uint vtx_per_line = vtx_per_quad * 2; uint vtx_per_star = vtx_per_line * 3; diff --git a/Assets/Shaders/SnapshotCameraFlash.shader b/Assets/Shaders/SnapshotCameraFlash.shader index 279a70b7bf..5836f2d9db 100644 --- a/Assets/Shaders/SnapshotCameraFlash.shader +++ b/Assets/Shaders/SnapshotCameraFlash.shader @@ -41,6 +41,8 @@ Shader "Unlit/Snapshot Camera Flash" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f @@ -48,6 +50,8 @@ Shader "Unlit/Snapshot Camera Flash" float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -59,6 +63,11 @@ Shader "Unlit/Snapshot Camera Flash" v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); diff --git a/Assets/Shaders/StencilSurface.shader b/Assets/Shaders/StencilSurface.shader index a020441af8..9db03b8531 100644 --- a/Assets/Shaders/StencilSurface.shader +++ b/Assets/Shaders/StencilSurface.shader @@ -49,6 +49,8 @@ CGINCLUDE float4 vertex : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -57,12 +59,18 @@ CGINCLUDE float3 normal : TEXCOORD2; float2 texcoord : TEXCOORD3; float4 screenPos : TEXCOORD4; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = v.vertex; o.vertex = UnityObjectToClipPos(v.vertex); diff --git a/Assets/Shaders/StencilSurfaceTutorial.shader b/Assets/Shaders/StencilSurfaceTutorial.shader index e4ff076637..8c01c331cf 100644 --- a/Assets/Shaders/StencilSurfaceTutorial.shader +++ b/Assets/Shaders/StencilSurfaceTutorial.shader @@ -42,6 +42,8 @@ CGINCLUDE float4 vertex : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { @@ -50,12 +52,18 @@ CGINCLUDE float3 normal : TEXCOORD2; float2 texcoord : TEXCOORD3; float4 screenPos : TEXCOORD4; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + // Shrink the stencil slightly to prevent z fighting when the user is drawing on top of it. float stencilShrinkAmount = .005f; float curvedStencilShrinkAmount = .015f; diff --git a/Assets/Shaders/SwatchAdditive.shader b/Assets/Shaders/SwatchAdditive.shader index a0f15a3ae4..f65421047e 100644 --- a/Assets/Shaders/SwatchAdditive.shader +++ b/Assets/Shaders/SwatchAdditive.shader @@ -41,11 +41,15 @@ Category { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -53,6 +57,11 @@ Category { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); return o; diff --git a/Assets/Shaders/SwatchBloom.shader b/Assets/Shaders/SwatchBloom.shader index 6400d653d8..1387fda310 100644 --- a/Assets/Shaders/SwatchBloom.shader +++ b/Assets/Shaders/SwatchBloom.shader @@ -48,17 +48,26 @@ Category { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(_Color, _EmissionGain); diff --git a/Assets/Shaders/ThreeDeeFadeText.shader b/Assets/Shaders/ThreeDeeFadeText.shader index 5a6a2e4f4d..87c86b970b 100644 --- a/Assets/Shaders/ThreeDeeFadeText.shader +++ b/Assets/Shaders/ThreeDeeFadeText.shader @@ -34,12 +34,16 @@ SubShader { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float4 wpos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -49,6 +53,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.wpos = mul(unity_ObjectToWorld, v.vertex); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Shaders/ThreeDeeText.shader b/Assets/Shaders/ThreeDeeText.shader index d8617e3591..7463f759d2 100644 --- a/Assets/Shaders/ThreeDeeText.shader +++ b/Assets/Shaders/ThreeDeeText.shader @@ -35,12 +35,16 @@ SubShader { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float4 wpos : TEXCOORD1; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -51,6 +55,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.wpos = mul(unity_ObjectToWorld, v.vertex); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Shaders/TiltBrushLogo_Progress.shader b/Assets/Shaders/TiltBrushLogo_Progress.shader index ed9b0dd17a..d5107c0aa5 100644 --- a/Assets/Shaders/TiltBrushLogo_Progress.shader +++ b/Assets/Shaders/TiltBrushLogo_Progress.shader @@ -37,11 +37,15 @@ Shader "Custom/TiltBrushLogo_Progress" { struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv_MainTex : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; // Creates a smooth in and out line from min to max over the range t = [0, 1]. @@ -62,6 +66,11 @@ Shader "Custom/TiltBrushLogo_Progress" { v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv_MainTex = TRANSFORM_TEX(v.uv, _MainTex); return o; diff --git a/Assets/Shaders/TransformControllerOverlay.shader b/Assets/Shaders/TransformControllerOverlay.shader index 9a49279bc9..3c9c30842b 100644 --- a/Assets/Shaders/TransformControllerOverlay.shader +++ b/Assets/Shaders/TransformControllerOverlay.shader @@ -44,14 +44,23 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex + float4(v.normal * _BlackOutlineInflation * _Intensity,0)); return o; } @@ -82,10 +91,14 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -93,6 +106,11 @@ Category { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + _ColoredOutlineInflation += _BaseInflation * abs(sin(_Time.w*2)); o.vertex = UnityObjectToClipPos(v.vertex + float4(v.normal * _ColoredOutlineInflation * _Intensity,0)); return o; diff --git a/Assets/Shaders/TransformLine.shader b/Assets/Shaders/TransformLine.shader index 20ec12c707..ae061b1791 100644 --- a/Assets/Shaders/TransformLine.shader +++ b/Assets/Shaders/TransformLine.shader @@ -36,10 +36,14 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -47,7 +51,12 @@ Category { v2f vert (appdata_t v) { v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = UnityObjectToClipPos(v.vertex); return o; } diff --git a/Assets/Shaders/TransformLineHint.shader b/Assets/Shaders/TransformLineHint.shader index ae48bc8840..3271e3df04 100644 --- a/Assets/Shaders/TransformLineHint.shader +++ b/Assets/Shaders/TransformLineHint.shader @@ -39,10 +39,14 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float3 normal : NORMAL; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -50,7 +54,12 @@ Category { v2f vert (appdata_t v) { v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = UnityObjectToClipPos(v.vertex); return o; } diff --git a/Assets/Shaders/TutorialNotification.shader b/Assets/Shaders/TutorialNotification.shader index 4a0e57a862..55034f2927 100644 --- a/Assets/Shaders/TutorialNotification.shader +++ b/Assets/Shaders/TutorialNotification.shader @@ -43,12 +43,16 @@ Category { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; @@ -56,6 +60,11 @@ Category { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.color = v.color; o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); diff --git a/Assets/Shaders/TwoTexAnimation.shader b/Assets/Shaders/TwoTexAnimation.shader index 87f237f786..faea0197aa 100644 --- a/Assets/Shaders/TwoTexAnimation.shader +++ b/Assets/Shaders/TwoTexAnimation.shader @@ -38,12 +38,16 @@ Shader "Custom/TwoTexAnimation" { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -55,6 +59,11 @@ Shader "Custom/TwoTexAnimation" v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; diff --git a/Assets/Shaders/Unlit-BackFaces.shader b/Assets/Shaders/Unlit-BackFaces.shader index 0c9ca72e5c..9c91d19f3d 100644 --- a/Assets/Shaders/Unlit-BackFaces.shader +++ b/Assets/Shaders/Unlit-BackFaces.shader @@ -32,11 +32,14 @@ SubShader { struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; - UNITY_FOG_COORDS(1) + UNITY_FOG_COORDS(1) + UNITY_VERTEX_OUTPUT_STEREO }; fixed4 _Color; @@ -44,6 +47,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); UNITY_TRANSFER_FOG(o,o.vertex); return o; diff --git a/Assets/Shaders/Unlit-Diffuse.shader b/Assets/Shaders/Unlit-Diffuse.shader index 6af1b31e40..00a566ac96 100644 --- a/Assets/Shaders/Unlit-Diffuse.shader +++ b/Assets/Shaders/Unlit-Diffuse.shader @@ -37,10 +37,14 @@ SubShader { struct appdata_t { float4 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -48,6 +52,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); return o; } diff --git a/Assets/Shaders/Unlit-DiffuseNoCull.shader b/Assets/Shaders/Unlit-DiffuseNoCull.shader index 4502e12345..f6dfe3b848 100644 --- a/Assets/Shaders/Unlit-DiffuseNoCull.shader +++ b/Assets/Shaders/Unlit-DiffuseNoCull.shader @@ -36,11 +36,13 @@ SubShader { struct appdata_t { float4 vertex : POSITION; + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; UNITY_FOG_COORDS(1) + UNITY_VERTEX_OUTPUT_STEREO }; uniform float4 _Color; @@ -49,6 +51,11 @@ SubShader { { PrepForOds(v.vertex); v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); UNITY_TRANSFER_FOG(o,o.vertex); return o; diff --git a/Assets/Shaders/Unlit-TextureNoCull.shader b/Assets/Shaders/Unlit-TextureNoCull.shader index c804aaf969..9677c8acb2 100644 --- a/Assets/Shaders/Unlit-TextureNoCull.shader +++ b/Assets/Shaders/Unlit-TextureNoCull.shader @@ -32,11 +32,15 @@ SubShader { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -45,6 +49,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Shaders/Unlit-TextureTint.shader b/Assets/Shaders/Unlit-TextureTint.shader index cd0f2b47a3..80b7217ff9 100644 --- a/Assets/Shaders/Unlit-TextureTint.shader +++ b/Assets/Shaders/Unlit-TextureTint.shader @@ -33,11 +33,15 @@ SubShader { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; @@ -47,6 +51,11 @@ SubShader { v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); diff --git a/Assets/Shaders/UnlitHDRColorButton.shader b/Assets/Shaders/UnlitHDRColorButton.shader index 62f3f7a393..48364b6df7 100644 --- a/Assets/Shaders/UnlitHDRColorButton.shader +++ b/Assets/Shaders/UnlitHDRColorButton.shader @@ -39,15 +39,24 @@ Shader "Custom/UnlitHDRColorButton" { struct Input { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (Input v) { - v2f o = (v2f)0; + v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(Input, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; diff --git a/Assets/Shaders/VisualizerRing.shader b/Assets/Shaders/VisualizerRing.shader index a36e003ea6..63d8285ade 100644 --- a/Assets/Shaders/VisualizerRing.shader +++ b/Assets/Shaders/VisualizerRing.shader @@ -46,17 +46,26 @@ Shader "Custom/VisualizerRing" { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); o.color = bloomColor(v.color, _EmissionGain); diff --git a/Assets/Shaders/WaveformIndicator.shader b/Assets/Shaders/WaveformIndicator.shader index 0830fce092..fb9b0e11cf 100644 --- a/Assets/Shaders/WaveformIndicator.shader +++ b/Assets/Shaders/WaveformIndicator.shader @@ -27,6 +27,8 @@ Shader "Custom/WaveformIndicator" { #pragma vertex vert #pragma fragment frag #pragma multi_compile __ AUDIO_REACTIVE + + #include "UnityCG.cginc" #include "Assets/Shaders/Include/Brush.cginc" fixed4 _Color; @@ -37,16 +39,25 @@ Shader "Custom/WaveformIndicator" { struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; diff --git a/Assets/ThirdParty/jintiao_FXAA/FXAA.shader b/Assets/ThirdParty/jintiao_FXAA/FXAA.shader index a621eac56f..7b3ad88508 100644 --- a/Assets/ThirdParty/jintiao_FXAA/FXAA.shader +++ b/Assets/ThirdParty/jintiao_FXAA/FXAA.shader @@ -24,24 +24,33 @@ { float4 vertex : POSITION; float2 uv : TEXCOORD0; + + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; + + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } - sampler2D _MainTex; + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); float4 _MainTex_TexelSize; float _ContrastThreshold; @@ -65,7 +74,7 @@ float SampleLuminance(float2 uv) { - return LinearRgbToLuminance(saturate(tex2D(_MainTex, uv).rgb)); + return LinearRgbToLuminance(saturate(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv).rgb)); } @@ -221,7 +230,7 @@ { LuminanceData l = SampleLuminanceNeighborhood(uv); if (ShouldSkipPixel(l)) - return tex2D(_MainTex, uv); + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv); float pixelBlend = DeterminePixelBlendFactor(l); EdgeData e = DetermineEdge(l); @@ -236,12 +245,14 @@ { uv.x += e.pixelStep * finalBlend; } - return tex2Dlod(_MainTex, float4(uv, 0, 0)); + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, float4(uv, 0, 0)); } fixed4 frag (v2f i) : SV_Target { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + return ApplyFXAA(i.uv); } ENDCG diff --git a/Packages/manifest.json b/Packages/manifest.json index 5a5a6f0e68..e6737655ab 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -9,7 +9,7 @@ "com.unity.cloud.gltfast": "6.0.1", "com.unity.editorcoroutines": "1.0.0", "com.unity.formats.usd": "1.0.3-preview.2", - "com.unity.ide.rider": "3.0.24", + "com.unity.ide.rider": "3.0.28", "com.unity.ide.visualstudio": "2.0.20", "com.unity.inputsystem": "https://github.com/icosa-mirror/com.unity.inputsystem.git#open-brush", "com.unity.localization": "1.4.2", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 095dbb195c..6d1a2c8a97 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -101,7 +101,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.rider": { - "version": "3.0.24", + "version": "3.0.28", "depth": 0, "source": "registry", "dependencies": { diff --git a/Support/steam/app.vdf.j2 b/Support/steam/app.vdf.j2 index bee4ff242f..cb2b3f771b 100644 --- a/Support/steam/app.vdf.j2 +++ b/Support/steam/app.vdf.j2 @@ -11,5 +11,6 @@ { "{{ OPEN_BRUSH_WINDOWS_DEPOT_ID }}" build_windows_openxr/main_depot.vdf "{{ OPEN_BRUSH_MAC_DEPOT_ID }}" build_macos/main_depot.vdf + "{{ OPEN_BRUSH_LINUX_DEPOT_ID }}" build_linux/main_depot.vdf } } diff --git a/Support/steam/installscript_win.vdf.j2 b/Support/steam/installscript_win.vdf.j2 index 9ed6105813..744be6c7ea 100644 --- a/Support/steam/installscript_win.vdf.j2 +++ b/Support/steam/installscript_win.vdf.j2 @@ -12,12 +12,12 @@ InstallScript { } "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Icosa.OpenBrush.File\\DefaultIcon" { string { - "(Default)" "%INSTALLDIR%\\{{ OPEN_BRUSH_EXECUTABLE }}" + "(Default)" "%INSTALLDIR%\\{{ OPEN_BRUSH_WINDOWS_EXECUTABLE }}" } } "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Icosa.OpenBrush.File\\Shell\\Open\\Command" { string { - "(Default)" "%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell -windowstyle hidden -c \"try { $s=[uri]::EscapeDataString('%1'); (new-object System.Net.WebClient).DownloadString('http://localhost:40074/load?'+$s) } catch { & '%INSTALLDIR%\\{{ OPEN_BRUSH_EXECUTABLE }}' '%1' }\"" + "(Default)" "%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell -windowstyle hidden -c \"try { $s=[uri]::EscapeDataString('%1'); (new-object System.Net.WebClient).DownloadString('http://localhost:40074/load?'+$s) } catch { & '%INSTALLDIR%\\{{ OPEN_BRUSH_WINDOWS_EXECUTABLE }}' '%1' }\"" } } "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\tiltbrush" { @@ -30,17 +30,17 @@ InstallScript { } "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\tiltbrush\\DefaultIcon" { string { - "(Default)" "%INSTALLDIR%\\{{ OPEN_BRUSH_EXECUTABLE }}" + "(Default)" "%INSTALLDIR%\\{{ OPEN_BRUSH_WINDOWS_EXECUTABLE }}" } } "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\tiltbrush\\Shell\\Open\\Command" { string { - "(Default)" "%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell -windowstyle hidden -c \"try { $s=[uri]::EscapeDataString('%1'); (new-object System.Net.WebClient).DownloadString('http://localhost:40074/load?'+$s) } catch { & '%INSTALLDIR%\\{{ OPEN_BRUSH_EXECUTABLE }}' '%1' }\"" + "(Default)" "%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell -windowstyle hidden -c \"try { $s=[uri]::EscapeDataString('%1'); (new-object System.Net.WebClient).DownloadString('http://localhost:40074/load?'+$s) } catch { & '%INSTALLDIR%\\{{ OPEN_BRUSH_WINDOWS_EXECUTABLE }}' '%1' }\"" } } } Firewall { - "Open Brush" "%INSTALLDIR%\\{{ OPEN_BRUSH_EXECUTABLE }}" + "Open Brush" "%INSTALLDIR%\\{{ OPEN_BRUSH_WINDOWS_EXECUTABLE }}" } } diff --git a/Support/steam/main_depot.linux.vdf.j2 b/Support/steam/main_depot.linux.vdf.j2 new file mode 100644 index 0000000000..90ab8bcbfe --- /dev/null +++ b/Support/steam/main_depot.linux.vdf.j2 @@ -0,0 +1,25 @@ +"DepotBuildConfig" +{ + // # Set your assigned depot ID here + "DepotID" "{{ OPEN_BRUSH_LINUX_DEPOT_ID }}" + + "ContentRoot" "build_linux/StandaloneLinux64" + + "FileMapping" + { + // Include all files in the build output directory (ContentRoot) + "LocalPath" "*" + + // Destination is the main install directory + "DepotPath" "." + + // If LocalPath contains wildcards, setting this means that all + // matching files within subdirectories of LocalPath will also + // be included. + "recursive" "1" + } + + // but exclude all symbol files + "FileExclusion" "*.pdb" + "FileExclusion" "build_log.txt" +}