testss
This commit is contained in:
13
Library/PackageCache/com.unity.shadergraph@11.0.0/.npmignore
Normal file
13
Library/PackageCache/com.unity.shadergraph@11.0.0/.npmignore
Normal file
@@ -0,0 +1,13 @@
|
||||
artifacts/**
|
||||
build/**
|
||||
/Editor/Testing*
|
||||
/.collabignore
|
||||
/.gitignore
|
||||
/.gitmodules
|
||||
.npmignore
|
||||
upm-ci~/**
|
||||
.Editor/**
|
||||
.yamato/**
|
||||
*.zip*
|
||||
TestRunnerOptions.json
|
||||
.idea/**
|
608
Library/PackageCache/com.unity.shadergraph@11.0.0/CHANGELOG.md
Normal file
608
Library/PackageCache/com.unity.shadergraph@11.0.0/CHANGELOG.md
Normal file
@@ -0,0 +1,608 @@
|
||||
# Changelog
|
||||
All notable changes to this package are documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [11.0.0] - 2020-10-21
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
- Fixed an issue where nodes with ports on one side would appear incorrectly on creation [1262050]
|
||||
- Fixed a broken link in the TOC to Main Preview
|
||||
- Fixed an issue with the Gradient color picker displaying different values than the selected color.
|
||||
- Fixed an issue where blackboard properties when dragged wouldn't scroll the list of properties to show the user more of the property list [1293632]
|
||||
- Fixed an issue where, when blackboard properties were dragged and then the user hit the "Escape" key, the drag indicator would still be visible
|
||||
- Fixed an issue where renaming blackboard properties through the Blackboard wouldn't actually change the underlying property name
|
||||
- Fixed an issue where blackboard wasn't resizable from all directions like the Inspector and Main Preview
|
||||
- Fixed an issue where deleting a property node while your mouse is over it leaves the property highlighted in the blackboard [1238635]
|
||||
- Fixed an issue where Float/Vector1 properties did not have the ability to be edited using a slider in the Inspector like the other Vector types
|
||||
- Fixed an issue with the Gradient color picker displaying different values than the selected color.
|
||||
- Fixed an issue with inactive node deletion throwing a superfluous exception.
|
||||
- Fixed an issue on upgrading graphs with inactive Master Nodes causing null ref errors. [1298867](https://issuetracker.unity3d.com/product/unity/issues/guid/1298867/)
|
||||
- Fixed the ViewDirection Node in Tangent space's calculation to match how the transform node works.
|
||||
- Boolean keywords now have no longer require their reference name to end in _ON to show up in the Material inspector [1306820] (https://issuetracker.unity3d.com/product/unity/issues/guid/1306820/)
|
||||
- Newly created properties and keywords will no longer use obfuscated GUID-based reference names in the shader code [1300484]
|
||||
- Fixed an issue where generated `BuildVertexDescriptionInputs()` produced an HLSL warning, "implicit truncation of vector type" [1299179](https://issuetracker.unity3d.com/product/unity/issues/guid/1299179/)
|
||||
- Fixed issue with SRP Batcher compatibility [1310624]
|
||||
- Fixed issue with Hybrid renderer compatibility [1296776]
|
||||
- Fixed the Custom Editor GUI field in the Graph settings that was ignored.
|
||||
- Fixed an issue where SampleRawCubemapNode were requiring the Normal in Object space instead of World space [1307962]
|
||||
- Fixed a bug in master node preview generation that failed compilation when a block was deleted [1319066] (https://issuetracker.unity3d.com/issues/shadergraph-deleting-stack-blocks-of-universal-rp-targeted-shadergraph-causes-the-main-preview-to-fail-to-compile)
|
||||
- Fixed a bug where property deduplication was failing and spamming errors [1317809] (https://issuetracker.unity3d.com/issues/console-error-when-adding-a-sample-texture-operator-when-a-sampler-state-property-is-present-in-blackboard)
|
||||
- Fixed a bug where synchronously compiling an unencountered shader variant for preview was causing long delays in graph updates [1324429]
|
||||
- Fixed a issue when clicking a property in subgraph blackboard will throw null exception errors.[1328377](https://issuetracker.unity3d.com/product/unity/issues/guid/1328377/)
|
||||
- Fixed an issue where an integer property would be exposed in the material inspector as a float [1332563]
|
||||
|
||||
## [10.3.0] - 2020-11-03
|
||||
|
||||
### Added
|
||||
- Users can now manually control the preview mode of nodes in the graph, and subgraphs
|
||||
|
||||
### Changed
|
||||
- Texture and SamplerState types are now HLSL structures (defined in com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl). CustomFunctionNode use of the old plain types is supported, but the user should upgrade to structures to avoid bugs.
|
||||
- The shader graph inspector window will now switch to the "Node Settings" tab whenever a property/node/other selectable item in the graph is clicked on to save the user a click
|
||||
|
||||
### Fixed
|
||||
- Fixed an issue where shaders could be generated with CR/LF ("\r\n") instead of just LF ("\n") line endings [1286430]
|
||||
- Fixed Custom Function Node to display the name of the custom function. [1293575]
|
||||
- Addressed C# warning 0649 generated by unassigned structure members
|
||||
- Fixed using TexelSize or reading sampler states from Textures output from a Subgraph or Custom Function Node [1284036]
|
||||
- Shaders using SamplerState types now compile with GLES2 (SamplerStates are ignored, falls back to Texture-associated sampler state) [1292031]
|
||||
- Fixed an issue where the horizontal scrollbar at the bottom of the shader graph inspector window could not be used due to the resizing widget always taking priority over it
|
||||
- Fixed an issue where the shader graph inspector window could be resized past the edges of the shader graph view
|
||||
- Fixed an issue where resizing the shader graph inspector window sometimes had unexpected results
|
||||
- Fixed Graph Inspector scaling that was allocating too much space to the labels [1268134]
|
||||
- Fixed an issue on upgrading graphs with inactive Master Nodes causing null ref errors. [1298867](https://issuetracker.unity3d.com/product/unity/issues/guid/1298867/)
|
||||
- Fixed an issue where blackboard properties when dragged wouldn't scroll the list of properties to show the user more of the property list [1293632]
|
||||
- Fixed an issue where, when blackboard properties were dragged and then the user hit the "Escape" key, the drag indicator would still be visible
|
||||
- Fixed an issue where renaming blackboard properties through the Blackboard wouldn't actually change the underlying property name
|
||||
- Fixed an issue where blackboard wasn't resizable from all directions like the Inspector and Main Preview
|
||||
- Fixed an issue where deleting a property node while your mouse is over it leaves the property highlighted in the blackboard [1238635]
|
||||
- Fixed an issue where Float/Vector1 properties did not have the ability to be edited using a slider in the Inspector like the other Vector types
|
||||
- Fixed some issues with our Convert To Subgraph contextual menu to allow passthrough and fix inputs/outputs getting lost.
|
||||
- Fixed issue where a NullReferenceException would be thrown on resetting reference name for a Shader Graph property
|
||||
- Fixed an upgrade issue where old ShaderGraph files with a weird/bugged state would break on update to master stack [1255011]
|
||||
- Fixed a bug where non-word characters in an enum keyword reference name would break the graph. [1270168](https://issuetracker.unity3d.com/product/unity/issues/guid/1270168)
|
||||
- Fixed issue where a NullReferenceException would be thrown on resetting reference name for a Shader Graph property
|
||||
- Fixed an issue with the Gradient color picker displaying different values than the selected color.
|
||||
|
||||
## [10.2.0] - 2020-10-19
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
- Renamed the existing Sample Cubemap Node to Sample Reflected Cubemap Node, and created a new Sample Cubemap Node that samples cubemaps with a direction.
|
||||
- Removed unnecessary HDRP constant declarations used by Material inspector from the UnityPerMaterial cbuffer [1285701]
|
||||
- Virtual Texture properties are now forced to be Exposed, as they do not work otherwise [1256374]
|
||||
|
||||
### Fixed
|
||||
- Fixed an issue where old ShaderGraphs would import non-deterministically, changing their embedded property names each import [1283800]
|
||||
- Using the TexelSize node on a ShaderGraph texture property is now SRP batchable [1284029]
|
||||
- Fixed an issue where Mesh Deformation nodes did not have a category color. [1227081](https://issuetracker.unity3d.com/issues/shadergraph-color-mode-vertex-skinning-catagory-has-no-color-associated-with-it)
|
||||
- Fixed SampleTexture2DLOD node to return opaque black on unsupported platforms [1241602]
|
||||
- ShaderGraph now detects when a SubGraph is deleted while being used by a SubGraph node, and displays appropriate errors [1206438]
|
||||
- Fixed an issue where the Main Preview window rendered too large on small monitors during first open. [1254392]
|
||||
- Fixed an issue where Block nodes using Color slots would not be automatically removed from the Master Stack. [1259794]
|
||||
- Fixed an issue where the Create Node menu would not close when pressing the Escape key. [1263667]
|
||||
- Fixed an issue with the Preview Manager not updating correctly when deleting an edge that was created with a node (dragging off an existing node slot)
|
||||
- Fixed an issue where ShaderGraph could not read matrices from a Material or MaterialPropertyBlock while rendering with SRP batcher [1256374]
|
||||
- Fixed an issue where user setting a property to not Exposed, Hybrid-Instanced would result in a non-Hybrid Global property [1285700]
|
||||
- Fixed an issue with Gradient when it is used as expose parameters. Generated code was failing [1285640 ]
|
||||
- Fixed the subgraph slot sorting function [1286805]
|
||||
- Fixed Parallax Occlusion Mapping not working in sub graphs. [1221317](https://issuetracker.unity3d.com/product/unity/issues/guid/1221317/)
|
||||
- All textures in a ShaderGraph, even those not used, will now be pulled into an Exported Package [1283902]
|
||||
- Fixed an issue where the presence of an HDRP DiffusionProfile property or node would cause the graph to fail to load when HDRP package was not present [1287904]
|
||||
- Fixed an issue where unknown type Nodes (i.e. HDRP-only nodes used without HDRP package) could be copied, resulting in an unloadable graph [1288475]
|
||||
- Fixed an issue where dropping HDRP-only properties from the blackboard field into the graph would soft-lock the graph [1288887]
|
||||
- Fixed an issue using the sample gradient macros in custom function nodes, which was using a scalar value instead of a vector value for the gradients [1299830]
|
||||
|
||||
## [10.1.0] - 2020-10-12
|
||||
|
||||
### Added
|
||||
- Added parallax mapping node and parallax occlusion mapping node.
|
||||
- Added the possibility to have multiple POM node in a single graph.
|
||||
- Added better error feedback when SampleVirtualTexture nodes run into issues with the VirtualTexture property inputs
|
||||
- Added ability for Shader Graph to change node behavior without impacting existing graphs via the “Allow Deprecated Nodes”
|
||||
|
||||
### Changed
|
||||
- Added method chaining support to shadergraph collection API.
|
||||
- Optimized ShaderSubGraph import dependencies to minimize unnecessary reimports when using CustomFunctionNode
|
||||
- Changed UI names from `Vector1` to `Float`
|
||||
- Renamed `Float` precision to `Single`
|
||||
- Cleaned up the UI to add/remove Targets
|
||||
- The * in the ShaderGraph title bar now indicates that the graph has been modified when compared to the state it was loaded, instead of compared to what is on disk
|
||||
- Cancelling a "Save changes on Close?" will now cancel the Close as well
|
||||
- When attempting to Save and encountering a Read Only file or other exception, ShaderGraph will allow the user to retry as many times as they like
|
||||
|
||||
### Fixed
|
||||
- Fixed a bug where ShaderGraph subgraph nodes would not update their slot names or order
|
||||
- Fixed an issue where very old ShaderGraphs would fail to load because of uninitialized data [1269616](https://issuetracker.unity3d.com/issues/shadergraph-matrix-split-and-matrix-combine-shadergraphs-in-shadergraph-automated-tests-dont-open-throw-error)
|
||||
- Fixed an issue where ShaderGraph previews didn't display correctly when setting a texture to "None" [1264932]
|
||||
- Fixed an issue with the SampleVirtualTexture node in ShaderGraph, where toggling Automatic Streaming would cause the node to incorrectly display four output slots [1271618]
|
||||
- Fixed an issue in ShaderGraph with integer-mode Vector1 properties throwing errors when the value is changed [1264930]
|
||||
- Fixed a bug where ShaderGraph would not load graphs using Procedural VT nodes when the nodes were the project had them disabled [1271598]
|
||||
- Fixed an issue where the ProceduralVT node was not updating any connected SampleVT nodes when the number of layers was changed [1274288]
|
||||
- Fixed an issue with how unknown nodes were treated during validation
|
||||
- Fixed an issue where ShaderGraph shaders did not reimport automatically when some of the included files changed [1269634]
|
||||
- Fixed an issue where building a context menu on a dragging block node would leave it floating and undo/redo would result in a soft-lock
|
||||
- Fixed an issue where ShaderGraph was logging error when edited in play mode [1274148].
|
||||
- Fixed a bug where properties copied over with their graph inputs would not hook up correctly in a new graph [1274306]
|
||||
- Fixed an issue where renaming a property in the blackboard at creation would trigger an error.
|
||||
- Fixed an issue where ShaderGraph shaders did not reimport automatically when missing dependencies were reintroduced [1182895]
|
||||
- Fixed an issue where ShaderGraph previews would not show error shaders when the active render pipeline is incompatible with the shader [1257015]
|
||||
- ShaderGraph DDX, DDY, DDXY, and NormalFromHeight nodes do not allow themselves to be connected to vertex shader, as the derivative instructions can't be used [1209087]
|
||||
- When ShaderGraph detects no active SRP, it will still continue to render the master preview, but it will use the error shader [1264642]
|
||||
- VirtualTexture is no longer allowed as a SubGraph output (it is not supported by current system) [1254483]
|
||||
- ShaderGraph Custom Function Node will now correctly convert function and slot names to valid HLSL identifiers [1258832]
|
||||
- Fixed an issue where ShaderGraph Custom Function Node would reorder slots when you modified them [1280106]
|
||||
- Fixed Undo handling when adding or removing Targets from a ShaderGraph [1257028]
|
||||
- Fixed an issue with detection of circular subgraph dependencies [1269841]
|
||||
- Fixed an issue where subgraph nodes were constantly changing their serialized data [1281975]
|
||||
- Modifying a subgraph will no longer cause ShaderGraphs that use them to "reload from disk?" [1198885]
|
||||
- Fixed issues with ShaderGraph title bar not correctly displaying the modified status * [1282031]
|
||||
- Fixed issues where ShaderGraph could discard modified data without user approval when closed [1170503]
|
||||
- Fixed an issue where ShaderGraph file dependency gathering would fail to include any files that didn't exist
|
||||
- Fixed issues with ShaderGraph detection and handling of deleted graph files
|
||||
- Fixed an issue where the ShaderGraph was corrupting the translation cache
|
||||
- Fixed an issue where ShaderGraph would not prompt the user to save unsaved changes after an assembly reload
|
||||
- Fixed an issue with Position Node not automatically upgrading
|
||||
- Fixed an issue where failing SubGraphs would block saving graph files using them (recursion check would throw exceptions) [1283425]
|
||||
- Fixed an issue where choosing "None" as the default texture for a texture property would not correctly preview the correct default color [1283782]
|
||||
- Fixed some bugs with Color Nodes and properties that would cause incorrect collorspace conversions
|
||||
|
||||
## [10.0.0] - 2019-06-10
|
||||
### Added
|
||||
- Added the Internal Inspector which allows the user to view data contained in selected nodes and properties in a new floating graph sub-window. Also added support for custom property drawers to let you visualize any data type you like and expose it to the inspector.
|
||||
- Added samples for Procedural Patterns to the package.
|
||||
- You can now use the right-click context menu to delete Sticky Notes.
|
||||
- You can now save your graph as a new Asset.
|
||||
- Added support for vertex skinning when you use the DOTS animation package.
|
||||
- You can now use the right-click context menu to set the precision on multiple selected nodes.
|
||||
- You can now select unused nodes in your graph.
|
||||
- When you start the Editor, Shader Graph now displays Properties in the Blackboard as collapsed.
|
||||
- Updated the zoom level to let you zoom in further.
|
||||
- Blackboard properties now have a __Duplicate__ menu option. When you duplicate properties, Shader Graph maintains the order, and inserts duplicates below the current selection.
|
||||
- When you convert a node to a Sub Graph, the dialog now opens up in the directory of the original graph that contained the node. If the new Sub Graph is outside this directory, it also remembers that path for the next dialog to ease folder navigation.
|
||||
- If Unity Editor Analytics are enabled, Shader Graph collects anonymous data about which nodes you use in your graphs. This helps the Shader Graph team focus our efforts on the most common graph scenarios, and better understand the needs of our customers. We don't track edge data and cannot recreate your graphs in any form.
|
||||
- The Create Node Menu now has a tree view and support for fuzzy field searching.
|
||||
- When a Shader Graph or Sub Graph Asset associated with a open window has been deleted, Unity now displays a dialog that asks whether you would like to save the graph as a new Asset or close the window.
|
||||
- Added a drop-down menu to the PBR Master Node that lets you select the final coordinate space of normals delivered from the fragment function.
|
||||
- Added support for users to drag and drop Blackboard Properties from one graph to another.
|
||||
- Breaking out GraphData validation into clearer steps.
|
||||
- Added AlphaToMask render state.
|
||||
- Added a field to the Master Nodes that overrides the generated shader's ShaderGUI, which determines how a Material that uses a Shader Graph looks.
|
||||
- Added Redirect Nodes. You can now double-click an edge to add a control point that allows you to route edges around other nodes and connect multiple output edges.
|
||||
- Added `Compute Deformation` Node to read deformed vertex data from Dots Deformations.
|
||||
- Added new graph nodes that allow sampling Virtual Textures
|
||||
- Shader Graph now uses a new file format that is much friendlier towards version control systems and humans. Existing Shader Graphs and will use the new format next time they are saved.
|
||||
|
||||
### Changed
|
||||
- Changed the `Branch` node so that it uses a ternary operator (`Out = bool ? a : B`) instead of a linear interpolate function.
|
||||
- Copied nodes are now pasted at the cursor location instead of slightly offset from their original location.
|
||||
- Error messages reported on Sub Graph output nodes for invalid previews now present clearer information, with documentation support.
|
||||
- Updated legacy COLOR output semantic to SV_Target in pixel shader for compatibility with DXC.
|
||||
- Updated the functions in the `Normal From Height` node to avoid NaN outputs.
|
||||
- Changed the Voronoi Node algorithm to increase the useful range of the input values and to always use float values internally to avoid clipping.
|
||||
- Changed the `Reference Suffix` of Keyword Enum entries so that you cannot edit them, which ensures that material keywords compile properly.
|
||||
- Updated the dependent version of `Searcher` to 4.2.0.
|
||||
- Added support for `Linear Blend Skinning` Node to Universal Render Pipeline.
|
||||
- Moved all code to be under Unity specific namespaces.
|
||||
- Changed ShaderGraphImporter and ShaderSubgraphImporter so that graphs are imported before Models.
|
||||
- Remove VFXTarget if VisualEffect Graph package isn't included.
|
||||
- VFXTarget doesn't overwrite the shader export anymore, VFXTarget can be active with another target.
|
||||
|
||||
### Fixed
|
||||
- Edges no longer produce errors when you save a Shader Graph.
|
||||
- Shader Graph no longer references the `NUnit` package.
|
||||
- Fixed a shader compatibility issue in the SRP Batcher when you use a hybrid instancing custom variable.
|
||||
- Fixed an issue where Unity would crash when you imported a Shader Graph Asset with invalid formatting.
|
||||
- Fixed an issue with the animated preview when there is no Camera with animated Materials in the Editor.
|
||||
- Triplanar nodes no longer use Camera-relative world space by default in HDRP.
|
||||
- Errors no longer occur when you activate `Enable GPU Instancing` on Shader Graph Materials. [1184870](https://issuetracker.unity3d.com/issues/universalrp-shader-compilation-error-when-using-gpu-instancing)
|
||||
- Errors no longer occur when there are multiple tangent transform nodes on a graph. [1185752](https://issuetracker.unity3d.com/issues/shadergraph-fails-to-compile-with-redefinition-of-transposetangent-when-multiple-tangent-transform-nodes-are-plugged-in)
|
||||
- The Main Preview for Sprite Lit and Sprite Unlit master nodes now displays the correct color. [1184656](https://issuetracker.unity3d.com/issues/shadergraph-preview-for-lit-and-unlit-master-node-wrong-color-when-color-is-set-directly-on-master-node)
|
||||
- Shader Graph shaders in `Always Include Shaders` no longer crash builds. [1191757](https://issuetracker.unity3d.com/issues/lwrp-build-crashes-when-built-with-shadergraph-file-added-to-always-include-shaders-list)
|
||||
- The `Transform` node now correctly transforms Absolute World to Object.
|
||||
- Errors no longer occur when you change the precision of Sub Graphs. [1158413](https://issuetracker.unity3d.com/issues/shadergraph-changing-precision-of-sg-with-subgraphs-that-still-use-the-other-precision-breaks-the-generated-shader)
|
||||
- Fixed an error where the UV channel drop-down menu on nodes had clipped text. [1188710](https://issuetracker.unity3d.com/issues/shader-graph-all-uv-dropdown-value-is-clipped-under-shader-graph)
|
||||
- Added StencilOverride support.
|
||||
- Sticky Notes can now be grouped properly.
|
||||
- Fixed an issue where nodes couldn't be copied from a group.
|
||||
- Fixed a bug that occurred when you duplicated multiple Blackboard properties or keywords simultaneously, where Shader Graph stopped working, potentially causing data loss.
|
||||
- Fixed a bug where you couldn't reorder Blackboard properties.
|
||||
- Shader Graph now properly duplicates the __Exposed__ status for Shader properties and keywords.
|
||||
- Fixed a bug where the __Save Graph As__ dialog for a Shader or Sub Graph sometimes appeared in the wrong Project when you had multiple Unity Projects open simultaneously.
|
||||
- Fixed an issue where adding the first output to a Sub Graph without any outputs prior caused Shader Graphs containing the Sub Graph to break.
|
||||
- Fixed an issue where Shader Graph shaders using the `CameraNode` failed to build on PS4 with "incompatible argument list for call to 'mul'".
|
||||
- Fixed a bug that caused problems with Blackboard property ordering.
|
||||
- Fixed a bug where the redo functionality in Shader Graph often didn't work.
|
||||
- Fixed a bug where using the Save As command on a Sub Graph raised an exception.
|
||||
- Fixed a bug where the input fields sometimes didn't render properly. [1176268](https://issuetracker.unity3d.com/issues/shadergraph-input-fields-get-cut-off-after-minimizing-and-maximizing-become-unusable)
|
||||
- Fixed a bug where the Gradient property didn't work with all system locales. [1140924](https://issuetracker.unity3d.com/issues/shader-graph-shader-doesnt-compile-when-using-a-gradient-property-and-a-regional-format-with-comma-decimal-separator-is-used)
|
||||
- Fixed a bug where Properties in the Blackboard could have duplicate names.
|
||||
- Fixed a bug where you could drag the Blackboard into a graph even when you disabled the Blackboard.
|
||||
- Fixed a bug where the `Vertex Normal` slot on master nodes needed vertex normal data input to compile. [1193348](https://issuetracker.unity3d.com/issues/hdrp-unlit-shader-plugging-anything-into-the-vertex-normal-input-causes-shader-to-fail-to-compile)
|
||||
- Fixed a bug where `GetWorldSpaceNormalizeViewDir()` could cause undeclared indentifier errors. [1190606](https://issuetracker.unity3d.com/issues/view-dir-node-plugged-into-vertex-position-creates-error-undeclared-identifier-getworldspacenormalizeviewdir)
|
||||
- Fixed a bug where Emission on PBR Shader Graphs in the Universal RP would not bake to lightmaps. [1190225](https://issuetracker.unity3d.com/issues/emissive-custom-pbr-shadergraph-material-only-works-for-primitive-unity-objects)
|
||||
- Fixed a bug where Shader Graph shaders were writing to `POSITION` instead of `SV_POSITION`, which caused PS4 builds to fail.
|
||||
- Fixed a bug where `Object to Tangent` transforms in the `Transform` node used the wrong matrix. [1162203](https://issuetracker.unity3d.com/issues/shadergraph-transform-node-from-object-to-tangent-space-uses-the-wrong-matrix)
|
||||
- Fixed an issue where boolean keywords in a Shader Graph caused HDRP Material features to fail. [1204827](https://issuetracker.unity3d.com/issues/hdrp-shadergraph-adding-a-boolean-keyword-to-an-hdrp-lit-shader-makes-material-features-not-work)
|
||||
- Fixed a bug where Object space normals scaled with Object Scale.
|
||||
- Documentation links on nodes now point to the correct URLs and package versions.
|
||||
- Fixed an issue where Sub Graphs sometimes had duplicate names when you converted nodes into Sub Graphs.
|
||||
- Fixed an issue where the number of ports on Keyword nodes didn't update when you added or removed Enum Keyword entries.
|
||||
- Fixed an issue where colors in graphs didn't update when you changed a Blackboard Property's precision while the Color Mode is set to Precision.
|
||||
- Fixed a bug where custom mesh in the Master Preview didn't work.
|
||||
- Fixed a number of memory leaks that caused Shader Graph assets to stay in memory after closing the Shader Graph window.
|
||||
- You can now smoothly edit controls on the `Dielectric Specular` node.
|
||||
- Fixed Blackboard Properties to support scientific notation.
|
||||
- Fixed a bug where warnings in the Shader Graph or Sub Graph were treated as errors.
|
||||
- Fixed a bug where the error `Output value 'vert' is not initialized` displayed on all PBR graphs in Universal. [1210710](https://issuetracker.unity3d.com/issues/output-value-vert-is-not-completely-initialized-error-is-thrown-when-pbr-graph-is-created-using-urp)
|
||||
- Fixed a bug where PBR and Unlit master nodes in Universal had Alpha Clipping enabled by default.
|
||||
- Fixed an issue in where analytics wasn't always working.
|
||||
- Fixed a bug where if a user had a Blackboard Property Reference start with a digit the generated shader would be broken.
|
||||
- Avoid unintended behavior by removing the ability to create presets from Shader Graph (and Sub Graph) assets. [1220914](https://issuetracker.unity3d.com/issues/shadergraph-preset-unable-to-open-editor-when-clicking-on-open-shader-editor-in-the-shadersubgraphimporter)
|
||||
- Fixed a bug where undo would make the Master Preview visible regardless of its toggle status.
|
||||
- Fixed a bug where any change to the PBR master node settings would lose connection to the normal slot.
|
||||
- Fixed a bug where the user couldn't open up HDRP Master Node Shader Graphs without the Render Pipeline set to HDRP.
|
||||
- Fixed a bug where adding a HDRP Master Node to a Shader Graph would softlock the Shader Graph.
|
||||
- Fixed a bug where shaders fail to compile due to `#pragma target` generation when your system locale uses commas instead of periods.
|
||||
- Fixed a compilation error when using Hybrid Renderer due to incorrect positioning of macros.
|
||||
- Fixed a bug where the `Create Node Menu` lagged on load. Entries are now only generated when property, keyword, or subgraph changes are detected. [1209567](https://issuetracker.unity3d.com/issues/shadergraph-opening-node-search-window-is-unnecessarily-slow).
|
||||
- Fixed a bug with the `Transform` node where converting from `Absolute World` space in a sub graph causes invalid subscript errors. [1190813](https://issuetracker.unity3d.com/issues/shadergraph-invalid-subscript-errors-are-thrown-when-connecting-a-subgraph-with-transform-node-with-unlit-master-node)
|
||||
- Fixed a bug where depndencies were not getting included when exporting a shadergraph and subgraphs
|
||||
- Fixed a bug where adding a " to a property display name would cause shader compilation errors and show all nodes as broken
|
||||
- Fixed a bug where the `Position` node would change coordinate spaces from `World` to `Absolute World` when shaders recompile. [1184617](https://issuetracker.unity3d.com/product/unity/issues/guid/1184617/)
|
||||
- Fixed a bug where instanced shaders wouldn't compile on PS4.
|
||||
- Fixed a bug where switching a Color Nodes' Mode between Default and HDR would cause the Color to be altered incorrectly.
|
||||
- Fixed a bug where nodes dealing with matricies would sometimes display a preview, sometimes not.
|
||||
- Optimized loading a large Shader Graph. [1209047](https://issuetracker.unity3d.com/issues/shader-graph-unresponsive-editor-when-using-large-graphs)
|
||||
- Fixed NaN issue in triplanar SG node when blend goes to 0.
|
||||
- Fixed a recurring bug where node inputs would get misaligned from their ports. [1224480]
|
||||
- Fixed an issue where Blackboard properties would not duplicate with `Precision` or `Hybrid Instancing` options.
|
||||
- Fixed an issue where `Texture` properties on the Blackboard would not duplicate with the same `Mode` settings.
|
||||
- Fixed an issue where `Keywords` on the Blackboard would not duplicate with the same `Default` value.
|
||||
- Shader Graph now requests preview shader compilation asynchronously. [1209047](https://issuetracker.unity3d.com/issues/shader-graph-unresponsive-editor-when-using-large-graphs)
|
||||
- Fixed an issue where Shader Graph would not compile master previews after an assembly reload.
|
||||
- Fixed issue where `Linear Blend Skinning` node could not be converted to Sub Graph [1227087](https://issuetracker.unity3d.com/issues/shadergraph-linear-blend-skinning-node-reports-an-error-and-prevents-shader-compilation-when-used-within-a-sub-graph)
|
||||
- Fixed a compilation error in preview shaders for nodes requiring view direction.
|
||||
- Fixed undo not being recorded properly for setting active master node, graph precision, and node defaults.
|
||||
- Fixed an issue where Custum Function nodes and Sub Graph Output nodes could no longer rename slots.
|
||||
- Fixed a bug where searcher entries would not repopulate correctly after an undo was perfromed (https://fogbugz.unity3d.com/f/cases/1241018/)
|
||||
- Fixed a bug where Redirect Nodes did not work as inputs to Custom Function Nodes. [1235999](https://issuetracker.unity3d.com/product/unity/issues/guid/1235999/)
|
||||
- Fixed a bug where changeing the default value on a keyword would reset the node input type to vec4 (https://fogbugz.unity3d.com/f/cases/1216760/)
|
||||
- Fixed a soft lock when you open a graph when the blackboard hidden.
|
||||
- Fixed an issue where keyboard navigation in the Create Node menu no longer worked. [1253544]
|
||||
- Preview correctly shows unassigned VT texture result, no longer ignores null textures
|
||||
- Don't allow duplicate VT layer names when renaming layers
|
||||
- Moved VT layer TextureType to the VTProperty from the SampleVT node
|
||||
- Fixed the squished UI of VT property layers
|
||||
- Disallow Save As and Convert to Subgraph that would create recursive dependencies
|
||||
- Fixed an issue where the user would not get a save prompt on application close [1262044](https://issuetracker.unity3d.com/product/unity/issues/guid/1262044/)
|
||||
- Fixed bug where output port type would not visually update when input type changed (for example from Vec1 to Vec3) [1259501](https://issuetracker.unity3d.com/product/unity/issues/guid/1259501/)
|
||||
- Fixed an issue with how we collected/filtered nodes for targets. Applied the work to the SearchWindowProvider as well
|
||||
- Fixed a bug where the object selector for Custom Function Nodes did not update correctly. [1176129](https://issuetracker.unity3d.com/product/unity/issues/guid/1176129/)
|
||||
- Fixed a bug where whitespaces were allowed in keyword reference names
|
||||
- Fixed a bug where the Create Node menu would override the Object Field selection window. [1176125](https://issuetracker.unity3d.com/issues/shader-graph-object-input-field-with-space-bar-shortcut-opens-shader-graph-search-window-and-object-select-window)
|
||||
- Fixed a bug where the Main Preview window was no longer a square aspect ratio. [1257053](https://issuetracker.unity3d.com/product/unity/issues/guid/1257053/)
|
||||
- Fixed a bug where the size of the Graph Inspector would not save properly. [1257084](https://issuetracker.unity3d.com/product/unity/issues/guid/1257084/)
|
||||
- Replace toggle by an enumField for lit/unlit with VFXTarget
|
||||
- Alpha Clipping option in Graph inspector now correctly hides and indents dependent options. (https://fogbugz.unity3d.com/f/cases/1257041/)
|
||||
- Fixed a bug where changing the name of a property did not update nodes on the graph. [1249164](https://issuetracker.unity3d.com/product/unity/issues/guid/1249164/)
|
||||
- Fixed a crash issue when ShaderGraph included in a project along with DOTS assemblies
|
||||
- Added missing SampleVirtualTextureNode address mode control in ShaderGraph
|
||||
- Fixed a badly named control on SampleVirtualTextureNode in ShaderGraph
|
||||
- Fixed an issue where multiple SampleVirtualTextureNodes created functions with names that may collide in ShaderGraph
|
||||
- Made sub graph importer deterministic to avoid cascading shader recompiles when no change was present.
|
||||
- Adjusted style sheet for Blackboard to prevent ui conflicts.
|
||||
- Fixed a bug where the SampleVirtualTexture node would delete slots when changing its LOD mode
|
||||
- Use preview of the other target if VFXTarget is active.
|
||||
|
||||
## [7.1.1] - 2019-09-05
|
||||
### Added
|
||||
- You can now define shader keywords on the Blackboard. Use these keywords on the graph to create static branches in the generated shader.
|
||||
- The tab now shows whether you are working in a Sub Graph or a Shader Graph file.
|
||||
- The Shader Graph importer now bakes the output node type name into a meta-data object.
|
||||
|
||||
### Fixed
|
||||
- The Shader Graph preview no longer breaks when you create new PBR Graphs.
|
||||
- Fixed an issue where deleting a group and a property at the same time would cause an error.
|
||||
- Fixed the epsilon that the Hue Node uses to avoid NaN on platforms that support half precision.
|
||||
- Emission nodes no longer produce errors when you use them in Sub Graphs.
|
||||
- Exposure nodes no longer produce errors when you use them in Sub Graphs.
|
||||
- Unlit master nodes no longer define unnecessary properties in the Universal Render Pipeline.
|
||||
- Errors no longer occur when you convert a selection to a Sub Graph.
|
||||
- Color nodes now handle Gamma and Linear conversions correctly.
|
||||
- Sub Graph Output nodes now link to the correct documentation page.
|
||||
- When you use Keywords, PBR and Unlit master nodes no longer produce errors.
|
||||
- PBR master nodes now calculate Global Illumination (GI) correctly.
|
||||
- PBR master nodes now apply surface normals.
|
||||
- PBR master nodes now apply fog.
|
||||
- The Editor now displays correct errors for missing or deleted Sub Graph Assets.
|
||||
- You can no longer drag and drop recursive nodes onto Sub Graph Assets.
|
||||
|
||||
## [7.0.1] - 2019-07-25
|
||||
### Changed
|
||||
- New Shader Graph windows are now docked to either existing Shader Graph windows, or to the Scene View.
|
||||
|
||||
### Fixed
|
||||
- Fixed various dependency tracking issues with Sub Graphs and HLSL files from Custom Function Nodes.
|
||||
- Fixed an error that previously occurred when you used `Sampler State` input ports on Sub Graphs.
|
||||
- `Normal Reconstruct Z` node is now compatible with both fragment and vertex stages.
|
||||
- `Position` node now draws the correct label for **Absolute World**.
|
||||
- Node previews now inherit preview type correctly.
|
||||
- Normal maps now unpack correctly for mobile platforms.
|
||||
- Fixed an error that previously occurred when you used the Gradient Sample node and your system locale uses commas instead of periods.
|
||||
- Fixed an issue where you couldn't group several nodes.
|
||||
|
||||
## [7.0.0] - 2019-07-10
|
||||
### Added
|
||||
- You can now use the `SHADERGRAPH_PREVIEW` keyword in `Custom Function Node` to generate different code for preview Shaders.
|
||||
- Color Mode improves node visibility by coloring the title bar by Category, Precision, or custom colors.
|
||||
- You can now set the precision of a Shader Graph and individual nodes.
|
||||
- Added the `_TimeParameters` variable which contains `Time`, `Sin(Time)`, and `Cosine(Time)`
|
||||
- _Absolute World_ space on `Position Node` now provides absolute world space coordinates regardless of the active render pipeline.
|
||||
- You can now add sticky notes to graphs.
|
||||
|
||||
### Changed
|
||||
- The `Custom Function Node` now uses an object field to reference its source when using `File` mode.
|
||||
- To enable master nodes to generate correct motion vectors for time-based vertex modification, time is now implemented as an input to the graph rather than as a global uniform.
|
||||
- **World** space on `Position Node` now uses the default world space coordinates of the active render pipeline.
|
||||
|
||||
### Fixed
|
||||
- Fixed an error in `Custom Function Node` port naming.
|
||||
- `Sampler State` properties and nodes now serialize correctly.
|
||||
- Labels in the Custom Port menu now use the correct coloring when using the Personal skin.
|
||||
- Fixed an error that occured when creating a Sub Graph from a selection containing a Group Node.
|
||||
- When you change a Sub Graph, Shader Graph windows now correctly reload.
|
||||
- When you save a Shader Graph, all other Shader Graph windows no longer re-compile their preview Shaders.
|
||||
- Shader Graph UI now draws with correct styling for 2019.3.
|
||||
- When deleting edge connections to nodes with a preview error, input ports no longer draw in the wrong position.
|
||||
- Fixed an error involving deprecated components from VisualElements.
|
||||
- When you convert nodes to a Sub Graph, the nodes are now placed correctly in the Sub Graph.
|
||||
- The `Bitangent Vector Node` now generates all necessary shader requirements.
|
||||
|
||||
## [6.7.0-preview] - 2019-05-16
|
||||
### Added
|
||||
- Added a hidden path namespace for Sub Graphs to prevent certain Sub Graphs from populating the Create Node menu.
|
||||
|
||||
### Changed
|
||||
- Anti-aliasing (4x) is now enabled on Shader Graph windows.
|
||||
|
||||
### Fixed
|
||||
- When you click on the gear icon, Shader Graph now focuses on the selected node, and brings the settings menu to front view.
|
||||
- Sub Graph Output and Custom Function Node now validate slot names, and display an appropriate error badge when needed.
|
||||
- Remaining outdated documentation has been removed.
|
||||
- When you perform an undo or redo to an inactive Shader Graph window, the window no longer breaks.
|
||||
- When you rapidly perform an undo or redo, Shader Graph windows no longer break.
|
||||
- Sub Graphs that contain references to non-existing Sub Graphs no longer break the Sub Graph Importer.
|
||||
- You can now reference sub-assets such as Textures.
|
||||
- You can now reference Scene Color and Scene Depth correctly from within a Sub Graph.
|
||||
- When you create a new empty Sub Graph, it no longer shows a warning about a missing output.
|
||||
- When you create outputs that start with a digit, Shader generation no longer fails.
|
||||
- You can no longer add nodes that are not allowed into Sub Graphs.
|
||||
- A graph must now always contain at least one Master Node.
|
||||
- Duplicate output names are now allowed.
|
||||
- Fixed an issue where the main preview was always redrawing.
|
||||
- When you set a Master Node as active, the Main Preview now shows the correct result.
|
||||
- When you save a graph that contains a Sub Graph node, the Shader Graph window no longer freezes.
|
||||
- Fixed an error that occured when using multiple Sampler State nodes with different parameters.
|
||||
- Fixed an issue causing default inputs to be misaligned in certain cases.
|
||||
- You can no longer directly connect slots with invalid types. When the graph detects that situation, it now doesn't break and gives an error instead.
|
||||
|
||||
## [6.6.0] - 2019-04-01
|
||||
### Added
|
||||
- You can now add Matrix, Sampler State and Gradient properties to the Blackboard.
|
||||
- Added Custom Function node. Use this node to define a custom HLSL function either via string directly in the graph, or via a path to an HLSL file.
|
||||
- You can now group nodes by pressing Ctrl + G.
|
||||
- Added "Delete Group and Contents" and removed "Ungroup All Nodes" from the context menu for groups.
|
||||
- You can now use Sub Graphs in other Sub Graphs.
|
||||
- Preview shaders now compile in the background, and only redraw when necessary.
|
||||
|
||||
### Changed
|
||||
- Removed Blackboard fields, which had no effect on Sub Graph input ports, from the Sub Graph Blackboard.
|
||||
- Subgraph Output node is now called Outputs.
|
||||
- Subgraph Output node now supports renaming of ports.
|
||||
- Subgraph Output node now supports all port types.
|
||||
- Subgraph Output node now supports reordering ports.
|
||||
- When you convert nodes to a Sub Graph, Shader Graph generates properties and output ports in the Sub Graph, and now by default, names those resulting properties and output ports based on their types.
|
||||
- When you delete a group, Shader Graph now deletes the Group UI, but doesn't delete the nodes inside.
|
||||
|
||||
### Fixed
|
||||
- You can now undo edits to Vector port default input fields.
|
||||
- You can now undo edits to Gradient port default input fields.
|
||||
- Boolean port input fields now display correct values when you undo changes.
|
||||
- Vector type properties now behave as expected when you undo changes.
|
||||
- Fixed an error that previously occurred when you opened saved Shader Graphs containing one or more Voronoi nodes.
|
||||
- You can now drag normal map type textures on to a Shader Graph to create Sample Texture 2D nodes with the correct type set.
|
||||
- Fixed the Multiply node so default input values are applied correctly.
|
||||
- Added padding on input values for Blend node to prevent NaN outputs.
|
||||
- Fixed an issue where `IsFaceSign` would not compile within Sub Graph Nodes.
|
||||
- Null reference errors no longer occur when you remove ports with connected edges.
|
||||
- Default input fields now correctly hide and show when connections change.
|
||||
|
||||
## [6.5.0] - 2019-03-07
|
||||
|
||||
### Fixed
|
||||
- Fixed master preview for HDRP master nodes when alpha clip is enabled.
|
||||
|
||||
## [6.4.0] - 2019-02-21
|
||||
### Fixed
|
||||
- Fixed the Transform node, so going from Tangent Space to any other space now works as expected.
|
||||
|
||||
## [6.3.0] - 2019-02-18
|
||||
### Fixed
|
||||
- Fixed an issue where the Normal Reconstruct Z Node sometimes caused Not a Number (NaN) errors when using negative values.
|
||||
|
||||
## [6.2.0] - 2019-02-15
|
||||
### Fixed
|
||||
- Fixed the property blackboard so it no longer goes missing or turns very small.
|
||||
|
||||
### Changed
|
||||
- Code refactor: all macros with ARGS have been swapped with macros with PARAM. This is because the ARGS macros were incorrectly named.
|
||||
|
||||
## [6.1.0] - 2019-02-13
|
||||
|
||||
## [6.0.0] - 2019-02-23
|
||||
### Added
|
||||
- When you hover your cursor over a property in the blackboard, this now highlights the corresponding property elements in your Shader Graph. Similarly, if you hover over a property in the Shader Graph itself, this highlights the corresponding property in the blackboard.
|
||||
- Property nodes in your Shader Graph now have a similar look and styling as the properties in the blackboard.
|
||||
|
||||
### Changed
|
||||
- Errors in the compiled shader are now displayed as badges on the appropriate node.
|
||||
- In the `Scene Depth` node you can now choose the depth sampling mode: `Linear01`, `Raw` or `Eye`.
|
||||
|
||||
### Fixed
|
||||
- When you convert an inline node to a `Property` node, this no longer allows duplicate property names.
|
||||
- When you move a node, you'll now be asked to save the Graph file.
|
||||
- You can now Undo edits to Property parameters on the Blackboard.
|
||||
- You can now Undo conversions between `Property` nodes and inline nodes.
|
||||
- You can now Undo moving a node.
|
||||
- You can no longer select the `Texture2D` Property type `Mode`, if the Property is not exposed.
|
||||
- The `Vector1` Property type now handles default values more intuitively when switching `Mode` dropdown.
|
||||
- The `Color` node control is now a consistent width.
|
||||
- Function declarations no longer contain double delimiters.
|
||||
- The `Slider` node control now functions correctly.
|
||||
- Fixed an issue where the Editor automatically re-imported Shader Graphs when there were changes to the asset database.
|
||||
- Reverted the visual styling of various graph elements to their previous correct states.
|
||||
- Previews now repaint correctly when Unity does not have focus.
|
||||
- Code generation now works correctly for exposed Vector1 shader properties where the decimal separator is not a dot.
|
||||
- The `Rotate About Axis` node's Modes now use the correct function versions.
|
||||
- Shader Graph now preserves grouping when you convert nodes between property and inline.
|
||||
- The `Flip` node now greys out labels for inactive controls.
|
||||
- The `Boolean` property type now uses the `ToggleUI` property attribute, so as to not generate keywords.
|
||||
- The `Normal Unpack` node no longer generates errors in Object space.
|
||||
- The `Split` node now uses values from its default Port input fields.
|
||||
- The `Channel Mask` node now allows multiple node instances, and no longer generates any errors.
|
||||
- Serialized the Alpha control value on the `Flip` node.
|
||||
- The `Is Infinite` and `Is NaN` nodes now use `Vector 1` input ports, but the output remains the same.
|
||||
- You can no longer convert a node inside a `Sub Graph` into a `Sub Graph`, which previously caused errors.
|
||||
- The `Transformation Matrix` node's Inverse Projection and Inverse View Projection modes no longer produce errors.
|
||||
- The term `Shader Graph` is now captilized correctly in the Save Graph prompt.
|
||||
|
||||
## [5.2.0] - 2018-11-27
|
||||
### Added
|
||||
- Shader Graph now has __Group Node__, where you can group together several nodes. You can use this to keep your Graphs organized and nice.
|
||||
|
||||
### Fixed
|
||||
- The expanded state of blackboard properties are now remembered during a Unity session.
|
||||
|
||||
## [5.1.0] - 2018-11-19
|
||||
### Added
|
||||
- You can now show and hide the Main Preview and the Blackboard from the toolbar.
|
||||
|
||||
### Changed
|
||||
- The Shader Graph package is no longer in preview.
|
||||
- Moved `NormalBlendRNM` node to a dropdown option on `Normal Blend` node.
|
||||
- `Sample Cubemap` node now has a `SamplerState` slot.
|
||||
- New Sub Graph assets now default to the "Sub Graphs" path in the Create Node menu.
|
||||
- New Shader Graph assets now default to the "Shader Graphs" path in the Shader menu.
|
||||
- The `Light Probe` node is now a `Baked GI` node. When you use LWRP with lightmaps, this node now returns the correct lightmap data. This node is supported in HDRP.
|
||||
- `Reflection Probe` nodes now only work with LWRP. This solves compilation errors in HDRP.
|
||||
- `Ambient` nodes now only work with LWRP. This solves compilation errors in HDRP.
|
||||
- `Fog` nodes now only work with LWRP. This solves compilation errors in HDRP.
|
||||
- In HDRP, the `Position` port for the `Object` node now returns the absolute world position.
|
||||
- The `Baked GI`, `Reflection Probe`, and `Ambient` nodes are now in the `Input/Lighting` category.
|
||||
- The master node no longer has its own preview, because it was redundant. You can see the results for the master node in the Main Preview.
|
||||
|
||||
### Fixed
|
||||
- Shadow projection is now correct when using the `Unlit` master node with HD Render Pipeline.
|
||||
- Removed all direct references to matrices
|
||||
- `Matrix Construction` nodes with different `Mode` values now evaluate correctly.
|
||||
- `Is Front Face` node now works correctly when connected to `Alpha` and `AlphaThreshold` slots on the `PBR` master node.
|
||||
- Corrected some instances of incorrect port dimensions on several nodes.
|
||||
- `Scene Depth` and `Scene Color` nodes now work in single pass stereo in Lightweight Render Pipeline.
|
||||
- `Channel Mask` node controls are now aligned correctly.
|
||||
- In Lightweight Render Pipeline, Pre-multiply surface type now matches the Lit shader.
|
||||
- Non-exposed properties in the blackboard no longer have a green dot next to them.
|
||||
- Default reference name for shader properties are now serialized. You cannot change them after initial creation.
|
||||
- When you save Shader Graph and Sub Graph files, they're now automatically checked out on version control.
|
||||
- Shader Graph no longer throws an exception when you double-click a folder in the Project window.
|
||||
- Gradient Node no longer throws an error when you undo a deletion.
|
||||
|
||||
## [5.0.0-preview] - 2018-09-28
|
||||
|
||||
## [4.0.0-preview] - 2018-09-28
|
||||
### Added
|
||||
- Shader Graph now supports the High Definition Render Pipeline with both PBR and Unlit Master nodes. Shaders built with Shader Graph work with both the Lightweight and HD render pipelines.
|
||||
- You can now modify vertex position via the Position slot on the PBR and Unlit Master nodes. By default, the input to this node is object space position. Custom inputs to this slot should specify the absolute local position of a given vertex. Certain nodes (such as Procedural Shapes) are not viable in the vertex shader. Such nodes are incompatible with this slot.
|
||||
- You can now edit the Reference name for a property. To do so, select the property and type a new name next to Reference. If you want to reset to the default name, right-click Reference, and select Reset reference.
|
||||
- In the expanded property window, you can now toggle whether the property is exposed.
|
||||
- You can now change the path of Shader Graphs and Sub Graphs. When you change the path of a Shader Graph, this modifies the location it has in the shader selection list. When you change the path of Sub Graph, it will have a different location in the node creation menu.
|
||||
- Added `Is Front Face` node. With this node, you can change graph output depending on the face sign of a given fragment. If the current fragment is part of a front face, the node returns true. For a back face, the node returns false. Note: This functionality requires that you have enabled **two sided** on the Master node.
|
||||
- Gradient functionality is now available via two new nodes: Sample Gradient and Gradient Asset. The Sample Gradient node samples a gradient given a Time parameter. You can define this gradient on the Gradient slot control view. The Gradient Asset node defines a gradient that can be sampled by multiple Sample Gradient nodes using different Time parameters.
|
||||
- Math nodes now have a Waves category. The category has four different nodes: Triangle wave, Sawtooth wave, Square wave, and Noise Sine wave. The Triangle, Sawtooth, and Square wave nodes output a waveform with a range of -1 to 1 over a period of 1. The Noise Sine wave outputs a standard Sine wave with a range of -1 to 1 over a period of 2 * pi. For variance, random noise is added to the amplitude of the Sine wave, within a determined range.
|
||||
- Added `Sphere Mask` node for which you can indicate the starting coordinate and center point. The sphere mask uses these with the **Radius** and **Hardness** parameters. Sphere mask functionality works in both 2D and 3D spaces, and is based on the vector coordinates in the **Coords and Center** input.
|
||||
- Added support for Texture 3D and Texture 2D Array via two new property types and four new nodes.
|
||||
- A new node `Texture 2D LOD` has been added for LOD functionality on a Texture 2D Sample. Sample Texture 2D LOD uses the exact same input and output slots as Sample Texture 2D, but also includes an input for level of detail adjustments via a Vector1 slot.
|
||||
- Added `Texel Size` node, which allows you to get the special texture properties of a Texture 2D Asset via the `{texturename}_TexelSize` variable. Based on input from the Texture 2D Asset, the node outputs the width and height of the texel size in Vector1 format.
|
||||
- Added `Rotate About Axis` node. This allows you to rotate a 3D vector space around an axis. For the rotation, you can specify an amount of degrees or a radian value.
|
||||
- Unpacking normal maps in object space.
|
||||
- Unpacking derivative maps option on sample texture nodes.
|
||||
- Added Uint type for instancing support.
|
||||
- Added HDR option for color material slots.
|
||||
- Added definitions used by new HD Lit Master node.
|
||||
- Added a popup control for a string list.
|
||||
- Added conversion type (position/direction) to TransformNode.
|
||||
- In your preview for nodes that are not master nodes, pixels now display as pink if they are not finite.
|
||||
|
||||
### Changed
|
||||
- The settings for master nodes now live in a small window that you can toggle on and off. Here, you can change various rendering settings for your shader.
|
||||
- There are two Normal Derive Nodes: `Normal From Height` and `Normal Reconstruct Z`.
|
||||
`Normal From Height` uses Vector1 input to derive a normal map.
|
||||
`Normal Reconstruct Z` uses the X and Y components in Vector2 input to derive the proper Z value for a normal map.
|
||||
- The Texture type default input now accepts render textures.
|
||||
- HD PBR subshader no longer duplicates surface description code into vertex shader.
|
||||
- If the current render pipeline is not compatible, master nodes now display an error badge.
|
||||
- The preview shader now only considers the current render pipeline. Because of this there is less code to compile, so the preview shader compiles faster.
|
||||
- When you rename a shader graph or sub shader graph locally on your disk, the title of the Shader Graph window, black board, and preview also updates.
|
||||
- Removed legacy matrices from Transfomation Matrix node.
|
||||
- Texture 2D Array and Texture 3D nodes can no longer be used in the vertex shader.
|
||||
- `Normal Create` node has been renamed to `Normal From Texture`.
|
||||
- When you close the Shader Graph after you have modified a file, the prompt about saving your changes now shows the file name as well.
|
||||
- `Blend` node now supports Overwrite mode.
|
||||
- `Simple Noise` node no longer has a loop.
|
||||
- The `Polygon` node now calculates radius based on apothem.
|
||||
- `Normal Strength` node now calculates Z value more accurately.
|
||||
- You can now connect Sub Graphs to vertex shader slots. If a node in the Sub Graph specifies a shader stage, that specific Sub Graph node is locked to that stage. When an instance of a Sub Graph node is connected to a slot that specifies a shader stage, all slots on that instance are locked to the stage.
|
||||
- Separated material options and tags.
|
||||
- Master node settings are now recreated when a topological modification occurs.
|
||||
|
||||
### Fixed
|
||||
- Vector 1 nodes now evaluate correctly. ([#334](https://github.com/Unity-Technologies/ShaderGraph/issues/334) and [#337](https://github.com/Unity-Technologies/ShaderGraph/issues/337))
|
||||
- Properties can now be copied and pasted.
|
||||
- Pasting a property node into another graph will now convert it to a concrete node. ([#300](https://github.com/Unity-Technologies/ShaderGraph/issues/300) and [#307](https://github.com/Unity-Technologies/ShaderGraph/pull/307))
|
||||
- Nodes that are copied from one graph to another now spawn in the center of the current view. ([#333](https://github.com/Unity-Technologies/ShaderGraph/issues/333))
|
||||
- When you edit sub graph paths, the search window no longer yields a null reference exception.
|
||||
- The blackboard is now within view when deserialized.
|
||||
- Your system locale can no longer cause incorrect commands due to full stops being converted to commas.
|
||||
- Deserialization of subgraphs now works correctly.
|
||||
- Sub graphs are now suffixed with (sub), so you can tell them apart from other nodes.
|
||||
- Boolean and Texture type properties now function correctly in sub-graphs.
|
||||
- The preview of a node does not obstruct the selection outliner anymore.
|
||||
- The Dielectric Specular node no longer resets its control values.
|
||||
- You can now copy, paste, and duplicate sub-graph nodes with vector type input ports.
|
||||
- The Lightweight PBR subshader now normalizes normal, tangent, and view direction correctly.
|
||||
- Shader graphs using alpha clip now generate correct depth and shadow passes.
|
||||
- `Normal Create` node has been renamed to `Normal From Texture`.
|
||||
- The preview of nodes now updates correctly.
|
||||
- Your system locale can no longer cause incorrect commands due to full stops being converted to commas.
|
||||
- `Show Generated Code` no longer throws an "Argument cannot be null" error.
|
||||
- Sub Graphs now use the correct generation mode when they generate preview shaders.
|
||||
- The `CodeFunctionNode` API now generates correct function headers when you use `DynamicMatrix` type slots.
|
||||
- Texture type input slots now set correct default values for 'Normal' texture type.
|
||||
- SpaceMaterialSlot now reads correct slot.
|
||||
- Slider node control now functions correctly.
|
||||
- Shader Graphs no longer display an error message intended for Sub Graphs when you delete properties.
|
||||
- The Shader Graph and Sub Shader Graph file extensions are no longer case-sensitive.
|
||||
- The dynamic value slot type now uses the correct decimal separator during HLSL generation.
|
||||
- Fixed an issue where Show Generated Code could fail when external editor was not set.
|
||||
- In the High Definition Render Pipeline, Shader Graph now supports 4-channel UVs.
|
||||
- The Lightweight PBR subshader now generates the correct meta pass.
|
||||
- Both PBR subshaders can now generate indirect light from emission.
|
||||
- Shader graphs now support the SRP batcher.
|
||||
- Fixed an issue where floatfield would be parsed according to OS locale settings with .NET 4.6
|
@@ -0,0 +1,8 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.Tests")]
|
||||
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.GraphicsTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.GraphicsTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.RenderPipelines.HighDefinition.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualEffectGraph.Editor")]
|
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class CreateShaderGraph
|
||||
{
|
||||
[MenuItem("Assets/Create/Shader/Blank Shader Graph", false, 208)]
|
||||
public static void CreateBlankShaderGraph()
|
||||
{
|
||||
GraphUtil.CreateNewGraph();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
using System.IO;
|
||||
using UnityEditor.ProjectWindowCallback;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class CreateShaderSubGraph : EndNameEditAction
|
||||
{
|
||||
[MenuItem("Assets/Create/Shader/Sub Graph", false, 208)]
|
||||
public static void CreateMaterialSubGraph()
|
||||
{
|
||||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreateShaderSubGraph>(),
|
||||
string.Format("New Shader Sub Graph.{0}", ShaderSubGraphImporter.Extension), null, null);
|
||||
}
|
||||
|
||||
public override void Action(int instanceId, string pathName, string resourceFile)
|
||||
{
|
||||
var graph = new GraphData { isSubGraph = true };
|
||||
var outputNode = new SubGraphOutputNode();
|
||||
graph.AddNode(outputNode);
|
||||
graph.outputNode = outputNode;
|
||||
outputNode.AddSlot(ConcreteSlotValueType.Vector4);
|
||||
graph.path = "Sub Graphs";
|
||||
FileUtilities.WriteShaderGraphToDisk(pathName, graph);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
#if VFX_GRAPH_10_0_0_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph;
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class CreateVFXShaderGraph
|
||||
{
|
||||
[MenuItem("Assets/Create/Shader/VFX Shader Graph", false, 208)]
|
||||
public static void CreateVFXGraph()
|
||||
{
|
||||
var target = (VFXTarget)Activator.CreateInstance(typeof(VFXTarget));
|
||||
|
||||
var blockDescriptors = new[]
|
||||
{
|
||||
BlockFields.SurfaceDescription.BaseColor,
|
||||
BlockFields.SurfaceDescription.Alpha,
|
||||
};
|
||||
|
||||
GraphUtil.CreateNewGraphWithOutputs(new[] {target}, blockDescriptors);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
class BuiltinKeywordAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||
internal abstract class ContextFilterableAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class InspectableAttribute : Attribute
|
||||
{
|
||||
// String value to use in the Property name TextLabel
|
||||
public string labelName { get; private set; }
|
||||
|
||||
// The default value of this property
|
||||
public object defaultValue { get; private set; }
|
||||
|
||||
// String value to supply if you wish to use a custom style when drawing this property
|
||||
public string customStyleName { get; private set; }
|
||||
|
||||
public InspectableAttribute(string labelName, object defaultValue, string customStyleName = "")
|
||||
{
|
||||
this.labelName = labelName;
|
||||
this.defaultValue = defaultValue;
|
||||
this.customStyleName = customStyleName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class NeverAllowedByTargetAttribute : ContextFilterableAttribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class SGPropertyDrawerAttribute : Attribute
|
||||
{
|
||||
public Type propertyType { get; private set; }
|
||||
|
||||
public SGPropertyDrawerAttribute(Type propertyType)
|
||||
{
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class SRPFilterAttribute : ContextFilterableAttribute
|
||||
{
|
||||
public Type[] srpTypes = null;
|
||||
public SRPFilterAttribute(params Type[] WorksWithSRP)
|
||||
{
|
||||
srpTypes = WorksWithSRP;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
sealed class ContextData
|
||||
{
|
||||
[SerializeField]
|
||||
Vector2 m_Position;
|
||||
|
||||
[SerializeField]
|
||||
List<JsonRef<BlockNode>> m_Blocks = new List<JsonRef<BlockNode>>();
|
||||
|
||||
[NonSerialized]
|
||||
ShaderStage m_ShaderStage;
|
||||
|
||||
public ContextData()
|
||||
{
|
||||
}
|
||||
|
||||
public List<JsonRef<BlockNode>> blocks => m_Blocks;
|
||||
|
||||
public Vector2 position
|
||||
{
|
||||
get => m_Position;
|
||||
set => m_Position = value;
|
||||
}
|
||||
|
||||
public ShaderStage shaderStage
|
||||
{
|
||||
get => m_ShaderStage;
|
||||
set => m_ShaderStage = value;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
enum Precision
|
||||
{
|
||||
Inherit,
|
||||
Single,
|
||||
Half,
|
||||
}
|
||||
|
||||
public enum ConcretePrecision
|
||||
{
|
||||
Single,
|
||||
Half,
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
}
|
@@ -0,0 +1,262 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class AbstractShaderProperty : ShaderInput
|
||||
{
|
||||
public abstract PropertyType propertyType { get; }
|
||||
|
||||
internal override ConcreteSlotValueType concreteShaderValueType => propertyType.ToConcreteShaderValueType();
|
||||
|
||||
// user selected precision setting
|
||||
[SerializeField]
|
||||
Precision m_Precision = Precision.Inherit;
|
||||
|
||||
[Obsolete("AbstractShaderProperty.gpuInstanced is no longer used")]
|
||||
public bool gpuInstanced
|
||||
{
|
||||
get { return false; }
|
||||
set {}
|
||||
}
|
||||
|
||||
internal virtual string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
// NOTE: this does not tell you the HLSLDeclaration of the entire property...
|
||||
// instead, it tells you what the DEFAULT HLSL Declaration would be, IF the property makes use of the default
|
||||
// to check ACTUAL HLSL Declaration types, enumerate the HLSL Properties and check their HLSLDeclarations...
|
||||
internal virtual HLSLDeclaration GetDefaultHLSLDeclaration()
|
||||
{
|
||||
if (overrideHLSLDeclaration)
|
||||
return hlslDeclarationOverride;
|
||||
// default Behavior switches between UnityPerMaterial and Global based on Exposed checkbox
|
||||
if (generatePropertyBlock)
|
||||
return HLSLDeclaration.UnityPerMaterial;
|
||||
else
|
||||
return HLSLDeclaration.Global;
|
||||
}
|
||||
|
||||
// by default we disallow UI from choosing "DoNotDeclare"
|
||||
// it needs a bit more UI support to disable property node output slots before we make it public
|
||||
internal virtual bool AllowHLSLDeclaration(HLSLDeclaration decl) => (decl != HLSLDeclaration.DoNotDeclare);
|
||||
|
||||
[SerializeField]
|
||||
internal bool overrideHLSLDeclaration = false;
|
||||
|
||||
[SerializeField]
|
||||
internal HLSLDeclaration hlslDeclarationOverride;
|
||||
|
||||
internal Precision precision
|
||||
{
|
||||
get => m_Precision;
|
||||
set => m_Precision = value;
|
||||
}
|
||||
|
||||
ConcretePrecision m_ConcretePrecision = ConcretePrecision.Single;
|
||||
public ConcretePrecision concretePrecision => m_ConcretePrecision;
|
||||
internal void ValidateConcretePrecision(ConcretePrecision graphPrecision)
|
||||
{
|
||||
m_ConcretePrecision = (precision == Precision.Inherit) ? graphPrecision : precision.ToConcrete();
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Hidden = false;
|
||||
public bool hidden
|
||||
{
|
||||
get => m_Hidden;
|
||||
set => m_Hidden = value;
|
||||
}
|
||||
|
||||
internal string hideTagString => hidden ? "[HideInInspector]" : "";
|
||||
|
||||
// reference names are the HLSL declaration name / property block ref name
|
||||
internal virtual void GetPropertyReferenceNames(List<string> result)
|
||||
{
|
||||
result.Add(referenceName);
|
||||
}
|
||||
|
||||
// display names are used as the UI name in the property block / show up in the Material Inspector
|
||||
internal virtual void GetPropertyDisplayNames(List<string> result)
|
||||
{
|
||||
result.Add(displayName);
|
||||
}
|
||||
|
||||
// the simple interface for simple properties
|
||||
internal virtual string GetPropertyBlockString()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// the more complex interface for complex properties (defaulted for simple properties)
|
||||
internal virtual void AppendPropertyBlockStrings(ShaderStringBuilder builder)
|
||||
{
|
||||
builder.AppendLine(GetPropertyBlockString());
|
||||
}
|
||||
|
||||
internal abstract void ForeachHLSLProperty(Action<HLSLProperty> action);
|
||||
|
||||
internal virtual string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return GetPropertyAsArgumentString();
|
||||
}
|
||||
|
||||
internal abstract string GetPropertyAsArgumentString();
|
||||
internal abstract AbstractMaterialNode ToConcreteNode();
|
||||
internal abstract PreviewProperty GetPreviewMaterialProperty();
|
||||
|
||||
public virtual string GetPropertyTypeString()
|
||||
{
|
||||
string depString = $" (Deprecated{(ShaderGraphPreferences.allowDeprecatedBehaviors ? " V" + sgVersion : "" )})";
|
||||
return propertyType.ToString() + (sgVersion < latestVersion ? depString : "");
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public abstract class AbstractShaderProperty<T> : AbstractShaderProperty
|
||||
{
|
||||
[SerializeField]
|
||||
T m_Value;
|
||||
|
||||
public virtual T value
|
||||
{
|
||||
get => m_Value;
|
||||
set => m_Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// class for extracting deprecated data from older versions of AbstractShaderProperty
|
||||
class LegacyShaderPropertyData
|
||||
{
|
||||
// indicates user wishes to support the HYBRID renderer GPU instanced path
|
||||
[SerializeField]
|
||||
public bool m_GPUInstanced = false;
|
||||
|
||||
// converts the old m_GPUInstanced data into the new override HLSLDeclaration system.
|
||||
public static void UpgradeToHLSLDeclarationOverride(string json, AbstractShaderProperty property)
|
||||
{
|
||||
// this maintains the old behavior for versioned properties:
|
||||
// old exposed GPUInstanced properties are declared hybrid (becomes override in new system)
|
||||
// old unexposed GPUInstanced properties are declared global (becomes override in new system)
|
||||
// old exposed properties are declared UnityPerMaterial (default behavior, no override necessary)
|
||||
// old unexposed properties are declared Global (default behavior, no override necessary)
|
||||
// moving forward, users can use the overrides directly to control what it does
|
||||
|
||||
var legacyShaderPropertyData = new LegacyShaderPropertyData();
|
||||
JsonUtility.FromJsonOverwrite(json, legacyShaderPropertyData);
|
||||
if (legacyShaderPropertyData.m_GPUInstanced)
|
||||
{
|
||||
property.overrideHLSLDeclaration = true;
|
||||
if (property.generatePropertyBlock)
|
||||
property.hlslDeclarationOverride = HLSLDeclaration.HybridPerInstance;
|
||||
else
|
||||
property.hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum HLSLType
|
||||
{
|
||||
// value types
|
||||
_float,
|
||||
_float2,
|
||||
_float3,
|
||||
_float4,
|
||||
_matrix4x4,
|
||||
|
||||
// object types
|
||||
FirstObjectType,
|
||||
_Texture2D = FirstObjectType,
|
||||
_Texture3D,
|
||||
_TextureCube,
|
||||
_Texture2DArray,
|
||||
_SamplerState,
|
||||
|
||||
// custom type
|
||||
_CUSTOM
|
||||
}
|
||||
|
||||
// describes the different ways we can generate HLSL declarations
|
||||
[Flags]
|
||||
internal enum HLSLDeclaration
|
||||
{
|
||||
DoNotDeclare, // NOT declared in HLSL
|
||||
Global, // declared in the global scope, mainly for use with state coming from Shader.SetGlobal*()
|
||||
UnityPerMaterial, // declared in the UnityPerMaterial cbuffer, populated by Material or MaterialPropertyBlock
|
||||
HybridPerInstance, // declared using HybridRenderer path (v1 or v2) to get DOTS GPU instancing
|
||||
}
|
||||
|
||||
internal struct HLSLProperty
|
||||
{
|
||||
public string name;
|
||||
public HLSLType type;
|
||||
public ConcretePrecision precision;
|
||||
public HLSLDeclaration declaration;
|
||||
public Action<ShaderStringBuilder> customDeclaration;
|
||||
|
||||
public HLSLProperty(HLSLType type, string name, HLSLDeclaration declaration, ConcretePrecision precision = ConcretePrecision.Single)
|
||||
{
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.declaration = declaration;
|
||||
this.precision = precision;
|
||||
this.customDeclaration = null;
|
||||
}
|
||||
|
||||
static string[,] kValueTypeStrings = new string[(int)HLSLType.FirstObjectType, 2]
|
||||
{
|
||||
{"float", "half"},
|
||||
{"float2", "half2"},
|
||||
{"float3", "half3"},
|
||||
{"float4", "half4"},
|
||||
{"float4x4", "half4x4"}
|
||||
};
|
||||
|
||||
static string[] kObjectTypeStrings = new string[(int)HLSLType._CUSTOM - (int)HLSLType.FirstObjectType]
|
||||
{
|
||||
"TEXTURE2D",
|
||||
"TEXTURE3D",
|
||||
"TEXTURECUBE",
|
||||
"TEXTURE2D_ARRAY",
|
||||
"SAMPLER",
|
||||
};
|
||||
|
||||
public string GetValueTypeString()
|
||||
{
|
||||
if (type < HLSLType.FirstObjectType)
|
||||
return kValueTypeStrings[(int)type, (int)precision];
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AppendTo(ShaderStringBuilder ssb, Func<string, string> nameModifier = null)
|
||||
{
|
||||
var mName = nameModifier?.Invoke(name) ?? name;
|
||||
|
||||
if (type < HLSLType.FirstObjectType)
|
||||
{
|
||||
ssb.Append(kValueTypeStrings[(int)type, (int)precision]);
|
||||
ssb.Append(" ");
|
||||
ssb.Append(mName);
|
||||
ssb.Append(";");
|
||||
}
|
||||
else if (type < HLSLType._CUSTOM)
|
||||
{
|
||||
ssb.Append(kObjectTypeStrings[type - HLSLType.FirstObjectType]);
|
||||
ssb.Append("(");
|
||||
ssb.Append(mName);
|
||||
ssb.Append(");");
|
||||
}
|
||||
else
|
||||
{
|
||||
customDeclaration(ssb);
|
||||
}
|
||||
//ssb.Append(" // ");
|
||||
//ssb.Append(declaration.ToString());
|
||||
ssb.AppendNewLine();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class BitangentMaterialSlot : SpaceMaterialSlot, IMayRequireBitangent
|
||||
{
|
||||
public BitangentMaterialSlot() : base()
|
||||
{}
|
||||
|
||||
public BitangentMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.BiTangent));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresBitangent(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class BooleanMaterialSlot : MaterialSlot, IMaterialSlotHasValue<bool>
|
||||
{
|
||||
[SerializeField]
|
||||
private bool m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_DefaultValue;
|
||||
|
||||
public BooleanMaterialSlot()
|
||||
{}
|
||||
|
||||
public BooleanMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
bool value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_DefaultValue = value;
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new BooleanSlotControlView(this);
|
||||
}
|
||||
|
||||
public bool defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public bool value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return (value ? 1 : 0).ToString();
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new BooleanShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Boolean; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Boolean; } }
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Boolean)
|
||||
{
|
||||
name = name,
|
||||
booleanValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as BooleanMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<bool> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.BooleanShaderProperty")]
|
||||
[BlackboardInputInfo(20)]
|
||||
public sealed class BooleanShaderProperty : AbstractShaderProperty<bool>
|
||||
{
|
||||
internal BooleanShaderProperty()
|
||||
{
|
||||
displayName = "Boolean";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Boolean;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}[ToggleUI]{referenceName}(\"{displayName}\", Float) = {(value == true ? 1 : 0)}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new BooleanNode { value = new ToggleData(value) };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
booleanValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new BooleanShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class ColorRGBAMaterialSlot : Vector4MaterialSlot
|
||||
{
|
||||
public ColorRGBAMaterialSlot() {}
|
||||
|
||||
public ColorRGBAMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, value, stageCapability, hidden: hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new ColorRGBASlotControlView(this);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("IsGammaSpace() ? $precision4({0}, {1}, {2}, {3}) : $precision4 (SRGBToLinear($precision3({0}, {1}, {2})), {3})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z)
|
||||
, NodeUtils.FloatToShaderValue(value.w));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new ColorShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Color)
|
||||
{
|
||||
name = name,
|
||||
colorValue = new Color(value.x, value.y, value.z, value.w),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class ColorRGBMaterialSlot : Vector3MaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
ColorMode m_ColorMode = ColorMode.Default;
|
||||
|
||||
[SerializeField]
|
||||
private Color m_DefaultColor = Color.grey;
|
||||
|
||||
public ColorRGBMaterialSlot() {}
|
||||
|
||||
public ColorRGBMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Color value,
|
||||
ColorMode colorMode,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, (Vector4)value, stageCapability, hidden: hidden)
|
||||
{
|
||||
m_ColorMode = colorMode;
|
||||
m_DefaultColor = value;
|
||||
}
|
||||
|
||||
public ColorMode colorMode
|
||||
{
|
||||
get { return m_ColorMode; }
|
||||
set { m_ColorMode = value; }
|
||||
}
|
||||
|
||||
public Color defaultColor => m_DefaultColor;
|
||||
|
||||
public override bool isDefaultValue => value.Equals((Vector4)defaultColor);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new ColorRGBSlotControlView(this);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format(m_ColorMode == ColorMode.Default ? "IsGammaSpace() ? $precision3({0}, {1}, {2}) : SRGBToLinear($precision3({0}, {1}, {2}))" : "$precision3({0}, {1}, {2})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new ColorShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = new Color(value.x, value.y, value.z)
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Color)
|
||||
{
|
||||
name = name,
|
||||
colorValue = new Color(value.x, value.y, value.z, 1),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.ColorShaderProperty")]
|
||||
[BlackboardInputInfo(10)]
|
||||
public sealed class ColorShaderProperty : AbstractShaderProperty<Color>
|
||||
{
|
||||
// 0 - original (broken color space)
|
||||
// 1 - fixed color space
|
||||
// 2 - original (broken color space) with HLSLDeclaration override
|
||||
// 3 - fixed color space with HLSLDeclaration override
|
||||
public override int latestVersion => 3;
|
||||
public const int deprecatedVersion = 2;
|
||||
|
||||
internal ColorShaderProperty()
|
||||
{
|
||||
displayName = "Color";
|
||||
}
|
||||
|
||||
internal ColorShaderProperty(int version) : this()
|
||||
{
|
||||
this.sgVersion = version;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Color;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string hdrTagString => colorMode == ColorMode.HDR ? "[HDR]" : "";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{hdrTagString}{referenceName}(\"{displayName}\", Color) = ({NodeUtils.FloatToShaderValue(value.r)}, {NodeUtils.FloatToShaderValue(value.g)}, {NodeUtils.FloatToShaderValue(value.b)}, {NodeUtils.FloatToShaderValue(value.a)})";
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float4, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override string GetOldDefaultReferenceName()
|
||||
{
|
||||
return $"Color_{objectId}";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
ColorMode m_ColorMode;
|
||||
|
||||
public ColorMode colorMode
|
||||
{
|
||||
get => m_ColorMode;
|
||||
set => m_ColorMode = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new ColorNode { color = new ColorNode.Color(value, colorMode) };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
UnityEngine.Color propColor = value;
|
||||
if (colorMode == ColorMode.Default)
|
||||
{
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
propColor = propColor.linear;
|
||||
}
|
||||
else if (colorMode == ColorMode.HDR)
|
||||
{
|
||||
// conversion from linear to active color space is handled in the shader code (see PropertyNode.cs)
|
||||
}
|
||||
|
||||
// we use Vector4 type to avoid all of the automatic color conversions of PropertyType.Color
|
||||
return new PreviewProperty(PropertyType.Vector4)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = propColor
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new ColorShaderProperty()
|
||||
{
|
||||
sgVersion = sgVersion,
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
colorMode = colorMode,
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion < 2)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
// version 0 upgrades to 2
|
||||
// version 1 upgrades to 3
|
||||
ChangeVersion((sgVersion == 0) ? 2 : 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalCubemapInputMaterialSlot))]
|
||||
class CubemapInputMaterialSlot : CubemapMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableCubemap m_Cubemap = new SerializableCubemap();
|
||||
|
||||
public Cubemap cubemap
|
||||
{
|
||||
get { return m_Cubemap.cubemap; }
|
||||
set { m_Cubemap.cubemap = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => cubemap == null;
|
||||
|
||||
public CubemapInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public CubemapInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new CubemapSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTextureCubeStruct({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new CubemapShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.cubemap = cubemap;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Cubemap)
|
||||
{
|
||||
name = name,
|
||||
cubemapValue = cubemap
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as CubemapInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_Cubemap = slot.m_Cubemap;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalCubemapInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableCubemap m_Cubemap = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_Cubemap.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class CubemapMaterialSlot : MaterialSlot
|
||||
{
|
||||
public CubemapMaterialSlot()
|
||||
{}
|
||||
|
||||
public CubemapMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURECUBE(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Cubemap; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Cubemap; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{}
|
||||
}
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.CubemapShaderProperty")]
|
||||
[BlackboardInputInfo(53)]
|
||||
public sealed class CubemapShaderProperty : AbstractShaderProperty<SerializableCubemap>
|
||||
{
|
||||
internal CubemapShaderProperty()
|
||||
{
|
||||
displayName = "Cubemap";
|
||||
value = new SerializableCubemap();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Cubemap;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", CUBE) = \"\" {{}}";
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._TextureCube, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTextureCube " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURECUBE(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTextureCubeStruct({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
internal bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new CubemapAssetNode { cubemap = value.cubemap };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
cubemapValue = value.cubemap
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new CubemapShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class DynamicMatrixMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Matrix4;
|
||||
|
||||
public DynamicMatrixMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public DynamicMatrixMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.DynamicMatrix; } }
|
||||
|
||||
public override ConcreteSlotValueType concreteValueType
|
||||
{
|
||||
get { return m_ConcreteValueType; }
|
||||
}
|
||||
|
||||
public void SetConcreteType(ConcreteSlotValueType valueType)
|
||||
{
|
||||
m_ConcreteValueType = valueType;
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
var channelCount = (int)SlotValueHelper.GetMatrixDimension(concreteValueType);
|
||||
var values = "";
|
||||
bool isFirst = true;
|
||||
for (var r = 0; r < channelCount; r++)
|
||||
{
|
||||
for (var c = 0; c < channelCount; c++)
|
||||
{
|
||||
if (!isFirst)
|
||||
values += ", ";
|
||||
isFirst = false;
|
||||
values += value.GetRow(r)[c];
|
||||
}
|
||||
}
|
||||
return string.Format("$precision{0}x{0}({1})", channelCount, values);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
AbstractShaderProperty property;
|
||||
switch (concreteValueType)
|
||||
{
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
property = new Matrix4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
property = new Matrix3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
property = new Matrix2ShaderProperty();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
|
||||
property.generatePropertyBlock = false;
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as DynamicMatrixMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class DynamicValueMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
static readonly string[] k_Labels = {"X", "Y", "Z", "W"};
|
||||
|
||||
private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Vector4;
|
||||
|
||||
public DynamicValueMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public DynamicValueMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Matrix4x4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
var labels = k_Labels.Take(concreteValueType.GetChannelCount()).ToArray();
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value.GetRow(0), (newValue) =>
|
||||
value = new Matrix4x4()
|
||||
{
|
||||
m00 = newValue.x, m01 = newValue.y, m02 = newValue.z, m03 = newValue.w,
|
||||
m10 = value.m10, m11 = value.m11, m12 = value.m12, m13 = value.m13,
|
||||
m20 = value.m20, m21 = value.m21, m22 = value.m22, m23 = value.m23,
|
||||
m30 = value.m30, m31 = value.m31, m32 = value.m32, m33 = value.m33,
|
||||
});
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Dynamic; } }
|
||||
|
||||
public override ConcreteSlotValueType concreteValueType
|
||||
{
|
||||
get { return m_ConcreteValueType; }
|
||||
}
|
||||
|
||||
public void SetConcreteType(ConcreteSlotValueType valueType)
|
||||
{
|
||||
m_ConcreteValueType = valueType;
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var propType = concreteValueType.ToPropertyType();
|
||||
var pp = new PreviewProperty(propType) { name = name };
|
||||
if (propType == PropertyType.Float)
|
||||
pp.floatValue = value.m00;
|
||||
else
|
||||
pp.vector4Value = new Vector4(value.m00, value.m01, value.m02, value.m03);
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
|
||||
string values = NodeUtils.FloatToShaderValue(value.m00);
|
||||
if (channelCount == 1)
|
||||
return values;
|
||||
for (var i = 1; i < channelCount; i++)
|
||||
values += ", " + NodeUtils.FloatToShaderValue(value.GetRow(0)[i]);
|
||||
return string.Format("$precision{0}({1})", channelCount, values);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
AbstractShaderProperty property;
|
||||
switch (concreteValueType)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
property = new Vector4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
property = new Vector3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
property = new Vector2ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
property = new Vector1ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
property = new Matrix4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
property = new Matrix3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
property = new Matrix2ShaderProperty();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
|
||||
property.generatePropertyBlock = false;
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as DynamicValueMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Vector4 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Vector4 m_DefaultValue = Vector4.zero;
|
||||
|
||||
static readonly string[] k_Labels = {"X", "Y", "Z", "W"};
|
||||
|
||||
private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Vector4;
|
||||
|
||||
public DynamicVectorMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public DynamicVectorMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public Vector4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
var labels = k_Labels.Take(concreteValueType.GetChannelCount()).ToArray();
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.DynamicVector; } }
|
||||
|
||||
public override ConcreteSlotValueType concreteValueType
|
||||
{
|
||||
get { return m_ConcreteValueType; }
|
||||
}
|
||||
|
||||
public void SetConcreteType(ConcreteSlotValueType valueType)
|
||||
{
|
||||
m_ConcreteValueType = valueType;
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var propType = concreteValueType.ToPropertyType();
|
||||
var pp = new PreviewProperty(propType) { name = name };
|
||||
if (propType == PropertyType.Float)
|
||||
pp.floatValue = value.x;
|
||||
else
|
||||
pp.vector4Value = new Vector4(value.x, value.y, value.z, value.w);
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
|
||||
string values = NodeUtils.FloatToShaderValue(value.x);
|
||||
if (channelCount == 1)
|
||||
return values;
|
||||
for (var i = 1; i < channelCount; i++)
|
||||
values += ", " + NodeUtils.FloatToShaderValue(value[i]);
|
||||
return string.Format("$precision{0}({1})", channelCount, values);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
AbstractShaderProperty property;
|
||||
switch (concreteValueType)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
property = new Vector4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
property = new Vector3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
property = new Vector2ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
property = new Vector1ShaderProperty();
|
||||
break;
|
||||
default:
|
||||
// This shouldn't happen due to edge validation. The generated shader will
|
||||
// have errors.
|
||||
Debug.LogError($"Invalid value type {concreteValueType} passed to Vector Slot {displayName}. Value will be ignored, please plug in an edge with a vector type.");
|
||||
return;
|
||||
}
|
||||
|
||||
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
|
||||
property.generatePropertyBlock = false;
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as DynamicVectorMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class GradientInputMaterialSlot : GradientMaterialSlot, IMaterialSlotHasValue<Gradient>
|
||||
{
|
||||
[SerializeField]
|
||||
Gradient m_Value = new Gradient();
|
||||
|
||||
[SerializeField]
|
||||
Gradient m_DefaultValue = new Gradient();
|
||||
|
||||
public GradientInputMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public GradientInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public Gradient value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public Gradient defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new GradientSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
if (generationMode.IsPreview())
|
||||
return GradientUtil.GetGradientForPreview(matOwner.GetVariableNameForSlot(id));
|
||||
|
||||
return ConcreteSlotValueAsVariable();
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return GradientUtil.GetGradientValue(value, "");
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
if (generationMode != GenerationMode.Preview)
|
||||
return;
|
||||
|
||||
GradientUtil.GetGradientPropertiesForPreview(properties, matOwner.GetVariableNameForSlot(id), value);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
properties.Add(new PreviewProperty(PropertyType.Gradient)
|
||||
{
|
||||
name = name,
|
||||
gradientValue = value
|
||||
});
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as GradientInputMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class GradientMaterialSlot : MaterialSlot
|
||||
{
|
||||
public GradientMaterialSlot()
|
||||
{}
|
||||
|
||||
public GradientMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Gradient; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Gradient; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.ShaderGraph.Drawing.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(30)]
|
||||
class GradientShaderProperty : AbstractShaderProperty<Gradient>
|
||||
{
|
||||
public GradientShaderProperty()
|
||||
{
|
||||
displayName = "Gradient";
|
||||
value = new Gradient();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Gradient;
|
||||
|
||||
internal override bool isExposable => false;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
Action<ShaderStringBuilder> customDecl = (builder) =>
|
||||
{
|
||||
builder.AppendLine("Gradient {0}_Definition()", referenceName);
|
||||
using (builder.BlockScope())
|
||||
{
|
||||
string[] colors = new string[8];
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
colors[i] = string.Format("g.colors[{0}] = {1}4(0, 0, 0, 0);", i, concretePrecision.ToShaderString());
|
||||
for (int i = 0; i < value.colorKeys.Length; i++)
|
||||
colors[i] = string.Format("g.colors[{0}] = {1}4({2}, {3}, {4}, {5});"
|
||||
, i
|
||||
, concretePrecision.ToShaderString()
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].color.r)
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].color.g)
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].color.b)
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].time));
|
||||
|
||||
string[] alphas = new string[8];
|
||||
for (int i = 0; i < alphas.Length; i++)
|
||||
alphas[i] = string.Format("g.alphas[{0}] = {1}2(0, 0);", i, concretePrecision.ToShaderString());
|
||||
for (int i = 0; i < value.alphaKeys.Length; i++)
|
||||
alphas[i] = string.Format("g.alphas[{0}] = {1}2({2}, {3});"
|
||||
, i
|
||||
, concretePrecision.ToShaderString()
|
||||
, NodeUtils.FloatToShaderValue(value.alphaKeys[i].alpha)
|
||||
, NodeUtils.FloatToShaderValue(value.alphaKeys[i].time));
|
||||
|
||||
builder.AppendLine("Gradient g;");
|
||||
builder.AppendLine("g.type = {0};",
|
||||
(int)value.mode);
|
||||
builder.AppendLine("g.colorsLength = {0};",
|
||||
value.colorKeys.Length);
|
||||
builder.AppendLine("g.alphasLength = {0};",
|
||||
value.alphaKeys.Length);
|
||||
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
builder.AppendLine(colors[i]);
|
||||
|
||||
for (int i = 0; i < alphas.Length; i++)
|
||||
builder.AppendLine(alphas[i]);
|
||||
builder.AppendLine("return g;", true);
|
||||
}
|
||||
builder.AppendIndentation();
|
||||
builder.Append("#define {0} {0}_Definition()", referenceName);
|
||||
};
|
||||
|
||||
action(
|
||||
new HLSLProperty(HLSLType._CUSTOM, referenceName, HLSLDeclaration.Global, concretePrecision)
|
||||
{
|
||||
customDeclaration = customDecl
|
||||
});
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "Gradient " + referenceName;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new GradientNode { gradient = value };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
gradientValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new GradientShaderProperty
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphConcretization
|
||||
{
|
||||
public static void ConcretizeNode(AbstractMaterialNode node)
|
||||
{
|
||||
node.Concretize();
|
||||
}
|
||||
|
||||
public static void ConcretizeProperties(GraphData graph)
|
||||
{
|
||||
var propertyNodes = graph.GetNodes<PropertyNode>().Where(n => !graph.m_Properties.Any(p => p == n.property)).ToArray();
|
||||
foreach (var pNode in propertyNodes)
|
||||
graph.ReplacePropertyNodeWithConcreteNodeNoValidate(pNode);
|
||||
}
|
||||
|
||||
public static void ConcretizeGraph(GraphData graph)
|
||||
{
|
||||
ConcretizeProperties(graph);
|
||||
GraphDataUtils.ApplyActionLeafFirst(graph, ConcretizeNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphDataUtils
|
||||
{
|
||||
public static void ApplyActionLeafFirst(GraphData graph, Action<AbstractMaterialNode> action)
|
||||
{
|
||||
var temporaryMarks = PooledHashSet<string>.Get();
|
||||
var permanentMarks = PooledHashSet<string>.Get();
|
||||
var slots = ListPool<MaterialSlot>.Get();
|
||||
|
||||
// Make sure we process a node's children before the node itself.
|
||||
var stack = StackPool<AbstractMaterialNode>.Get();
|
||||
foreach (var node in graph.GetNodes<AbstractMaterialNode>())
|
||||
{
|
||||
stack.Push(node);
|
||||
}
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var node = stack.Pop();
|
||||
if (permanentMarks.Contains(node.objectId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temporaryMarks.Contains(node.objectId))
|
||||
{
|
||||
action.Invoke(node);
|
||||
permanentMarks.Add(node.objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
temporaryMarks.Add(node.objectId);
|
||||
stack.Push(node);
|
||||
node.GetInputSlots(slots);
|
||||
foreach (var inputSlot in slots)
|
||||
{
|
||||
var nodeEdges = graph.GetEdges(inputSlot.slotReference);
|
||||
foreach (var edge in nodeEdges)
|
||||
{
|
||||
var fromSocketRef = edge.outputSlot;
|
||||
var childNode = fromSocketRef.node;
|
||||
if (childNode != null)
|
||||
{
|
||||
stack.Push(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
slots.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
StackPool<AbstractMaterialNode>.Release(stack);
|
||||
ListPool<MaterialSlot>.Release(slots);
|
||||
temporaryMarks.Dispose();
|
||||
permanentMarks.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphSetup
|
||||
{
|
||||
public static void SetupNode(AbstractMaterialNode node)
|
||||
{
|
||||
node.Setup();
|
||||
}
|
||||
|
||||
public static void SetupGraph(GraphData graph)
|
||||
{
|
||||
GraphDataUtils.ApplyActionLeafFirst(graph, SetupNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphValidation
|
||||
{
|
||||
public static void ValidateNode(AbstractMaterialNode node)
|
||||
{
|
||||
Type t = node.GetType();
|
||||
node.ValidateNode();
|
||||
if (!(node is BlockNode))
|
||||
{
|
||||
bool disallowedByAnyTargets = false;
|
||||
bool disallowedByAllTargets = true;
|
||||
IEnumerable<Target> targets = node.owner.activeTargets;
|
||||
if (node.owner.isSubGraph)
|
||||
{
|
||||
targets = node.owner.allPotentialTargets;
|
||||
}
|
||||
foreach (var target in targets)
|
||||
{
|
||||
//if at least one target doesn't allow a node, it is considered invalid
|
||||
if (!target.IsNodeAllowedByTarget(t))
|
||||
{
|
||||
disallowedByAnyTargets = true;
|
||||
node.isValid = false;
|
||||
node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by {target.displayName} implementation", Rendering.ShaderCompilerMessageSeverity.Warning);
|
||||
node.owner.m_UnsupportedTargets.Add(target);
|
||||
}
|
||||
//at least one target does allow node, not going to be explicitly set inactive
|
||||
else
|
||||
{
|
||||
disallowedByAllTargets = false;
|
||||
}
|
||||
}
|
||||
if (!disallowedByAnyTargets)
|
||||
{
|
||||
node.isValid = true;
|
||||
}
|
||||
|
||||
//Set ActiveState based on if all targets disallow this node
|
||||
if (disallowedByAllTargets)
|
||||
{
|
||||
node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.ExplicitInactive);
|
||||
node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by any active targets, and will not be used in generation", Rendering.ShaderCompilerMessageSeverity.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.Implicit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateGraph(GraphData graph)
|
||||
{
|
||||
graph.m_UnsupportedTargets.Clear();
|
||||
GraphDataUtils.ApplyActionLeafFirst(graph, ValidateNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
public class GroupData : JsonObject
|
||||
{
|
||||
[SerializeField]
|
||||
string m_Title;
|
||||
|
||||
public string title
|
||||
{
|
||||
get { return m_Title; }
|
||||
set { m_Title = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_Position;
|
||||
|
||||
public Vector2 position
|
||||
{
|
||||
get { return m_Position; }
|
||||
set { m_Position = value; }
|
||||
}
|
||||
|
||||
public GroupData() : base() {}
|
||||
|
||||
public GroupData(string title, Vector2 position)
|
||||
{
|
||||
m_Title = title;
|
||||
m_Position = position;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
interface IMaterialSlotHasValue<T>
|
||||
{
|
||||
T defaultValue { get; }
|
||||
T value { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
internal static class LightmappingShaderProperties
|
||||
{
|
||||
public class LightmapTextureArrayProperty : Texture2DArrayShaderProperty
|
||||
{
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
// no declaration from ShaderGraph side -- declared by SRP internal include files
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly LightmapTextureArrayProperty kLightmapsArray = new LightmapTextureArrayProperty()
|
||||
{
|
||||
displayName = "unity_Lightmaps",
|
||||
generatePropertyBlock = true,
|
||||
overrideHLSLDeclaration = false,
|
||||
hlslDeclarationOverride = HLSLDeclaration.DoNotDeclare,
|
||||
hidden = true,
|
||||
modifiable = true,
|
||||
overrideReferenceName = "unity_Lightmaps",
|
||||
precision = Precision.Single
|
||||
};
|
||||
|
||||
public static readonly LightmapTextureArrayProperty kLightmapsIndirectionArray = new LightmapTextureArrayProperty()
|
||||
{
|
||||
displayName = "unity_LightmapsInd",
|
||||
generatePropertyBlock = true,
|
||||
overrideHLSLDeclaration = false,
|
||||
hlslDeclarationOverride = HLSLDeclaration.DoNotDeclare,
|
||||
hidden = true,
|
||||
modifiable = true,
|
||||
overrideReferenceName = "unity_LightmapsInd",
|
||||
precision = Precision.Single
|
||||
};
|
||||
|
||||
public static readonly LightmapTextureArrayProperty kShadowMasksArray = new LightmapTextureArrayProperty()
|
||||
{
|
||||
displayName = "unity_ShadowMasks",
|
||||
generatePropertyBlock = true,
|
||||
overrideHLSLDeclaration = false,
|
||||
hlslDeclarationOverride = HLSLDeclaration.DoNotDeclare,
|
||||
hidden = true,
|
||||
modifiable = true,
|
||||
overrideReferenceName = "unity_ShadowMasks",
|
||||
precision = Precision.Single
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,338 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
abstract class MaterialSlot : JsonObject
|
||||
{
|
||||
const string k_NotInit = "Not Initilaized";
|
||||
|
||||
[SerializeField]
|
||||
int m_Id;
|
||||
|
||||
[SerializeField]
|
||||
string m_DisplayName = k_NotInit;
|
||||
|
||||
[SerializeField]
|
||||
SlotType m_SlotType = SlotType.Input;
|
||||
|
||||
[SerializeField]
|
||||
bool m_Hidden;
|
||||
|
||||
[SerializeField]
|
||||
string m_ShaderOutputName;
|
||||
|
||||
[SerializeField]
|
||||
ShaderStageCapability m_StageCapability;
|
||||
|
||||
bool m_HasError;
|
||||
|
||||
protected MaterialSlot() {}
|
||||
|
||||
protected MaterialSlot(int slotId, string displayName, string shaderOutputName, SlotType slotType, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
{
|
||||
m_Id = slotId;
|
||||
m_DisplayName = displayName;
|
||||
m_SlotType = slotType;
|
||||
m_Hidden = hidden;
|
||||
m_ShaderOutputName = shaderOutputName;
|
||||
this.stageCapability = stageCapability;
|
||||
}
|
||||
|
||||
internal void SetInternalData(SlotType slotType, string shaderOutputName)
|
||||
{
|
||||
this.m_SlotType = slotType;
|
||||
this.shaderOutputName = shaderOutputName;
|
||||
}
|
||||
|
||||
public virtual VisualElement InstantiateControl()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
static string ConcreteSlotValueTypeAsString(ConcreteSlotValueType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
return "(1)";
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
return "(2)";
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
return "(3)";
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
return "(4)";
|
||||
case ConcreteSlotValueType.Boolean:
|
||||
return "(B)";
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
return "(2x2)";
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
return "(3x3)";
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
return "(4x4)";
|
||||
case ConcreteSlotValueType.SamplerState:
|
||||
return "(SS)";
|
||||
case ConcreteSlotValueType.Texture2D:
|
||||
return "(T2)";
|
||||
case ConcreteSlotValueType.Texture2DArray:
|
||||
return "(T2A)";
|
||||
case ConcreteSlotValueType.Texture3D:
|
||||
return "(T3)";
|
||||
case ConcreteSlotValueType.Cubemap:
|
||||
return "(C)";
|
||||
case ConcreteSlotValueType.Gradient:
|
||||
return "(G)";
|
||||
case ConcreteSlotValueType.VirtualTexture:
|
||||
return "(VT)";
|
||||
default:
|
||||
return "(E)";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string displayName
|
||||
{
|
||||
get { return m_DisplayName + ConcreteSlotValueTypeAsString(concreteValueType); }
|
||||
set { m_DisplayName = value; }
|
||||
}
|
||||
|
||||
public string RawDisplayName()
|
||||
{
|
||||
return m_DisplayName;
|
||||
}
|
||||
|
||||
public static MaterialSlot CreateMaterialSlot(SlotValueType type, int slotId, string displayName, string shaderOutputName, SlotType slotType, Vector4 defaultValue, ShaderStageCapability shaderStageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SlotValueType.SamplerState:
|
||||
return new SamplerStateMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.DynamicMatrix:
|
||||
return new DynamicMatrixMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Matrix4:
|
||||
return new Matrix4MaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Matrix3:
|
||||
return new Matrix3MaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Matrix2:
|
||||
return new Matrix2MaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Texture2D:
|
||||
return slotType == SlotType.Input
|
||||
? new Texture2DInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new Texture2DMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Texture2DArray:
|
||||
return slotType == SlotType.Input
|
||||
? new Texture2DArrayInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new Texture2DArrayMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Texture3D:
|
||||
return slotType == SlotType.Input
|
||||
? new Texture3DInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new Texture3DMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Cubemap:
|
||||
return slotType == SlotType.Input
|
||||
? new CubemapInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new CubemapMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.VirtualTexture:
|
||||
return slotType == SlotType.Input
|
||||
? new VirtualTextureInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new VirtualTextureMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Gradient:
|
||||
return slotType == SlotType.Input
|
||||
? new GradientInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new GradientMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.DynamicVector:
|
||||
return new DynamicVectorMaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden);
|
||||
case SlotValueType.Vector4:
|
||||
return new Vector4MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Vector3:
|
||||
return new Vector3MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Vector2:
|
||||
return new Vector2MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Vector1:
|
||||
return new Vector1MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue.x, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Dynamic:
|
||||
return new DynamicValueMaterialSlot(slotId, displayName, shaderOutputName, slotType, new Matrix4x4(defaultValue, Vector4.zero, Vector4.zero, Vector4.zero), shaderStageCapability, hidden);
|
||||
case SlotValueType.Boolean:
|
||||
return new BooleanMaterialSlot(slotId, displayName, shaderOutputName, slotType, false, shaderStageCapability, hidden);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("type", type, null);
|
||||
}
|
||||
|
||||
public SlotReference slotReference
|
||||
{
|
||||
get { return new SlotReference(owner, m_Id); }
|
||||
}
|
||||
|
||||
public AbstractMaterialNode owner { get; set; }
|
||||
|
||||
// if hidden, the slot does not create a port in the UI
|
||||
public bool hidden
|
||||
{
|
||||
get { return m_Hidden; }
|
||||
set { m_Hidden = value; }
|
||||
}
|
||||
|
||||
public int id
|
||||
{
|
||||
get { return m_Id; }
|
||||
}
|
||||
|
||||
public bool isInputSlot
|
||||
{
|
||||
get { return m_SlotType == SlotType.Input; }
|
||||
}
|
||||
|
||||
public bool isOutputSlot
|
||||
{
|
||||
get { return m_SlotType == SlotType.Output; }
|
||||
}
|
||||
|
||||
public SlotType slotType
|
||||
{
|
||||
get { return m_SlotType; }
|
||||
}
|
||||
|
||||
public bool isConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
// node and graph respectivly
|
||||
if (owner == null || owner.owner == null)
|
||||
return false;
|
||||
|
||||
var graph = owner.owner;
|
||||
var edges = graph.GetEdges(slotReference);
|
||||
return edges.Any();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool isDefaultValue { get; }
|
||||
|
||||
public abstract SlotValueType valueType { get; }
|
||||
|
||||
public abstract ConcreteSlotValueType concreteValueType { get; }
|
||||
|
||||
public string shaderOutputName
|
||||
{
|
||||
get { return m_ShaderOutputName; }
|
||||
private set { m_ShaderOutputName = value; }
|
||||
}
|
||||
|
||||
public ShaderStageCapability stageCapability
|
||||
{
|
||||
get { return m_StageCapability; }
|
||||
set { m_StageCapability = value; }
|
||||
}
|
||||
|
||||
public bool hasError
|
||||
{
|
||||
get { return m_HasError; }
|
||||
set { m_HasError = value; }
|
||||
}
|
||||
|
||||
public bool IsUsingDefaultValue()
|
||||
{
|
||||
if (!isConnected && isDefaultValue)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsCompatibleWith(MaterialSlot otherSlot)
|
||||
{
|
||||
return otherSlot != null
|
||||
&& otherSlot.owner != owner
|
||||
&& otherSlot.isInputSlot != isInputSlot
|
||||
&& ((isInputSlot
|
||||
? SlotValueHelper.AreCompatible(valueType, otherSlot.concreteValueType)
|
||||
: SlotValueHelper.AreCompatible(otherSlot.valueType, concreteValueType)));
|
||||
}
|
||||
|
||||
public bool IsCompatibleStageWith(MaterialSlot otherSlot)
|
||||
{
|
||||
var candidateStage = otherSlot.stageCapability;
|
||||
return stageCapability == ShaderStageCapability.All || candidateStage == stageCapability;
|
||||
}
|
||||
|
||||
public string GetDefaultValue(GenerationMode generationMode, ConcretePrecision concretePrecision)
|
||||
{
|
||||
string defaultValue = GetDefaultValue(generationMode);
|
||||
return defaultValue.Replace(PrecisionUtil.Token, concretePrecision.ToShaderString());
|
||||
}
|
||||
|
||||
public virtual string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
if (generationMode.IsPreview() && matOwner.isActive)
|
||||
return matOwner.GetVariableNameForSlot(id);
|
||||
|
||||
return ConcreteSlotValueAsVariable();
|
||||
}
|
||||
|
||||
protected virtual string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
|
||||
public abstract void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode);
|
||||
|
||||
public virtual void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
properties.Add(default(PreviewProperty));
|
||||
}
|
||||
|
||||
public virtual void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
sb.Append(concreteValueType.ToShaderString());
|
||||
sb.Append(" ");
|
||||
sb.Append(paramName);
|
||||
}
|
||||
|
||||
public abstract void CopyValuesFrom(MaterialSlot foundSlot);
|
||||
|
||||
public bool Equals(MaterialSlot other)
|
||||
{
|
||||
return m_Id == other.m_Id && owner == other.owner;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((MaterialSlot)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (m_Id * 397) ^ (owner != null ? owner.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// this tracks old CustomFunctionNode slots that are expecting the old bare resource inputs
|
||||
// rather than the new structure-based inputs
|
||||
internal virtual bool bareResource { get { return false; } set {} }
|
||||
|
||||
public virtual void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
m_Id = other.m_Id;
|
||||
m_DisplayName = other.m_DisplayName;
|
||||
m_SlotType = other.m_SlotType;
|
||||
m_Hidden = other.m_Hidden;
|
||||
m_ShaderOutputName = other.m_ShaderOutputName;
|
||||
m_StageCapability = other.m_StageCapability;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Matrix2MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
public Matrix2MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Matrix2MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "$precision2x2 (1,0,0,1)";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Matrix2ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Matrix2)
|
||||
{
|
||||
name = name,
|
||||
matrixValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Matrix2; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Matrix2; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Matrix2MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(70)]
|
||||
class Matrix2ShaderProperty : MatrixShaderProperty
|
||||
{
|
||||
public Matrix2ShaderProperty()
|
||||
{
|
||||
displayName = "Matrix2x2";
|
||||
value = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Matrix2;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concretePrecision.ToShaderString()}2x2 {referenceName}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Matrix2Node
|
||||
{
|
||||
row0 = new Vector2(value.m00, value.m01),
|
||||
row1 = new Vector2(value.m10, value.m11)
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
matrixValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Matrix2ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// all old matrices were declared global; yes even if flagged hybrid!
|
||||
// maintain old behavior on versioning, users can always change the override if they wish
|
||||
overrideHLSLDeclaration = true;
|
||||
hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Matrix3MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
public Matrix3MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Matrix3MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "$precision3x3 (1,0,0,0,1,0,0,0,1)";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Matrix3ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Matrix3)
|
||||
{
|
||||
name = name,
|
||||
matrixValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Matrix3; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Matrix3; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Matrix3MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(71)]
|
||||
class Matrix3ShaderProperty : MatrixShaderProperty
|
||||
{
|
||||
public Matrix3ShaderProperty()
|
||||
{
|
||||
displayName = "Matrix3x3";
|
||||
value = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Matrix3;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concretePrecision.ToShaderString()}3x3 {referenceName}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Matrix3Node
|
||||
{
|
||||
row0 = new Vector3(value.m00, value.m01, value.m02),
|
||||
row1 = new Vector3(value.m10, value.m11, value.m12),
|
||||
row2 = new Vector3(value.m20, value.m21, value.m22)
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
matrixValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Matrix3ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// all old matrices were declared global; yes even if flagged hybrid!
|
||||
// maintain old behavior on versioning, users can always change the override if they wish
|
||||
overrideHLSLDeclaration = true;
|
||||
hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Matrix4MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
public Matrix4MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Matrix4MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "$precision4x4 (1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Matrix4ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Matrix4)
|
||||
{
|
||||
name = name,
|
||||
matrixValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Matrix4; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Matrix4; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Matrix4MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(72)]
|
||||
class Matrix4ShaderProperty : MatrixShaderProperty
|
||||
{
|
||||
public Matrix4ShaderProperty()
|
||||
{
|
||||
displayName = "Matrix4x4";
|
||||
value = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Matrix4;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concretePrecision.ToShaderString()}4x4 {referenceName}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Matrix4Node
|
||||
{
|
||||
row0 = new Vector4(value.m00, value.m01, value.m02, value.m03),
|
||||
row1 = new Vector4(value.m10, value.m11, value.m12, value.m13),
|
||||
row2 = new Vector4(value.m20, value.m21, value.m22, value.m23),
|
||||
row3 = new Vector4(value.m30, value.m31, value.m32, value.m33)
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
matrixValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Matrix4ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// all old matrices were declared global; yes even if flagged hybrid!
|
||||
// maintain old behavior on versioning, users can always change the override if they wish
|
||||
overrideHLSLDeclaration = true;
|
||||
hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
abstract class MatrixShaderProperty : AbstractShaderProperty<Matrix4x4>
|
||||
{
|
||||
internal override bool isExposable => false;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override HLSLDeclaration GetDefaultHLSLDeclaration()
|
||||
{
|
||||
if (overrideHLSLDeclaration)
|
||||
return hlslDeclarationOverride;
|
||||
|
||||
// Since Matrices cannot be exposed, the default declaration rules would set them to Global.
|
||||
// However, this means new Matrix properties would be different from all other float-based property types
|
||||
// (all others use UnityPerMaterial by default, because they are exposed).
|
||||
// So instead, we override the default rules so that Matrices always default to UnityPerMaterial
|
||||
return HLSLDeclaration.UnityPerMaterial;
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
|
||||
// HLSL decl is always 4x4 even if matrix smaller
|
||||
action(new HLSLProperty(HLSLType._matrix4x4, referenceName, decl, concretePrecision));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Legacy;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimal version of <see cref="GraphData"/> used for gathering dependencies. This allows us to not deserialize
|
||||
/// all the nodes, ports, edges, groups etc., which is important as we cannot share data between
|
||||
/// <see cref="ShaderSubGraphImporter.GatherDependenciesFromSourceFile"/> and
|
||||
/// <see cref="ShaderSubGraphImporter.OnImportAsset"/>. The latter must always import fully, but for the former we
|
||||
/// want to avoid the extra GC pressure.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
class MinimalGraphData
|
||||
{
|
||||
static Dictionary<string, Type> s_MinimalTypeMap = CreateMinimalTypeMap();
|
||||
|
||||
static Dictionary<string, Type> CreateMinimalTypeMap()
|
||||
{
|
||||
var types = new Dictionary<string, Type>();
|
||||
foreach (var type in TypeCache.GetTypesWithAttribute<HasDependenciesAttribute>())
|
||||
{
|
||||
var dependencyAttribute = (HasDependenciesAttribute)type.GetCustomAttributes(typeof(HasDependenciesAttribute), false)[0];
|
||||
if (!typeof(IHasDependencies).IsAssignableFrom(dependencyAttribute.minimalType))
|
||||
{
|
||||
Debug.LogError($"{type} must implement {typeof(IHasDependencies)} to be used in {typeof(HasDependenciesAttribute)}");
|
||||
continue;
|
||||
}
|
||||
|
||||
types.Add(type.FullName, dependencyAttribute.minimalType);
|
||||
|
||||
var formerNameAttributes = (FormerNameAttribute[])type.GetCustomAttributes(typeof(FormerNameAttribute), false);
|
||||
foreach (var formerNameAttribute in formerNameAttributes)
|
||||
{
|
||||
types.Add(formerNameAttribute.fullName, dependencyAttribute.minimalType);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
|
||||
|
||||
// gather all asset dependencies declared by nodes in the given (shadergraph or shadersubgraph) asset
|
||||
// by reading the source file from disk, and doing a minimal parse
|
||||
// returns true if it successfully gathered the dependencies, false if there was an error
|
||||
public static bool GatherMinimalDependenciesFromFile(string assetPath, AssetCollection assetCollection)
|
||||
{
|
||||
var textGraph = FileUtilities.SafeReadAllText(assetPath);
|
||||
|
||||
// if we can't read the file, no dependencies can be gathered
|
||||
if (string.IsNullOrEmpty(textGraph))
|
||||
return false;
|
||||
|
||||
var entries = MultiJsonInternal.Parse(textGraph);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(entries[0].type))
|
||||
{
|
||||
var minimalGraphData = JsonUtility.FromJson<MinimalGraphData>(textGraph);
|
||||
entries.Clear();
|
||||
foreach (var node in minimalGraphData.m_SerializableNodes)
|
||||
{
|
||||
entries.Add(new MultiJsonEntry(node.typeInfo.fullName, null, node.JSONnodeData));
|
||||
AbstractMaterialNode0 amn = new AbstractMaterialNode0();
|
||||
JsonUtility.FromJsonOverwrite(node.JSONnodeData, amn);
|
||||
foreach (var slot in amn.m_SerializableSlots)
|
||||
{
|
||||
entries.Add(new MultiJsonEntry(slot.typeInfo.fullName, null, slot.JSONnodeData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (s_MinimalTypeMap.TryGetValue(entry.type, out var minimalType))
|
||||
{
|
||||
var instance = (IHasDependencies)Activator.CreateInstance(minimalType);
|
||||
JsonUtility.FromJsonOverwrite(entry.json, instance);
|
||||
instance.GetSourceAssetDependencies(assetCollection);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class NormalMaterialSlot : SpaceMaterialSlot, IMayRequireNormal
|
||||
{
|
||||
public NormalMaterialSlot()
|
||||
{}
|
||||
|
||||
public NormalMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Normal));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
struct ParentGroupChange
|
||||
{
|
||||
public IGroupItem groupItem;
|
||||
public GroupData oldGroup;
|
||||
public GroupData newGroup;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class PositionMaterialSlot : SpaceMaterialSlot, IMayRequirePosition
|
||||
{
|
||||
public PositionMaterialSlot()
|
||||
{}
|
||||
|
||||
public PositionMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresPosition(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
enum PreviewMode
|
||||
{
|
||||
Inherit, // this usually means: 2D, unless a connected input node is 3D, in which case it is 3D
|
||||
Preview2D,
|
||||
Preview3D
|
||||
}
|
||||
}
|
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
struct PreviewProperty
|
||||
{
|
||||
public string name { get; set; }
|
||||
public PropertyType propType { get; private set; }
|
||||
|
||||
public PreviewProperty(PropertyType type) : this()
|
||||
{
|
||||
propType = type;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
struct ClassData
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Texture textureValue;
|
||||
[FieldOffset(0)]
|
||||
public Cubemap cubemapValue;
|
||||
[FieldOffset(0)]
|
||||
public Gradient gradientValue;
|
||||
[FieldOffset(0)]
|
||||
public VirtualTextureShaderProperty vtProperty;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
struct StructData
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Color colorValue;
|
||||
[FieldOffset(0)]
|
||||
public Vector4 vector4Value;
|
||||
[FieldOffset(0)]
|
||||
public float floatValue;
|
||||
[FieldOffset(0)]
|
||||
public bool booleanValue;
|
||||
[FieldOffset(0)]
|
||||
public Matrix4x4 matrixValue;
|
||||
}
|
||||
|
||||
ClassData m_ClassData;
|
||||
StructData m_StructData;
|
||||
Texture2DShaderProperty.DefaultType m_texture2dDefaultType;
|
||||
|
||||
public Color colorValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Color)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Color, propType));
|
||||
return m_StructData.colorValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Color)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Color, propType));
|
||||
m_StructData.colorValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture textureValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Texture2D && propType != PropertyType.Texture2DArray && propType != PropertyType.Texture3D)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Texture2D, propType));
|
||||
return m_ClassData.textureValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Texture2D && propType != PropertyType.Texture2DArray && propType != PropertyType.Texture3D)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Texture2D, propType));
|
||||
m_ClassData.textureValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2DShaderProperty.DefaultType texture2DDefaultType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Texture2D)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, "Texture2DShaderProperty.DefaultType", propType));
|
||||
return m_texture2dDefaultType;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Texture2D)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, "Texture2DShaderProperty.DefaultType", propType));
|
||||
m_texture2dDefaultType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Cubemap cubemapValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Cubemap)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Cubemap, propType));
|
||||
return m_ClassData.cubemapValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Cubemap)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Cubemap, propType));
|
||||
m_ClassData.cubemapValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Gradient gradientValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Gradient)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Gradient, propType));
|
||||
return m_ClassData.gradientValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Gradient)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Gradient, propType));
|
||||
m_ClassData.gradientValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public VirtualTextureShaderProperty vtProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.VirtualTexture)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Gradient, propType));
|
||||
return m_ClassData.vtProperty;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.VirtualTexture)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Gradient, propType));
|
||||
m_ClassData.vtProperty = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4 vector4Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Vector4, propType));
|
||||
return m_StructData.vector4Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4
|
||||
&& propType != PropertyType.Matrix2 && propType != PropertyType.Matrix3 && propType != PropertyType.Matrix4)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Vector4, propType));
|
||||
m_StructData.vector4Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float floatValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Float)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Float, propType));
|
||||
return m_StructData.floatValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Float)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Float, propType));
|
||||
m_StructData.floatValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool booleanValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Boolean)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Boolean, propType));
|
||||
return m_StructData.booleanValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Boolean)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Boolean, propType));
|
||||
m_StructData.booleanValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix4x4 matrixValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Matrix2 && propType != PropertyType.Matrix3 && propType != PropertyType.Matrix4)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Boolean, propType));
|
||||
return m_StructData.matrixValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Matrix2 && propType != PropertyType.Matrix3 && propType != PropertyType.Matrix4)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Boolean, propType));
|
||||
m_StructData.matrixValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
const string k_SetErrorMessage = "Cannot set a {0} property on a PreviewProperty with type {1}.";
|
||||
const string k_GetErrorMessage = "Cannot get a {0} property on a PreviewProperty with type {1}.";
|
||||
|
||||
public void SetValueOnMaterialPropertyBlock(MaterialPropertyBlock mat)
|
||||
{
|
||||
if ((propType == PropertyType.Texture2D || propType == PropertyType.Texture2DArray || propType == PropertyType.Texture3D))
|
||||
{
|
||||
if (m_ClassData.textureValue == null)
|
||||
{
|
||||
// there's no way to set the texture back to NULL
|
||||
// and no way to delete the property either
|
||||
// so instead we set the value to what we know the default will be
|
||||
// (all textures in ShaderGraph default to white)
|
||||
switch (m_texture2dDefaultType)
|
||||
{
|
||||
case Texture2DShaderProperty.DefaultType.White:
|
||||
mat.SetTexture(name, Texture2D.whiteTexture);
|
||||
break;
|
||||
case Texture2DShaderProperty.DefaultType.Black:
|
||||
mat.SetTexture(name, Texture2D.blackTexture);
|
||||
break;
|
||||
case Texture2DShaderProperty.DefaultType.Grey:
|
||||
mat.SetTexture(name, Texture2D.grayTexture);
|
||||
break;
|
||||
case Texture2DShaderProperty.DefaultType.Bump:
|
||||
mat.SetTexture(name, Texture2D.normalTexture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
mat.SetTexture(name, m_ClassData.textureValue);
|
||||
}
|
||||
else if (propType == PropertyType.Cubemap)
|
||||
{
|
||||
if (m_ClassData.cubemapValue == null)
|
||||
{
|
||||
// there's no way to set the texture back to NULL
|
||||
// and no way to delete the property either
|
||||
// so instead we set the value to what we know the default will be
|
||||
// (all textures in ShaderGraph default to white)
|
||||
// there's no Cubemap.whiteTexture, but this seems to work
|
||||
mat.SetTexture(name, Texture2D.whiteTexture);
|
||||
}
|
||||
else
|
||||
mat.SetTexture(name, m_ClassData.cubemapValue);
|
||||
}
|
||||
else if (propType == PropertyType.Color)
|
||||
mat.SetColor(name, m_StructData.colorValue);
|
||||
else if (propType == PropertyType.Vector2 || propType == PropertyType.Vector3 || propType == PropertyType.Vector4)
|
||||
mat.SetVector(name, m_StructData.vector4Value);
|
||||
else if (propType == PropertyType.Float)
|
||||
mat.SetFloat(name, m_StructData.floatValue);
|
||||
else if (propType == PropertyType.Boolean)
|
||||
mat.SetFloat(name, m_StructData.booleanValue ? 1 : 0);
|
||||
else if (propType == PropertyType.Matrix2 || propType == PropertyType.Matrix3 || propType == PropertyType.Matrix4)
|
||||
mat.SetMatrix(name, m_StructData.matrixValue);
|
||||
else if (propType == PropertyType.Gradient)
|
||||
{
|
||||
mat.SetFloat(string.Format("{0}_Type", name), (int)m_ClassData.gradientValue.mode);
|
||||
mat.SetFloat(string.Format("{0}_ColorsLength", name), m_ClassData.gradientValue.colorKeys.Length);
|
||||
mat.SetFloat(string.Format("{0}_AlphasLength", name), m_ClassData.gradientValue.alphaKeys.Length);
|
||||
for (int i = 0; i < 8; i++)
|
||||
mat.SetVector(string.Format("{0}_ColorKey{1}", name, i), i < m_ClassData.gradientValue.colorKeys.Length ? GradientUtil.ColorKeyToVector(m_ClassData.gradientValue.colorKeys[i]) : Vector4.zero);
|
||||
for (int i = 0; i < 8; i++)
|
||||
mat.SetVector(string.Format("{0}_AlphaKey{1}", name, i), i < m_ClassData.gradientValue.alphaKeys.Length ? GradientUtil.AlphaKeyToVector(m_ClassData.gradientValue.alphaKeys[i]) : Vector2.zero);
|
||||
}
|
||||
else if (propType == PropertyType.VirtualTexture)
|
||||
{
|
||||
// virtual texture assignments are not supported via the material property block, we must assign them to the materials
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class SamplerStateMaterialSlot : MaterialSlot
|
||||
{
|
||||
public SamplerStateMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public SamplerStateMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
// we have to use our modified macro declaration here, to ensure that something is declared for GLES2 platforms
|
||||
// (the standard SAMPLER macro doesn't declare anything, so the commas will be messed up in the parameter list)
|
||||
sb.Append("UNITY_BARE_SAMPLER(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return "UnityBuildSamplerStateStruct(SamplerState_Linear_Repeat)";
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.SamplerState; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.SamplerState; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
properties.AddShaderProperty(new SamplerStateShaderProperty()
|
||||
{
|
||||
value = new TextureSamplerState()
|
||||
{
|
||||
filter = TextureSamplerState.FilterMode.Linear,
|
||||
wrap = TextureSamplerState.WrapMode.Repeat
|
||||
},
|
||||
overrideReferenceName = "SamplerState_Linear_Repeat",
|
||||
generatePropertyBlock = false,
|
||||
});
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{}
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[BlackboardInputInfo(80)]
|
||||
class SamplerStateShaderProperty : AbstractShaderProperty<TextureSamplerState>
|
||||
{
|
||||
public SamplerStateShaderProperty()
|
||||
{
|
||||
displayName = "SamplerState";
|
||||
value = new TextureSamplerState();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.SamplerState;
|
||||
|
||||
internal override bool isExposable => false;
|
||||
internal override bool isRenamable => false;
|
||||
|
||||
public override TextureSamplerState value
|
||||
{
|
||||
get => base.value;
|
||||
set
|
||||
{
|
||||
overrideReferenceName = $"SamplerState_{value.filter}_{value.wrap}";
|
||||
base.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._SamplerState, referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"UnitySamplerState {referenceName}";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildSamplerStateStruct({referenceName})";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new SamplerStateNode()
|
||||
{
|
||||
filter = value.filter,
|
||||
wrap = value.wrap
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return default(PreviewProperty);
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new SamplerStateShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class ScreenPositionMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition
|
||||
{
|
||||
[SerializeField]
|
||||
ScreenSpaceType m_ScreenSpaceType;
|
||||
|
||||
public ScreenSpaceType screenSpaceType
|
||||
{
|
||||
get { return m_ScreenSpaceType; }
|
||||
set { m_ScreenSpaceType = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => screenSpaceType == ScreenSpaceType.Default;
|
||||
|
||||
public ScreenPositionMaterialSlot()
|
||||
{}
|
||||
|
||||
public ScreenPositionMaterialSlot(int slotId, string displayName, string shaderOutputName, ScreenSpaceType screenSpaceType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, stageCapability, hidden: hidden)
|
||||
{
|
||||
this.screenSpaceType = screenSpaceType;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new ScreenPositionSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return m_ScreenSpaceType.ToValueAsVariable();
|
||||
}
|
||||
|
||||
public bool RequiresScreenPosition(ShaderStageCapability stageCapability)
|
||||
{
|
||||
return !isConnected;
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as ScreenPositionMaterialSlot;
|
||||
if (slot != null)
|
||||
screenSpaceType = slot.screenSpaceType;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SerializableCubemap : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedCubemap;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Cubemap m_Cubemap;
|
||||
|
||||
[Serializable]
|
||||
class CubemapHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Cubemap cubemap;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
// used to get a Cubemap ref guid without loading the cubemap asset itself into memory
|
||||
[Serializable]
|
||||
class MinimalCubemapHelper
|
||||
{
|
||||
// these variables are only ever populated by serialization, disable the C# warning that checks if they are ever assigned
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct MinimalTextureRef
|
||||
{
|
||||
public string guid;
|
||||
}
|
||||
public MinimalTextureRef cubemap;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
internal string guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedCubemap))
|
||||
{
|
||||
var textureHelper = new MinimalCubemapHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, textureHelper);
|
||||
if (!string.IsNullOrEmpty(textureHelper.cubemap.guid))
|
||||
return textureHelper.cubemap.guid;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Guid))
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
if (m_Cubemap != null)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_Cubemap, out string guid, out long localId))
|
||||
return guid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Cubemap cubemap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedCubemap))
|
||||
{
|
||||
var textureHelper = new CubemapHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, textureHelper);
|
||||
m_SerializedCubemap = null;
|
||||
m_Guid = null;
|
||||
m_Cubemap = textureHelper.cubemap;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_Cubemap == null)
|
||||
{
|
||||
m_Cubemap = AssetDatabase.LoadAssetAtPath<Cubemap>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_Cubemap;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Cubemap = value;
|
||||
m_Guid = null;
|
||||
m_SerializedCubemap = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedCubemap = EditorJsonUtility.ToJson(new CubemapHelper { cubemap = cubemap }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class SerializableGuid : ISerializationCallbackReceiver
|
||||
{
|
||||
public SerializableGuid()
|
||||
{
|
||||
m_Guid = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public SerializableGuid(Guid guid)
|
||||
{
|
||||
m_Guid = guid;
|
||||
}
|
||||
|
||||
[NonSerialized]
|
||||
private Guid m_Guid;
|
||||
|
||||
[SerializeField]
|
||||
private string m_GuidSerialized;
|
||||
|
||||
public Guid guid
|
||||
{
|
||||
get { return m_Guid; }
|
||||
internal set { m_Guid = value; } // allow id to be overwritten when necessary
|
||||
}
|
||||
|
||||
public virtual void OnBeforeSerialize()
|
||||
{
|
||||
m_GuidSerialized = m_Guid.ToString();
|
||||
}
|
||||
|
||||
public virtual void OnAfterDeserialize()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_GuidSerialized))
|
||||
m_Guid = new Guid(m_GuidSerialized);
|
||||
else
|
||||
m_Guid = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class SerializableMesh : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedMesh;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Mesh m_Mesh;
|
||||
|
||||
[Serializable]
|
||||
class MeshHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Mesh mesh;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
public Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedMesh))
|
||||
{
|
||||
var textureHelper = new MeshHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedMesh, textureHelper);
|
||||
m_SerializedMesh = null;
|
||||
m_Guid = null;
|
||||
m_Mesh = textureHelper.mesh;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_Mesh == null)
|
||||
{
|
||||
m_Mesh = AssetDatabase.LoadAssetAtPath<Mesh>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_Mesh;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Mesh = value;
|
||||
m_Guid = null;
|
||||
m_SerializedMesh = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedMesh = EditorJsonUtility.ToJson(new MeshHelper { mesh = mesh }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SerializableTexture : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedTexture;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Texture m_Texture;
|
||||
|
||||
[Serializable]
|
||||
class TextureHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Texture texture;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
// used to get a Texture ref guid without loading the texture asset itself into memory
|
||||
[Serializable]
|
||||
class MinimalTextureHelper
|
||||
{
|
||||
// these variables are only ever populated by serialization, disable the C# warning that checks if they are ever assigned
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct MinimalTextureRef
|
||||
{
|
||||
public string guid;
|
||||
}
|
||||
public MinimalTextureRef texture;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
internal string guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new MinimalTextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
if (!string.IsNullOrEmpty(textureHelper.texture.guid))
|
||||
return textureHelper.texture.guid;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Guid))
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
if (m_Texture != null)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_Texture, out string guid, out long localId))
|
||||
return guid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture texture
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new TextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
m_SerializedTexture = null;
|
||||
m_Guid = null;
|
||||
m_Texture = textureHelper.texture;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_Texture == null)
|
||||
{
|
||||
m_Texture = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_Texture;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Texture = value;
|
||||
m_Guid = null;
|
||||
m_SerializedTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedTexture = EditorJsonUtility.ToJson(new TextureHelper { texture = texture }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SerializableTextureArray : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedTexture;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Texture2DArray m_TextureArray;
|
||||
|
||||
[Serializable]
|
||||
class TextureHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Texture2DArray textureArray;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
// used to get a Texture2DArray ref guid without loading the Texture2dArray asset itself into memory
|
||||
[Serializable]
|
||||
class MinimalTextureHelper
|
||||
{
|
||||
// these variables are only ever populated by serialization, disable the C# warning that checks if they are ever assigned
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct MinimalTextureRef
|
||||
{
|
||||
public string guid;
|
||||
}
|
||||
public MinimalTextureRef textureArray;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
internal string guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new MinimalTextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
if (!string.IsNullOrEmpty(textureHelper.textureArray.guid))
|
||||
return textureHelper.textureArray.guid;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Guid))
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
if (m_TextureArray != null)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_TextureArray, out string guid, out long localId))
|
||||
return guid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2DArray textureArray
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new TextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
m_SerializedTexture = null;
|
||||
m_Guid = null;
|
||||
m_TextureArray = textureHelper.textureArray;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_TextureArray == null)
|
||||
{
|
||||
m_TextureArray = AssetDatabase.LoadAssetAtPath<Texture2DArray>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_TextureArray;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_TextureArray = value;
|
||||
m_Guid = null;
|
||||
m_SerializedTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedTexture = EditorJsonUtility.ToJson(new TextureHelper { textureArray = textureArray }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
enum LayerTextureType
|
||||
{
|
||||
Default,
|
||||
NormalTangentSpace,
|
||||
NormalObjectSpace
|
||||
};
|
||||
|
||||
[Serializable]
|
||||
internal class SerializableVirtualTextureLayer
|
||||
{
|
||||
public string layerName;
|
||||
public string layerRefName;
|
||||
public SerializableTexture layerTexture;
|
||||
public LayerTextureType layerTextureType;
|
||||
[SerializeField]
|
||||
private Guid guid;
|
||||
|
||||
public SerializableVirtualTextureLayer(string name, string refName, SerializableTexture texture)
|
||||
{
|
||||
this.layerName = name; this.layerName = name;
|
||||
this.guid = Guid.NewGuid();
|
||||
this.layerRefName = refName; this.layerRefName = refName;
|
||||
this.layerTexture = texture; this.layerTexture = texture;
|
||||
this.layerTextureType = LayerTextureType.Default; this.layerTextureType = LayerTextureType.Default;
|
||||
}
|
||||
|
||||
public SerializableVirtualTextureLayer(string name, SerializableTexture texture)
|
||||
{
|
||||
this.layerName = name;
|
||||
this.guid = Guid.NewGuid();
|
||||
this.layerRefName = $"Layer_{GuidEncoder.Encode(this.guid)}";
|
||||
this.layerTexture = texture;
|
||||
this.layerTextureType = LayerTextureType.Default;
|
||||
}
|
||||
|
||||
public SerializableVirtualTextureLayer(SerializableVirtualTextureLayer other)
|
||||
{
|
||||
this.layerName = other.layerName;
|
||||
this.guid = Guid.NewGuid();
|
||||
this.layerRefName = $"Layer_{GuidEncoder.Encode(this.guid)}";
|
||||
this.layerTexture = other.layerTexture;
|
||||
this.layerTextureType = LayerTextureType.Default;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal sealed class SerializableVirtualTexture
|
||||
{
|
||||
[SerializeField]
|
||||
public List<SerializableVirtualTextureLayer> layers = new List<SerializableVirtualTextureLayer>();
|
||||
|
||||
[SerializeField]
|
||||
public bool procedural;
|
||||
}
|
||||
}
|
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public struct ShaderGraphRequirements
|
||||
{
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresNormal;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresBitangent;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresTangent;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresViewDir;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresPosition;
|
||||
[SerializeField] bool m_RequiresScreenPosition;
|
||||
[SerializeField] bool m_RequiresVertexColor;
|
||||
[SerializeField] bool m_RequiresFaceSign;
|
||||
[SerializeField] List<UVChannel> m_RequiresMeshUVs;
|
||||
[SerializeField] bool m_RequiresDepthTexture;
|
||||
[SerializeField] bool m_RequiresCameraOpaqueTexture;
|
||||
[SerializeField] bool m_RequiresTime;
|
||||
[SerializeField] bool m_RequiresVertexSkinning;
|
||||
[SerializeField] bool m_RequiresVertexID;
|
||||
|
||||
internal static ShaderGraphRequirements none
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ShaderGraphRequirements
|
||||
{
|
||||
m_RequiresMeshUVs = new List<UVChannel>()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresNormal
|
||||
{
|
||||
get { return m_RequiresNormal; }
|
||||
internal set { m_RequiresNormal = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresBitangent
|
||||
{
|
||||
get { return m_RequiresBitangent; }
|
||||
internal set { m_RequiresBitangent = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresTangent
|
||||
{
|
||||
get { return m_RequiresTangent; }
|
||||
internal set { m_RequiresTangent = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresViewDir
|
||||
{
|
||||
get { return m_RequiresViewDir; }
|
||||
internal set { m_RequiresViewDir = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresPosition
|
||||
{
|
||||
get { return m_RequiresPosition; }
|
||||
internal set { m_RequiresPosition = value; }
|
||||
}
|
||||
|
||||
public bool requiresScreenPosition
|
||||
{
|
||||
get { return m_RequiresScreenPosition; }
|
||||
internal set { m_RequiresScreenPosition = value; }
|
||||
}
|
||||
|
||||
public bool requiresVertexColor
|
||||
{
|
||||
get { return m_RequiresVertexColor; }
|
||||
internal set { m_RequiresVertexColor = value; }
|
||||
}
|
||||
|
||||
public bool requiresFaceSign
|
||||
{
|
||||
get { return m_RequiresFaceSign; }
|
||||
internal set { m_RequiresFaceSign = value; }
|
||||
}
|
||||
|
||||
public List<UVChannel> requiresMeshUVs
|
||||
{
|
||||
get { return m_RequiresMeshUVs; }
|
||||
internal set { m_RequiresMeshUVs = value; }
|
||||
}
|
||||
|
||||
public bool requiresDepthTexture
|
||||
{
|
||||
get { return m_RequiresDepthTexture; }
|
||||
internal set { m_RequiresDepthTexture = value; }
|
||||
}
|
||||
|
||||
public bool requiresCameraOpaqueTexture
|
||||
{
|
||||
get { return m_RequiresCameraOpaqueTexture; }
|
||||
internal set { m_RequiresCameraOpaqueTexture = value; }
|
||||
}
|
||||
|
||||
public bool requiresTime
|
||||
{
|
||||
get { return m_RequiresTime; }
|
||||
internal set { m_RequiresTime = value; }
|
||||
}
|
||||
|
||||
public bool requiresVertexSkinning
|
||||
{
|
||||
get { return m_RequiresVertexSkinning; }
|
||||
internal set { m_RequiresVertexSkinning = value; }
|
||||
}
|
||||
|
||||
public bool requiresVertexID
|
||||
{
|
||||
get { return m_RequiresVertexID; }
|
||||
internal set { m_RequiresVertexID = value; }
|
||||
}
|
||||
|
||||
internal bool NeedsTangentSpace()
|
||||
{
|
||||
var compoundSpaces = m_RequiresBitangent | m_RequiresNormal | m_RequiresPosition
|
||||
| m_RequiresTangent | m_RequiresViewDir | m_RequiresPosition
|
||||
| m_RequiresNormal;
|
||||
|
||||
return (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
|
||||
}
|
||||
|
||||
internal ShaderGraphRequirements Union(ShaderGraphRequirements other)
|
||||
{
|
||||
var newReqs = new ShaderGraphRequirements();
|
||||
newReqs.m_RequiresNormal = other.m_RequiresNormal | m_RequiresNormal;
|
||||
newReqs.m_RequiresTangent = other.m_RequiresTangent | m_RequiresTangent;
|
||||
newReqs.m_RequiresBitangent = other.m_RequiresBitangent | m_RequiresBitangent;
|
||||
newReqs.m_RequiresViewDir = other.m_RequiresViewDir | m_RequiresViewDir;
|
||||
newReqs.m_RequiresPosition = other.m_RequiresPosition | m_RequiresPosition;
|
||||
newReqs.m_RequiresScreenPosition = other.m_RequiresScreenPosition | m_RequiresScreenPosition;
|
||||
newReqs.m_RequiresVertexColor = other.m_RequiresVertexColor | m_RequiresVertexColor;
|
||||
newReqs.m_RequiresFaceSign = other.m_RequiresFaceSign | m_RequiresFaceSign;
|
||||
newReqs.m_RequiresDepthTexture = other.m_RequiresDepthTexture | m_RequiresDepthTexture;
|
||||
newReqs.m_RequiresCameraOpaqueTexture = other.m_RequiresCameraOpaqueTexture | m_RequiresCameraOpaqueTexture;
|
||||
newReqs.m_RequiresTime = other.m_RequiresTime | m_RequiresTime;
|
||||
newReqs.m_RequiresVertexSkinning = other.m_RequiresVertexSkinning | m_RequiresVertexSkinning;
|
||||
newReqs.m_RequiresVertexID = other.m_RequiresVertexID | m_RequiresVertexID;
|
||||
|
||||
newReqs.m_RequiresMeshUVs = new List<UVChannel>();
|
||||
if (m_RequiresMeshUVs != null)
|
||||
newReqs.m_RequiresMeshUVs.AddRange(m_RequiresMeshUVs);
|
||||
if (other.m_RequiresMeshUVs != null)
|
||||
newReqs.m_RequiresMeshUVs.AddRange(other.m_RequiresMeshUVs);
|
||||
return newReqs;
|
||||
}
|
||||
|
||||
internal static ShaderGraphRequirements FromNodes<T>(List<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true)
|
||||
where T : AbstractMaterialNode
|
||||
{
|
||||
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal(stageCapability));
|
||||
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent(stageCapability));
|
||||
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent(stageCapability));
|
||||
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection(stageCapability));
|
||||
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition(stageCapability));
|
||||
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition(stageCapability));
|
||||
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
|
||||
bool requiresFaceSign = nodes.OfType<IMayRequireFaceSign>().Any(x => x.RequiresFaceSign());
|
||||
bool requiresDepthTexture = nodes.OfType<IMayRequireDepthTexture>().Any(x => x.RequiresDepthTexture());
|
||||
bool requiresCameraOpaqueTexture = nodes.OfType<IMayRequireCameraOpaqueTexture>().Any(x => x.RequiresCameraOpaqueTexture());
|
||||
bool requiresTime = nodes.Any(x => x.RequiresTime());
|
||||
bool requiresVertexSkinning = nodes.OfType<IMayRequireVertexSkinning>().Any(x => x.RequiresVertexSkinning(stageCapability));
|
||||
bool requiresVertexID = nodes.OfType<IMayRequireVertexID>().Any(x => x.RequiresVertexID(stageCapability));
|
||||
|
||||
var meshUV = new List<UVChannel>();
|
||||
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
|
||||
{
|
||||
var channel = (UVChannel)uvIndex;
|
||||
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
|
||||
meshUV.Add(channel);
|
||||
}
|
||||
|
||||
// if anything needs tangentspace we have make
|
||||
// sure to have our othonormal basis!
|
||||
if (includeIntermediateSpaces)
|
||||
{
|
||||
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
|
||||
| requiresTangent | requiresViewDir | requiresPosition
|
||||
| requiresNormal;
|
||||
|
||||
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
|
||||
if (needsTangentSpace)
|
||||
{
|
||||
requiresBitangent |= NeededCoordinateSpace.World;
|
||||
requiresNormal |= NeededCoordinateSpace.World;
|
||||
requiresTangent |= NeededCoordinateSpace.World;
|
||||
}
|
||||
}
|
||||
|
||||
var reqs = new ShaderGraphRequirements()
|
||||
{
|
||||
m_RequiresNormal = requiresNormal,
|
||||
m_RequiresBitangent = requiresBitangent,
|
||||
m_RequiresTangent = requiresTangent,
|
||||
m_RequiresViewDir = requiresViewDir,
|
||||
m_RequiresPosition = requiresPosition,
|
||||
m_RequiresScreenPosition = requiresScreenPosition,
|
||||
m_RequiresVertexColor = requiresVertexColor,
|
||||
m_RequiresFaceSign = requiresFaceSign,
|
||||
m_RequiresMeshUVs = meshUV,
|
||||
m_RequiresDepthTexture = requiresDepthTexture,
|
||||
m_RequiresCameraOpaqueTexture = requiresCameraOpaqueTexture,
|
||||
m_RequiresTime = requiresTime,
|
||||
m_RequiresVertexSkinning = requiresVertexSkinning,
|
||||
m_RequiresVertexID = requiresVertexID,
|
||||
};
|
||||
|
||||
return reqs;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
public abstract class ShaderInput : JsonObject
|
||||
{
|
||||
[SerializeField]
|
||||
SerializableGuid m_Guid = new SerializableGuid();
|
||||
|
||||
internal Guid guid => m_Guid.guid;
|
||||
|
||||
internal void OverrideGuid(string namespaceId, string name) { m_Guid.guid = GenerateNamespaceUUID(namespaceId, name); }
|
||||
|
||||
[SerializeField]
|
||||
string m_Name;
|
||||
|
||||
public string displayName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_Name))
|
||||
return $"{concreteShaderValueType}_{objectId}";
|
||||
return m_Name;
|
||||
}
|
||||
set
|
||||
{
|
||||
// this is a raw set of the display name
|
||||
// if you want to a fully graph-connected set-and-sanitize-and-update,
|
||||
// call SetDisplayNameAndSanitizeForGraph() instead
|
||||
m_Name = value;
|
||||
}
|
||||
}
|
||||
|
||||
// This delegate and the associated callback can be bound to in order for any one that cares about display name changes to be notified
|
||||
internal delegate void ChangeDisplayNameCallback(string newDisplayName);
|
||||
ChangeDisplayNameCallback m_displayNameUpdateTrigger;
|
||||
internal ChangeDisplayNameCallback displayNameUpdateTrigger
|
||||
{
|
||||
get => m_displayNameUpdateTrigger;
|
||||
set => m_displayNameUpdateTrigger = value;
|
||||
}
|
||||
|
||||
// sanitizes the desired name according to the current graph, and assigns it as the display name
|
||||
// also calls the update trigger to update other bits of the graph UI that use the name
|
||||
internal void SetDisplayNameAndSanitizeForGraph(GraphData graphData, string desiredName = null)
|
||||
{
|
||||
string originalDisplayName = displayName;
|
||||
|
||||
// if no desired name passed in, sanitize the current name
|
||||
if (desiredName == null)
|
||||
desiredName = originalDisplayName;
|
||||
|
||||
var sanitizedName = graphData.SanitizeGraphInputName(this, desiredName);
|
||||
bool changed = (originalDisplayName != sanitizedName);
|
||||
|
||||
// only assign if it was changed
|
||||
if (changed)
|
||||
m_Name = sanitizedName;
|
||||
|
||||
// update the default reference name
|
||||
UpdateDefaultReferenceName(graphData);
|
||||
|
||||
// Updates any views associated with this input so that display names stay up to date
|
||||
// NOTE: we call this even when the name has not changed, because there may be fields
|
||||
// that were user-edited and still have the temporary desired name -- those must update
|
||||
if (m_displayNameUpdateTrigger != null)
|
||||
{
|
||||
m_displayNameUpdateTrigger.Invoke(m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetReferenceNameAndSanitizeForGraph(GraphData graphData, string desiredRefName = null)
|
||||
{
|
||||
string originalRefName = referenceName;
|
||||
|
||||
// if no desired ref name, use the current name
|
||||
if (string.IsNullOrEmpty(desiredRefName))
|
||||
desiredRefName = originalRefName;
|
||||
|
||||
// sanitize and deduplicate the desired name
|
||||
var sanitizedRefName = graphData.SanitizeGraphInputReferenceName(this, desiredRefName);
|
||||
|
||||
// check if the final result is different from the current name
|
||||
bool changed = (originalRefName != sanitizedRefName);
|
||||
|
||||
// if changed, then set the new name up as an override
|
||||
if (changed)
|
||||
overrideReferenceName = sanitizedRefName;
|
||||
}
|
||||
|
||||
// resets the reference name to a "default" value (deduplicated against existing reference names)
|
||||
// returns the new default reference name
|
||||
internal string ResetReferenceName(GraphData graphData)
|
||||
{
|
||||
overrideReferenceName = null;
|
||||
|
||||
// because we are clearing an override, we must force a sanitization pass on the default ref name
|
||||
// as there may now be collisions that didn't previously exist
|
||||
UpdateDefaultReferenceName(graphData, true);
|
||||
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
internal void UpdateDefaultReferenceName(GraphData graphData, bool forceSanitize = false)
|
||||
{
|
||||
if (m_DefaultRefNameVersion <= 0)
|
||||
return; // old version is updated in the getter
|
||||
|
||||
var dispName = displayName;
|
||||
if (forceSanitize ||
|
||||
string.IsNullOrEmpty(m_DefaultReferenceName) ||
|
||||
(m_RefNameGeneratedByDisplayName != dispName))
|
||||
{
|
||||
m_DefaultReferenceName = graphData.SanitizeGraphInputReferenceName(this, dispName);
|
||||
m_RefNameGeneratedByDisplayName = dispName;
|
||||
}
|
||||
}
|
||||
|
||||
const int k_LatestDefaultRefNameVersion = 1;
|
||||
|
||||
// this is used to know whether this shader input is using:
|
||||
// 0) the "old" default reference naming scheme (type + GUID)
|
||||
// 1) the new default reference naming scheme (make it similar to the display name)
|
||||
[SerializeField]
|
||||
int m_DefaultRefNameVersion = k_LatestDefaultRefNameVersion;
|
||||
|
||||
[SerializeField]
|
||||
string m_RefNameGeneratedByDisplayName; // used to tell what was the display name used to generate the default reference name
|
||||
|
||||
[SerializeField]
|
||||
string m_DefaultReferenceName; // NOTE: this can be NULL for old graphs, or newly created properties
|
||||
|
||||
public string referenceName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(overrideReferenceName))
|
||||
{
|
||||
if (m_DefaultRefNameVersion == 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_DefaultReferenceName))
|
||||
m_DefaultReferenceName = GetOldDefaultReferenceName();
|
||||
return m_DefaultReferenceName;
|
||||
}
|
||||
else // version 1
|
||||
{
|
||||
// default reference name is updated elsewhere in the new naming scheme
|
||||
return m_DefaultReferenceName;
|
||||
}
|
||||
}
|
||||
return overrideReferenceName;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnBeforeDeserialize()
|
||||
{
|
||||
// if serialization doesn't write to m_DefaultRefNameVersion, then it is an old shader input, and should use the old default naming scheme
|
||||
m_DefaultRefNameVersion = 0;
|
||||
base.OnBeforeDeserialize();
|
||||
}
|
||||
|
||||
// This is required to handle Material data serialized with "_Color_GUID" reference names
|
||||
// m_DefaultReferenceName expects to match the material data and previously used PropertyType
|
||||
// ColorShaderProperty is the only case where PropertyType doesn't match ConcreteSlotValueType
|
||||
public virtual string GetOldDefaultReferenceName()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToString()}_{objectId}";
|
||||
}
|
||||
|
||||
// returns true if this shader input is CURRENTLY using the old default reference name
|
||||
public bool IsUsingOldDefaultRefName()
|
||||
{
|
||||
return string.IsNullOrEmpty(overrideReferenceName) && (m_DefaultRefNameVersion == 0);
|
||||
}
|
||||
|
||||
// returns true if this shader input is CURRENTLY using the new default reference name
|
||||
public bool IsUsingNewDefaultRefName()
|
||||
{
|
||||
return string.IsNullOrEmpty(overrideReferenceName) && (m_DefaultRefNameVersion >= 1);
|
||||
}
|
||||
|
||||
// upgrades the default reference name to use the new naming scheme
|
||||
internal string UpgradeDefaultReferenceName(GraphData graphData)
|
||||
{
|
||||
m_DefaultRefNameVersion = k_LatestDefaultRefNameVersion;
|
||||
m_DefaultReferenceName = null;
|
||||
m_RefNameGeneratedByDisplayName = null;
|
||||
UpdateDefaultReferenceName(graphData, true); // make sure to sanitize the new default
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
string m_OverrideReferenceName;
|
||||
|
||||
internal string overrideReferenceName
|
||||
{
|
||||
get => m_OverrideReferenceName;
|
||||
set => m_OverrideReferenceName = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_GeneratePropertyBlock = true;
|
||||
|
||||
internal bool generatePropertyBlock // this is basically the "exposed" toggle
|
||||
{
|
||||
get => m_GeneratePropertyBlock;
|
||||
set => m_GeneratePropertyBlock = value;
|
||||
}
|
||||
|
||||
internal bool isExposed => isExposable && generatePropertyBlock;
|
||||
|
||||
internal abstract ConcreteSlotValueType concreteShaderValueType { get; }
|
||||
|
||||
internal abstract bool isExposable { get; }
|
||||
internal virtual bool isAlwaysExposed => false;
|
||||
|
||||
// this controls whether the UI allows the user to rename the display and reference names
|
||||
internal abstract bool isRenamable { get; }
|
||||
|
||||
internal abstract ShaderInput Copy();
|
||||
}
|
||||
}
|
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class ShaderKeyword : ShaderInput
|
||||
{
|
||||
public const string kVariantLimitWarning = "Graph is generating too many variants. Either delete Keywords, reduce Keyword variants or increase the Shader Variant Limit in Preferences > Shader Graph.";
|
||||
|
||||
public ShaderKeyword()
|
||||
{
|
||||
}
|
||||
|
||||
public ShaderKeyword(KeywordType keywordType)
|
||||
{
|
||||
this.displayName = keywordType.ToString();
|
||||
this.keywordType = keywordType;
|
||||
|
||||
// Add sensible default entries for Enum type
|
||||
if (keywordType == KeywordType.Enum)
|
||||
{
|
||||
m_Entries = new List<KeywordEntry>();
|
||||
m_Entries.Add(new KeywordEntry(1, "A", "A"));
|
||||
m_Entries.Add(new KeywordEntry(2, "B", "B"));
|
||||
m_Entries.Add(new KeywordEntry(3, "C", "C"));
|
||||
}
|
||||
}
|
||||
|
||||
public static ShaderKeyword CreateBuiltInKeyword(KeywordDescriptor descriptor)
|
||||
{
|
||||
if (descriptor.entries != null)
|
||||
{
|
||||
for (int i = 0; i < descriptor.entries.Length; i++)
|
||||
{
|
||||
if (descriptor.entries[i].id == -1)
|
||||
descriptor.entries[i].id = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new ShaderKeyword()
|
||||
{
|
||||
isBuiltIn = true,
|
||||
displayName = descriptor.displayName,
|
||||
overrideReferenceName = descriptor.referenceName,
|
||||
keywordType = descriptor.type,
|
||||
keywordDefinition = descriptor.definition,
|
||||
keywordScope = descriptor.scope,
|
||||
value = descriptor.value,
|
||||
entries = descriptor.entries.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private KeywordType m_KeywordType = KeywordType.Boolean;
|
||||
|
||||
public KeywordType keywordType
|
||||
{
|
||||
get => m_KeywordType;
|
||||
set => m_KeywordType = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private KeywordDefinition m_KeywordDefinition = KeywordDefinition.ShaderFeature;
|
||||
|
||||
public KeywordDefinition keywordDefinition
|
||||
{
|
||||
get => m_KeywordDefinition;
|
||||
set => m_KeywordDefinition = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private KeywordScope m_KeywordScope = KeywordScope.Local;
|
||||
|
||||
public KeywordScope keywordScope
|
||||
{
|
||||
get => m_KeywordScope;
|
||||
set => m_KeywordScope = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<KeywordEntry> m_Entries;
|
||||
|
||||
public List<KeywordEntry> entries
|
||||
{
|
||||
get => m_Entries;
|
||||
set => m_Entries = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int m_Value;
|
||||
|
||||
public int value
|
||||
{
|
||||
get => m_Value;
|
||||
set => m_Value = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool m_IsEditable = true; // this serializes !isBuiltIn
|
||||
|
||||
public bool isBuiltIn
|
||||
{
|
||||
get => !m_IsEditable;
|
||||
set => m_IsEditable = !value;
|
||||
}
|
||||
|
||||
internal override bool isExposable => !isBuiltIn && (keywordDefinition != KeywordDefinition.Predefined);
|
||||
|
||||
internal override bool isRenamable => !isBuiltIn;
|
||||
|
||||
internal override ConcreteSlotValueType concreteShaderValueType => keywordType.ToConcreteSlotValueType();
|
||||
|
||||
public override string GetOldDefaultReferenceName()
|
||||
{
|
||||
// _ON suffix is required for exposing Boolean type to Material
|
||||
var suffix = string.Empty;
|
||||
if (keywordType == KeywordType.Boolean)
|
||||
{
|
||||
suffix = "_ON";
|
||||
}
|
||||
|
||||
return $"{keywordType.ToString()}_{objectId}{suffix}".ToUpper();
|
||||
}
|
||||
|
||||
public void AppendPropertyBlockStrings(ShaderStringBuilder builder)
|
||||
{
|
||||
if (isExposed)
|
||||
{
|
||||
switch (keywordType)
|
||||
{
|
||||
case KeywordType.Enum:
|
||||
string enumTagString = $"[KeywordEnum({string.Join(", ", entries.Select(x => x.displayName))})]";
|
||||
builder.AppendLine($"{enumTagString}{referenceName}(\"{displayName}\", Float) = {value}");
|
||||
break;
|
||||
case KeywordType.Boolean:
|
||||
if (referenceName.EndsWith("_ON"))
|
||||
builder.AppendLine($"[Toggle]{referenceName.Remove(referenceName.Length - 3, 3)}(\"{displayName}\", Float) = {value}");
|
||||
else
|
||||
builder.AppendLine($"[Toggle({referenceName})]{referenceName}(\"{displayName}\", Float) = {value}");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetKeywordDeclarationString()
|
||||
{
|
||||
// Predefined keywords do not need to be defined
|
||||
if (keywordDefinition == KeywordDefinition.Predefined)
|
||||
return string.Empty;
|
||||
|
||||
// Get definition type using scope
|
||||
string scopeString = keywordScope == KeywordScope.Local ? "_local" : string.Empty;
|
||||
string definitionString = $"{keywordDefinition.ToDeclarationString()}{scopeString}";
|
||||
|
||||
switch (keywordType)
|
||||
{
|
||||
case KeywordType.Boolean:
|
||||
return $"#pragma {definitionString} _ {referenceName}";
|
||||
case KeywordType.Enum:
|
||||
var enumEntryDefinitions = entries.Select(x => $"{referenceName}_{x.referenceName}");
|
||||
string enumEntriesString = string.Join(" ", enumEntryDefinitions);
|
||||
return $"#pragma {definitionString} {enumEntriesString}";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetKeywordPreviewDeclarationString()
|
||||
{
|
||||
switch (keywordType)
|
||||
{
|
||||
case KeywordType.Boolean:
|
||||
return value == 1 ? $"#define {referenceName}" : string.Empty;
|
||||
case KeywordType.Enum:
|
||||
return $"#define {referenceName}_{entries[value].referenceName}";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
// Keywords copy reference name
|
||||
// This is because keywords are copied between graphs
|
||||
// When copying dependent nodes
|
||||
return new ShaderKeyword()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
isBuiltIn = isBuiltIn,
|
||||
keywordType = keywordType,
|
||||
keywordDefinition = keywordDefinition,
|
||||
keywordScope = keywordScope,
|
||||
entries = entries,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// we now allow keywords to control whether they are exposed (for Material control) or not.
|
||||
// old exposable keywords set their exposed state to maintain previous behavior
|
||||
// (where only keywords ending in "_ON" showed up in the material)
|
||||
if (isExposable)
|
||||
generatePropertyBlock = referenceName.EndsWith("_ON");
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
abstract class SpaceMaterialSlot : Vector3MaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private CoordinateSpace m_Space = CoordinateSpace.World;
|
||||
|
||||
public CoordinateSpace space
|
||||
{
|
||||
get { return m_Space; }
|
||||
set { m_Space = value; }
|
||||
}
|
||||
|
||||
protected SpaceMaterialSlot()
|
||||
{}
|
||||
|
||||
protected SpaceMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, stageCapability, hidden: hidden)
|
||||
{
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as SpaceMaterialSlot;
|
||||
if (slot != null)
|
||||
space = slot.space;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class StickyNoteData : JsonObject, IGroupItem
|
||||
{
|
||||
[SerializeField]
|
||||
string m_Title;
|
||||
|
||||
public string title
|
||||
{
|
||||
get => m_Title;
|
||||
set => m_Title = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
string m_Content;
|
||||
|
||||
public string content
|
||||
{
|
||||
get => m_Content;
|
||||
set => m_Content = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
int m_TextSize;
|
||||
|
||||
public int textSize
|
||||
{
|
||||
get => m_TextSize;
|
||||
set => m_TextSize = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
int m_Theme;
|
||||
|
||||
public int theme
|
||||
{
|
||||
get => m_Theme;
|
||||
set => m_Theme = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Rect m_Position;
|
||||
|
||||
public Rect position
|
||||
{
|
||||
get => m_Position;
|
||||
set => m_Position = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
JsonRef<GroupData> m_Group = null;
|
||||
|
||||
public GroupData group
|
||||
{
|
||||
get => m_Group;
|
||||
set
|
||||
{
|
||||
if (m_Group == value)
|
||||
return;
|
||||
|
||||
m_Group = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public StickyNoteData() : base() {}
|
||||
public StickyNoteData(string title, string content, Rect position)
|
||||
{
|
||||
m_Title = title;
|
||||
m_Position = position;
|
||||
m_Content = content;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class TangentMaterialSlot : SpaceMaterialSlot, IMayRequireTangent
|
||||
{
|
||||
public TangentMaterialSlot()
|
||||
{}
|
||||
|
||||
public TangentMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Tangent));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresTangent(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalTexture2DArrayInputMaterialSlot))]
|
||||
class Texture2DArrayInputMaterialSlot : Texture2DArrayMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTextureArray m_TextureArray = new SerializableTextureArray();
|
||||
|
||||
public Texture2DArray textureArray
|
||||
{
|
||||
get { return m_TextureArray.textureArray; }
|
||||
set { m_TextureArray.textureArray = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => textureArray == null;
|
||||
|
||||
public Texture2DArrayInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DArrayInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new TextureArraySlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTexture2DArrayStruct({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new Texture2DArrayShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.textureArray = textureArray;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Texture2DArray)
|
||||
{
|
||||
name = name,
|
||||
textureValue = textureArray,
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DArrayInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_TextureArray = slot.m_TextureArray;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalTexture2DArrayInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTextureArray m_TextureArray = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_TextureArray.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Texture2DArrayMaterialSlot : MaterialSlot
|
||||
{
|
||||
public Texture2DArrayMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DArrayMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURE2D_ARRAY(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Texture2DArray; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Texture2DArray; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DArrayMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_BareResource = slot.m_BareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Texture2DArrayShaderProperty")]
|
||||
[BlackboardInputInfo(51)]
|
||||
public class Texture2DArrayShaderProperty : AbstractShaderProperty<SerializableTextureArray>
|
||||
{
|
||||
internal Texture2DArrayShaderProperty()
|
||||
{
|
||||
displayName = "Texture2D Array";
|
||||
value = new SerializableTextureArray();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Texture2DArray;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", 2DArray) = \"\" {{}}";
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._Texture2DArray, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTexture2DArray " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURE2D_ARRAY(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTexture2DArrayStruct({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
internal bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Texture2DArrayAssetNode { texture = value.textureArray };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
textureValue = value.textureArray
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Texture2DArrayShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalTexture2DInputMaterialSlot))]
|
||||
class Texture2DInputMaterialSlot : Texture2DMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = new SerializableTexture();
|
||||
|
||||
[SerializeField]
|
||||
private Texture2DShaderProperty.DefaultType m_DefaultType = Texture2DShaderProperty.DefaultType.White;
|
||||
|
||||
public Texture texture
|
||||
{
|
||||
get { return m_Texture.texture; }
|
||||
set { m_Texture.texture = value; }
|
||||
}
|
||||
|
||||
public Texture2DShaderProperty.DefaultType defaultType
|
||||
{
|
||||
get { return m_DefaultType; }
|
||||
set { m_DefaultType = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => texture == null;
|
||||
|
||||
public Texture2DInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new TextureSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTexture2DStructNoScale({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new Texture2DShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.texture = texture;
|
||||
prop.defaultType = defaultType;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Texture2D)
|
||||
{
|
||||
name = name,
|
||||
textureValue = texture,
|
||||
texture2DDefaultType = defaultType
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_Texture = slot.m_Texture;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalTexture2DInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_Texture.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Texture2DMaterialSlot : MaterialSlot
|
||||
{
|
||||
public Texture2DMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURE2D(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Texture2D; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Texture2D; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_BareResource = slot.m_BareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.TextureShaderProperty")]
|
||||
[BlackboardInputInfo(50)]
|
||||
public sealed class Texture2DShaderProperty : AbstractShaderProperty<SerializableTexture>
|
||||
{
|
||||
public enum DefaultType { White, Black, Grey, Bump }
|
||||
|
||||
internal Texture2DShaderProperty()
|
||||
{
|
||||
displayName = "Texture2D";
|
||||
value = new SerializableTexture();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Texture2D;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", 2D) = \"{defaultType.ToString().ToLower()}\" {{}}";
|
||||
}
|
||||
|
||||
// Texture2D properties cannot be set via Hybrid path at the moment; disallow that choice
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => (decl != HLSLDeclaration.HybridPerInstance) && (decl != HLSLDeclaration.DoNotDeclare);
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = (generatePropertyBlock ? HLSLDeclaration.UnityPerMaterial : HLSLDeclaration.Global);
|
||||
|
||||
action(new HLSLProperty(HLSLType._Texture2D, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._float4, referenceName + "_TexelSize", decl));
|
||||
// action(new HLSLProperty(HLSLType._float4, referenceName + "_ST", decl)); // TODO: allow users to make use of the ST values
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTexture2D " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURE2D(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTexture2DStructNoScale({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
internal bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
DefaultType m_DefaultType = DefaultType.White;
|
||||
|
||||
public DefaultType defaultType
|
||||
{
|
||||
get { return m_DefaultType; }
|
||||
set { m_DefaultType = value; }
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Texture2DAssetNode { texture = value.texture };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
textureValue = value.texture,
|
||||
texture2DDefaultType = defaultType
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Texture2DShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
defaultType = defaultType,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalTexture3DInputMaterialSlot))]
|
||||
class Texture3DInputMaterialSlot : Texture3DMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = new SerializableTexture();
|
||||
|
||||
public Texture texture
|
||||
{
|
||||
get { return m_Texture.texture; }
|
||||
set { m_Texture.texture = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => texture == null;
|
||||
|
||||
public Texture3DInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture3DInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new Texture3DSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTexture3DStruct({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new Texture3DShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.texture = texture;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Texture3D)
|
||||
{
|
||||
name = name,
|
||||
textureValue = texture,
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture3DInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_Texture = slot.m_Texture;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalTexture3DInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_Texture.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Texture3DMaterialSlot : MaterialSlot
|
||||
{
|
||||
public Texture3DMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture3DMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURE3D(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Texture3D; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Texture3D; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture3DMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_BareResource = slot.m_BareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Texture3DShaderProperty")]
|
||||
[BlackboardInputInfo(52)]
|
||||
public sealed class Texture3DShaderProperty : AbstractShaderProperty<SerializableTexture>
|
||||
{
|
||||
internal Texture3DShaderProperty()
|
||||
{
|
||||
displayName = "Texture3D";
|
||||
value = new SerializableTexture();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Texture3D;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", 3D) = \"white\" {{}}";
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._Texture3D, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTexture3D " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURE3D(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTexture3DStruct({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
public bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Texture3DAssetNode { texture = value.texture as Texture3D };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
textureValue = value.texture
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Texture3DShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class TextureSamplerState
|
||||
{
|
||||
public enum FilterMode
|
||||
{
|
||||
Linear,
|
||||
Point,
|
||||
Trilinear
|
||||
}
|
||||
|
||||
public enum WrapMode
|
||||
{
|
||||
Repeat,
|
||||
Clamp,
|
||||
Mirror,
|
||||
MirrorOnce
|
||||
}
|
||||
|
||||
[SerializeField] private FilterMode m_filter = FilterMode.Linear;
|
||||
|
||||
public FilterMode filter
|
||||
{
|
||||
get { return m_filter; }
|
||||
set
|
||||
{
|
||||
if (m_filter == value)
|
||||
return;
|
||||
|
||||
m_filter = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private WrapMode m_wrap = WrapMode.Repeat;
|
||||
|
||||
public WrapMode wrap
|
||||
{
|
||||
get { return m_wrap; }
|
||||
set
|
||||
{
|
||||
if (m_wrap == value)
|
||||
return;
|
||||
|
||||
m_wrap = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class UVMaterialSlot : Vector2MaterialSlot, IMayRequireMeshUV
|
||||
{
|
||||
[SerializeField]
|
||||
UVChannel m_Channel = UVChannel.UV0;
|
||||
|
||||
public UVChannel channel
|
||||
{
|
||||
get { return m_Channel; }
|
||||
set { m_Channel = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => channel == UVChannel.UV0;
|
||||
|
||||
public UVMaterialSlot()
|
||||
{}
|
||||
|
||||
public UVMaterialSlot(int slotId, string displayName, string shaderOutputName, UVChannel channel,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector2.zero, stageCapability, hidden: hidden)
|
||||
{
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new UVSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}.xy", channel.GetUVName());
|
||||
}
|
||||
|
||||
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return false;
|
||||
|
||||
return m_Channel == channel;
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as UVMaterialSlot;
|
||||
if (slot != null)
|
||||
channel = slot.channel;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector1MaterialSlot : MaterialSlot, IMaterialSlotHasValue<float>
|
||||
{
|
||||
[SerializeField]
|
||||
float m_Value;
|
||||
|
||||
[SerializeField]
|
||||
float m_DefaultValue;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector1MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector1MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
float value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_DefaultValue = value;
|
||||
m_Value = value;
|
||||
if (label1 != null)
|
||||
m_Labels = new[] { label1 };
|
||||
}
|
||||
|
||||
public float defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public float value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => new Vector4(value, 0f, 0f, 0f), (newValue) => value = newValue.x);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return NodeUtils.FloatToShaderValue(value);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector1ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector1; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector1; } }
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Float)
|
||||
{
|
||||
name = name,
|
||||
floatValue = value,
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector1MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<float> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.FloatShaderProperty")]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector1ShaderProperty")]
|
||||
[BlackboardInputInfo(0, "Float")]
|
||||
public sealed class Vector1ShaderProperty : AbstractShaderProperty<float>
|
||||
{
|
||||
internal Vector1ShaderProperty()
|
||||
{
|
||||
displayName = "Float";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Float;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
string enumTagString
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (enumType)
|
||||
{
|
||||
case EnumType.CSharpEnum:
|
||||
return $"[Enum({m_CSharpEnumType.ToString()})]";
|
||||
case EnumType.KeywordEnum:
|
||||
return $"[KeywordEnum({string.Join(", ", enumNames)})]";
|
||||
default:
|
||||
string enumValuesString = "";
|
||||
for (int i = 0; i < enumNames.Count; i++)
|
||||
{
|
||||
int value = (i < enumValues.Count) ? enumValues[i] : i;
|
||||
enumValuesString += (enumNames[i] + ", " + value + ((i != enumNames.Count - 1) ? ", " : ""));
|
||||
}
|
||||
return $"[Enum({enumValuesString})]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
string valueString = NodeUtils.FloatToShaderValueShaderLabSafe(value);
|
||||
|
||||
switch (floatType)
|
||||
{
|
||||
case FloatType.Slider:
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Range({NodeUtils.FloatToShaderValue(m_RangeValues.x)}, {NodeUtils.FloatToShaderValue(m_RangeValues.y)})) = {valueString}";
|
||||
case FloatType.Integer:
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Int) = {((int)value).ToString(CultureInfo.InvariantCulture)}";
|
||||
case FloatType.Enum:
|
||||
return $"{hideTagString}{enumTagString}{referenceName}(\"{displayName}\", Float) = {valueString}";
|
||||
default:
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Float) = {valueString}";
|
||||
}
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
FloatType m_FloatType = FloatType.Default;
|
||||
|
||||
public FloatType floatType
|
||||
{
|
||||
get => m_FloatType;
|
||||
set => m_FloatType = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_RangeValues = new Vector2(0, 1);
|
||||
|
||||
public Vector2 rangeValues
|
||||
{
|
||||
get => m_RangeValues;
|
||||
set => m_RangeValues = value;
|
||||
}
|
||||
|
||||
EnumType m_EnumType = EnumType.Enum;
|
||||
|
||||
public EnumType enumType
|
||||
{
|
||||
get => m_EnumType;
|
||||
set => m_EnumType = value;
|
||||
}
|
||||
|
||||
Type m_CSharpEnumType;
|
||||
|
||||
public Type cSharpEnumType
|
||||
{
|
||||
get => m_CSharpEnumType;
|
||||
set => m_CSharpEnumType = value;
|
||||
}
|
||||
|
||||
List<string> m_EnumNames = new List<string>();
|
||||
|
||||
public List<string> enumNames
|
||||
{
|
||||
get => m_EnumNames;
|
||||
set => m_EnumNames = value;
|
||||
}
|
||||
|
||||
List<int> m_EnumValues = new List<int>();
|
||||
|
||||
public List<int> enumValues
|
||||
{
|
||||
get => m_EnumValues;
|
||||
set => m_EnumValues = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
switch (m_FloatType)
|
||||
{
|
||||
case FloatType.Slider:
|
||||
return new SliderNode { value = new Vector3(value, m_RangeValues.x, m_RangeValues.y) };
|
||||
case FloatType.Integer:
|
||||
return new IntegerNode { value = (int)value };
|
||||
default:
|
||||
var node = new Vector1Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector1Node.InputSlotXId).value = value;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
floatValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector1ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
floatType = floatType,
|
||||
rangeValues = rangeValues,
|
||||
enumType = enumType,
|
||||
enumNames = enumNames,
|
||||
enumValues = enumValues,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum FloatType { Default, Slider, Integer, Enum }
|
||||
|
||||
public enum EnumType { Enum, CSharpEnum, KeywordEnum, }
|
||||
}
|
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector2MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector2>
|
||||
{
|
||||
[SerializeField]
|
||||
Vector2 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_DefaultValue = Vector2.zero;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X", "Y" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector2MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector2 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
string label2 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
if ((label1 != null) || (label2 != null))
|
||||
{
|
||||
m_Labels = new[]
|
||||
{
|
||||
label1 ?? k_LabelDefaults[0],
|
||||
label2 ?? k_LabelDefaults[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector2 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("$precision2 ({0}, {1})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector2ShaderProperty
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Vector2)
|
||||
{
|
||||
name = name,
|
||||
vector4Value = new Vector4(value.x, value.y, 0, 0),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector2; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector2; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector2MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector2> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector2ShaderProperty")]
|
||||
[BlackboardInputInfo(1)]
|
||||
public sealed class Vector2ShaderProperty : VectorShaderProperty
|
||||
{
|
||||
internal Vector2ShaderProperty()
|
||||
{
|
||||
displayName = "Vector2";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Vector2;
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
var node = new Vector2Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector2Node.InputSlotXId).value = value.x;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector2Node.InputSlotYId).value = value.y;
|
||||
return node;
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector2ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float2, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector3MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector3>
|
||||
{
|
||||
[SerializeField]
|
||||
private Vector3 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Vector3 m_DefaultValue = Vector3.zero;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X", "Y", "Z" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector3MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector3 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
string label2 = null,
|
||||
string label3 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
if ((label1 != null) || (label2 != null) || (label3 != null))
|
||||
{
|
||||
m_Labels = new[]
|
||||
{
|
||||
label1 ?? k_LabelDefaults[0],
|
||||
label2 ?? k_LabelDefaults[1],
|
||||
label3 ?? k_LabelDefaults[2]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector3 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("$precision3 ({0}, {1}, {2})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector3ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Vector3)
|
||||
{
|
||||
name = name,
|
||||
vector4Value = new Vector4(value.x, value.y, value.z, 0)
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector3; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector3; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector3MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector3> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector3ShaderProperty")]
|
||||
[BlackboardInputInfo(3)]
|
||||
public sealed class Vector3ShaderProperty : VectorShaderProperty
|
||||
{
|
||||
internal Vector3ShaderProperty()
|
||||
{
|
||||
displayName = "Vector3";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Vector3;
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
var node = new Vector3Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector3Node.InputSlotXId).value = value.x;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector3Node.InputSlotYId).value = value.y;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector3Node.InputSlotZId).value = value.z;
|
||||
return node;
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector3ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float3, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector4MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Vector4 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Vector4 m_DefaultValue = Vector4.zero;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X", "Y", "Z", "W" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector4MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
string label2 = null,
|
||||
string label3 = null,
|
||||
string label4 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
if ((label1 != null) || (label2 != null) || (label3 != null) || (label4 != null))
|
||||
{
|
||||
m_Labels = new[]
|
||||
{
|
||||
label1 ?? k_LabelDefaults[0],
|
||||
label2 ?? k_LabelDefaults[1],
|
||||
label3 ?? k_LabelDefaults[2],
|
||||
label4 ?? k_LabelDefaults[3]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("$precision4 ({0}, {1}, {2}, {3})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z)
|
||||
, NodeUtils.FloatToShaderValue(value.w));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector4ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Vector4)
|
||||
{
|
||||
name = name,
|
||||
vector4Value = new Vector4(value.x, value.y, value.z, value.w),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector4; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector4; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector4MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector4ShaderProperty")]
|
||||
[BlackboardInputInfo(4)]
|
||||
public sealed class Vector4ShaderProperty : VectorShaderProperty
|
||||
{
|
||||
internal Vector4ShaderProperty()
|
||||
{
|
||||
displayName = "Vector4";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Vector4;
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
var node = new Vector4Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotXId).value = value.x;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotYId).value = value.y;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotZId).value = value.z;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotWId).value = value.w;
|
||||
return node;
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector4ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float4, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class VectorShaderProperty : AbstractShaderProperty<Vector4>
|
||||
{
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Vector) = ({NodeUtils.FloatToShaderValueShaderLabSafe(value.x)}, {NodeUtils.FloatToShaderValueShaderLabSafe(value.y)}, {NodeUtils.FloatToShaderValueShaderLabSafe(value.z)}, {NodeUtils.FloatToShaderValueShaderLabSafe(value.w)})";
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class VertexColorMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition
|
||||
{
|
||||
public VertexColorMaterialSlot(int slotId, string displayName, string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, stageCapability, hidden: hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Vertex Color");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", ShaderGeneratorNames.VertexColor);
|
||||
}
|
||||
|
||||
public bool RequiresScreenPosition(ShaderStageCapability stageCapability)
|
||||
{
|
||||
return !isConnected;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class ViewDirectionMaterialSlot : SpaceMaterialSlot, IMayRequireViewDirection
|
||||
{
|
||||
public ViewDirectionMaterialSlot()
|
||||
{}
|
||||
|
||||
public ViewDirectionMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.ViewDirection));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class VirtualTextureInputMaterialSlot : VirtualTextureMaterialSlot
|
||||
{
|
||||
public VirtualTextureInputMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public VirtualTextureInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return matOwner.GetVariableNameForSlot(id);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class VirtualTextureMaterialSlot : MaterialSlot
|
||||
{
|
||||
public VirtualTextureMaterialSlot()
|
||||
{}
|
||||
|
||||
public VirtualTextureMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.VirtualTexture; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.VirtualTexture; } }
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => throw new Exception();
|
||||
}
|
||||
}
|
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.ShaderGraph.Drawing.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(60)]
|
||||
class VirtualTextureShaderProperty : AbstractShaderProperty<SerializableVirtualTexture>
|
||||
{
|
||||
public VirtualTextureShaderProperty()
|
||||
{
|
||||
displayName = "VirtualTexture";
|
||||
value = new SerializableVirtualTexture();
|
||||
|
||||
// add at least one layer
|
||||
value.layers = new List<SerializableVirtualTextureLayer>();
|
||||
value.layers.Add(new SerializableVirtualTextureLayer("Layer0", new SerializableTexture()));
|
||||
value.layers.Add(new SerializableVirtualTextureLayer("Layer1", new SerializableTexture()));
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.VirtualTexture;
|
||||
|
||||
internal override bool isExposable => true; // the textures are exposable at least..
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override void GetPropertyReferenceNames(List<string> result)
|
||||
{
|
||||
result.Add(referenceName);
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
result.Add(value.layers[layer].layerRefName);
|
||||
}
|
||||
}
|
||||
|
||||
internal override void GetPropertyDisplayNames(List<string> result)
|
||||
{
|
||||
result.Add(displayName);
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
result.Add(value.layers[layer].layerName);
|
||||
}
|
||||
}
|
||||
|
||||
// this is used for properties exposed to the Material in the shaderlab Properties{} block
|
||||
internal override void AppendPropertyBlockStrings(ShaderStringBuilder builder)
|
||||
{
|
||||
if (!value.procedural)
|
||||
{
|
||||
// adds properties in this format so: [TextureStack.MyStack(0)] [NoScaleOffset] Layer0("Layer0", 2D) = "white" {}
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
string layerName = value.layers[layer].layerName;
|
||||
string layerRefName = value.layers[layer].layerRefName;
|
||||
builder.AppendLine($"{hideTagString}[TextureStack.{referenceName}({layer})][NoScaleOffset]{layerRefName}(\"{layerName}\", 2D) = \"white\" {{}}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
// this should not be called, as it is replaced by the Append*PropertyBlockStrings function above
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
int numLayers = value.layers.Count;
|
||||
if (numLayers > 0)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._CUSTOM, referenceName, HLSLDeclaration.UnityPerMaterial, concretePrecision)
|
||||
{
|
||||
customDeclaration = (ssb) =>
|
||||
{
|
||||
ssb.AppendIndentation();
|
||||
ssb.Append("DECLARE_STACK_CB(");
|
||||
ssb.Append(referenceName);
|
||||
ssb.Append(");");
|
||||
ssb.AppendNewLine();
|
||||
}
|
||||
});
|
||||
|
||||
if (!value.procedural)
|
||||
{
|
||||
// declare regular texture properties (for fallback case)
|
||||
for (int i = 0; i < numLayers; i++)
|
||||
{
|
||||
string layerRefName = value.layers[i].layerRefName;
|
||||
action(new HLSLProperty(HLSLType._Texture2D, layerRefName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + layerRefName, HLSLDeclaration.Global));
|
||||
}
|
||||
}
|
||||
|
||||
Action<ShaderStringBuilder> customDecl = (builder) =>
|
||||
{
|
||||
// declare texture stack
|
||||
builder.AppendIndentation();
|
||||
builder.Append("DECLARE_STACK");
|
||||
builder.Append((numLayers <= 1) ? "" : numLayers.ToString());
|
||||
builder.Append("(");
|
||||
builder.Append(referenceName);
|
||||
builder.Append(",");
|
||||
for (int i = 0; i < value.layers.Count; i++)
|
||||
{
|
||||
if (i != 0) builder.Append(",");
|
||||
builder.Append(value.layers[i].layerRefName);
|
||||
}
|
||||
builder.Append(");");
|
||||
builder.AppendNewLine();
|
||||
|
||||
// declare the actual virtual texture property "variable" as a macro define to the BuildVTProperties function
|
||||
builder.AppendIndentation();
|
||||
builder.Append("#define ");
|
||||
builder.Append(referenceName);
|
||||
builder.Append(" AddTextureType(BuildVTProperties_");
|
||||
builder.Append(referenceName);
|
||||
builder.Append("()");
|
||||
for (int i = 0; i < value.layers.Count; i++)
|
||||
{
|
||||
builder.Append(",");
|
||||
builder.Append("TEXTURETYPE_");
|
||||
builder.Append(value.layers[i].layerTextureType.ToString().ToUpper());
|
||||
}
|
||||
builder.Append(")");
|
||||
builder.AppendNewLine();
|
||||
};
|
||||
|
||||
action(new HLSLProperty(HLSLType._CUSTOM, referenceName, HLSLDeclaration.Global, concretePrecision)
|
||||
{
|
||||
customDeclaration = customDecl
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// argument string used to pass this property to a subgraph
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "VTPropertyWithTextureType " + referenceName;
|
||||
}
|
||||
|
||||
// if a blackboard property is deleted, or copy/pasted, all node instances of it are replaced with this:
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return null; // return null to indicate there is NO concrete form of a VT property
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vtProperty = this
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
var vt = new VirtualTextureShaderProperty
|
||||
{
|
||||
displayName = displayName,
|
||||
value = new SerializableVirtualTexture(),
|
||||
};
|
||||
|
||||
// duplicate layer data, but reset reference names (they should be unique)
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
var guid = Guid.NewGuid();
|
||||
vt.value.layers.Add(new SerializableVirtualTextureLayer(value.layers[layer]));
|
||||
}
|
||||
|
||||
return vt;
|
||||
}
|
||||
|
||||
internal void AddTextureInfo(List<PropertyCollector.TextureInfo> infos)
|
||||
{
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
string layerRefName = value.layers[layer].layerRefName;
|
||||
var layerTexture = value.layers[layer].layerTexture;
|
||||
var texture = layerTexture != null ? layerTexture.texture : null;
|
||||
|
||||
var textureInfo = new PropertyCollector.TextureInfo
|
||||
{
|
||||
name = layerRefName,
|
||||
textureId = texture != null ? texture.GetInstanceID() : 0,
|
||||
dimension = texture != null ? texture.dimension : UnityEngine.Rendering.TextureDimension.Any,
|
||||
modifiable = true
|
||||
};
|
||||
infos.Add(textureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool isAlwaysExposed => true;
|
||||
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
// VT shader properties must always be exposed
|
||||
generatePropertyBlock = true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
[Serializable]
|
||||
class Edge : IEdge, IComparable<Edge>
|
||||
{
|
||||
[SerializeField]
|
||||
private SlotReference m_OutputSlot;
|
||||
[SerializeField]
|
||||
private SlotReference m_InputSlot;
|
||||
|
||||
public Edge()
|
||||
{}
|
||||
|
||||
public Edge(SlotReference outputSlot, SlotReference inputSlot)
|
||||
{
|
||||
m_OutputSlot = outputSlot;
|
||||
m_InputSlot = inputSlot;
|
||||
}
|
||||
|
||||
public SlotReference outputSlot
|
||||
{
|
||||
get { return m_OutputSlot; }
|
||||
}
|
||||
|
||||
public SlotReference inputSlot
|
||||
{
|
||||
get { return m_InputSlot; }
|
||||
}
|
||||
|
||||
protected bool Equals(Edge other)
|
||||
{
|
||||
return Equals(m_OutputSlot, other.m_OutputSlot) && Equals(m_InputSlot, other.m_InputSlot);
|
||||
}
|
||||
|
||||
public bool Equals(IEdge other)
|
||||
{
|
||||
return Equals(other as object);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((Edge)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
// Can't make fields readonly due to Unity serialization
|
||||
return (m_OutputSlot.GetHashCode() * 397) ^ m_InputSlot.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(Edge other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
if (ReferenceEquals(null, other)) return 1;
|
||||
var outputSlotComparison = m_OutputSlot.CompareTo(other.m_OutputSlot);
|
||||
if (outputSlotComparison != 0) return outputSlotComparison;
|
||||
return m_InputSlot.CompareTo(other.m_InputSlot);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
class GraphObject : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
SerializationHelper.JSONSerializedElement m_SerializedGraph;
|
||||
|
||||
[SerializeField]
|
||||
int m_SerializedVersion;
|
||||
|
||||
[SerializeField]
|
||||
bool m_IsDirty;
|
||||
|
||||
[SerializeField]
|
||||
bool m_IsSubGraph;
|
||||
|
||||
[SerializeField]
|
||||
string m_AssetGuid;
|
||||
|
||||
[NonSerialized]
|
||||
GraphData m_Graph;
|
||||
|
||||
[NonSerialized]
|
||||
int m_DeserializedVersion;
|
||||
|
||||
public GraphData graph
|
||||
{
|
||||
get { return m_Graph; }
|
||||
set
|
||||
{
|
||||
if (m_Graph != null)
|
||||
m_Graph.owner = null;
|
||||
m_Graph = value;
|
||||
if (m_Graph != null)
|
||||
m_Graph.owner = this;
|
||||
}
|
||||
}
|
||||
|
||||
// this value stores whether an undo operation has been registered (which indicates a change has been made to the graph)
|
||||
// and is used to trigger the MaterialGraphEditWindow to update it's title
|
||||
public bool isDirty
|
||||
{
|
||||
get { return m_IsDirty; }
|
||||
set { m_IsDirty = value; }
|
||||
}
|
||||
|
||||
public virtual void RegisterCompleteObjectUndo(string actionName)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(this, actionName);
|
||||
m_SerializedVersion++;
|
||||
m_DeserializedVersion++;
|
||||
m_IsDirty = true;
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
if (graph != null)
|
||||
{
|
||||
var json = MultiJson.Serialize(graph);
|
||||
m_SerializedGraph = new SerializationHelper.JSONSerializedElement { JSONnodeData = json };
|
||||
m_IsSubGraph = graph.isSubGraph;
|
||||
m_AssetGuid = graph.assetGuid;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
public bool wasUndoRedoPerformed => m_DeserializedVersion != m_SerializedVersion;
|
||||
|
||||
public void HandleUndoRedo()
|
||||
{
|
||||
Debug.Assert(wasUndoRedoPerformed);
|
||||
var deserializedGraph = DeserializeGraph();
|
||||
m_Graph.ReplaceWith(deserializedGraph);
|
||||
}
|
||||
|
||||
GraphData DeserializeGraph()
|
||||
{
|
||||
var json = m_SerializedGraph.JSONnodeData;
|
||||
var deserializedGraph = new GraphData {isSubGraph = m_IsSubGraph, assetGuid = m_AssetGuid};
|
||||
MultiJson.Deserialize(deserializedGraph, json);
|
||||
m_DeserializedVersion = m_SerializedVersion;
|
||||
m_SerializedGraph = default;
|
||||
return deserializedGraph;
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (graph != null)
|
||||
{
|
||||
graph.OnEnable();
|
||||
graph.ValidateGraph();
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (graph == null && m_SerializedGraph.JSONnodeData != null)
|
||||
{
|
||||
graph = DeserializeGraph();
|
||||
}
|
||||
Validate();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
graph?.OnDisable();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
class HasDependenciesAttribute : Attribute
|
||||
{
|
||||
public HasDependenciesAttribute(Type minimalType)
|
||||
{
|
||||
this.minimalType = minimalType;
|
||||
}
|
||||
|
||||
public Type minimalType { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
interface IHasDependencies
|
||||
{
|
||||
void GetSourceAssetDependencies(AssetCollection assetCollection);
|
||||
}
|
||||
}
|
@@ -0,0 +1,998 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
using UnityEngine.Rendering.ShaderGraph;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
class SlotConfigurationException : Exception
|
||||
{
|
||||
public SlotConfigurationException(string message)
|
||||
: base(message)
|
||||
{}
|
||||
}
|
||||
|
||||
static class NodeUtils
|
||||
{
|
||||
static string NodeDocSuffix = "-Node";
|
||||
|
||||
public static void SlotConfigurationExceptionIfBadConfiguration(AbstractMaterialNode node, IEnumerable<int> expectedInputSlots, IEnumerable<int> expectedOutputSlots)
|
||||
{
|
||||
var missingSlots = new List<int>();
|
||||
|
||||
var inputSlots = expectedInputSlots as IList<int> ?? expectedInputSlots.ToList();
|
||||
missingSlots.AddRange(inputSlots.Except(node.GetInputSlots<MaterialSlot>().Select(x => x.id)));
|
||||
|
||||
var outputSlots = expectedOutputSlots as IList<int> ?? expectedOutputSlots.ToList();
|
||||
missingSlots.AddRange(outputSlots.Except(node.GetOutputSlots<MaterialSlot>().Select(x => x.id)));
|
||||
|
||||
if (missingSlots.Count == 0)
|
||||
return;
|
||||
|
||||
var toPrint = missingSlots.Select(x => x.ToString());
|
||||
|
||||
throw new SlotConfigurationException(string.Format("Missing slots {0} on node {1}", string.Join(", ", toPrint.ToArray()), node));
|
||||
}
|
||||
|
||||
public static IEnumerable<IEdge> GetAllEdges(AbstractMaterialNode node)
|
||||
{
|
||||
var result = new List<IEdge>();
|
||||
var validSlots = ListPool<MaterialSlot>.Get();
|
||||
|
||||
validSlots.AddRange(node.GetInputSlots<MaterialSlot>());
|
||||
for (int index = 0; index < validSlots.Count; index++)
|
||||
{
|
||||
var inputSlot = validSlots[index];
|
||||
result.AddRange(node.owner.GetEdges(inputSlot.slotReference));
|
||||
}
|
||||
|
||||
validSlots.Clear();
|
||||
validSlots.AddRange(node.GetOutputSlots<MaterialSlot>());
|
||||
for (int index = 0; index < validSlots.Count; index++)
|
||||
{
|
||||
var outputSlot = validSlots[index];
|
||||
result.AddRange(node.owner.GetEdges(outputSlot.slotReference));
|
||||
}
|
||||
|
||||
ListPool<MaterialSlot>.Release(validSlots);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string GetDuplicateSafeNameForSlot(AbstractMaterialNode node, int slotId, string name)
|
||||
{
|
||||
List<MaterialSlot> slots = new List<MaterialSlot>();
|
||||
node.GetSlots(slots);
|
||||
|
||||
name = name.Trim();
|
||||
return GraphUtil.SanitizeName(slots.Where(p => p.id != slotId).Select(p => p.RawDisplayName()), "{0} ({1})", name);
|
||||
}
|
||||
|
||||
// CollectNodesNodeFeedsInto looks at the current node and calculates
|
||||
// which child nodes it depends on for it's calculation.
|
||||
// Results are returned depth first so by processing each node in
|
||||
// order you can generate a valid code block.
|
||||
public enum IncludeSelf
|
||||
{
|
||||
Include,
|
||||
Exclude
|
||||
}
|
||||
|
||||
public static SlotReference DepthFirstCollectRedirectNodeFromNode(RedirectNodeData node)
|
||||
{
|
||||
var inputSlot = node.FindSlot<MaterialSlot>(RedirectNodeData.kInputSlotID);
|
||||
foreach (var edge in node.owner.GetEdges(inputSlot.slotReference))
|
||||
{
|
||||
// get the input details
|
||||
var outputSlotRef = edge.outputSlot;
|
||||
var inputNode = outputSlotRef.node;
|
||||
// If this is a redirect node we continue to look for the top one
|
||||
if (inputNode is RedirectNodeData redirectNode)
|
||||
{
|
||||
return DepthFirstCollectRedirectNodeFromNode(redirectNode);
|
||||
}
|
||||
return outputSlotRef;
|
||||
}
|
||||
// If no edges it is the first redirect node without an edge going into it and we should return the slot ref
|
||||
return node.GetSlotReference(RedirectNodeData.kInputSlotID);
|
||||
}
|
||||
|
||||
public static void DepthFirstCollectNodesFromNode(List<AbstractMaterialNode> nodeList, AbstractMaterialNode node,
|
||||
IncludeSelf includeSelf = IncludeSelf.Include, List<KeyValuePair<ShaderKeyword, int>> keywordPermutation = null, bool ignoreActiveState = false)
|
||||
{
|
||||
// no where to start
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
// already added this node
|
||||
if (nodeList.Contains(node))
|
||||
return;
|
||||
|
||||
IEnumerable<int> ids;
|
||||
|
||||
// If this node is a keyword node and we have an active keyword permutation
|
||||
// The only valid port id is the port that corresponds to that keywords value in the active permutation
|
||||
if (node is KeywordNode keywordNode && keywordPermutation != null)
|
||||
{
|
||||
var valueInPermutation = keywordPermutation.Where(x => x.Key == keywordNode.keyword).FirstOrDefault();
|
||||
ids = new int[] { keywordNode.GetSlotIdForPermutation(valueInPermutation) };
|
||||
}
|
||||
else
|
||||
{
|
||||
ids = node.GetInputSlots<MaterialSlot>().Select(x => x.id);
|
||||
}
|
||||
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(node.GetSlotReference(slot)))
|
||||
{
|
||||
var outputNode = edge.outputSlot.node;
|
||||
if (outputNode != null)
|
||||
DepthFirstCollectNodesFromNode(nodeList, outputNode, keywordPermutation: keywordPermutation, ignoreActiveState: ignoreActiveState);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeSelf == IncludeSelf.Include && (node.isActive || ignoreActiveState))
|
||||
nodeList.Add(node);
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetParentNodes(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> nodeList = new List<AbstractMaterialNode>();
|
||||
var ids = node.GetInputSlots<MaterialSlot>().Select(x => x.id);
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
if (node.owner == null)
|
||||
break;
|
||||
foreach (var edge in node.owner.GetEdges(node.FindSlot<MaterialSlot>(slot).slotReference))
|
||||
{
|
||||
var outputNode = ((Edge)edge).outputSlot.node;
|
||||
if (outputNode != null)
|
||||
{
|
||||
nodeList.Add(outputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
private static bool ActiveLeafExists(AbstractMaterialNode node)
|
||||
{
|
||||
//if our active state has been explicitly set to a value use it
|
||||
switch (node.activeState)
|
||||
{
|
||||
case AbstractMaterialNode.ActiveState.Implicit:
|
||||
break;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitInactive:
|
||||
return false;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitActive:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
List<AbstractMaterialNode> parentNodes = GetParentNodes(node);
|
||||
//at this point we know we are not explicitly set to a state,
|
||||
//so there is no reason to be inactive
|
||||
if (parentNodes.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool output = false;
|
||||
foreach (var parent in parentNodes)
|
||||
{
|
||||
output |= ActiveLeafExists(parent);
|
||||
if (output)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetChildNodes(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> nodeList = new List<AbstractMaterialNode>();
|
||||
var ids = node.GetOutputSlots<MaterialSlot>().Select(x => x.id);
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(node.FindSlot<MaterialSlot>(slot).slotReference))
|
||||
{
|
||||
var inputNode = ((Edge)edge).inputSlot.node;
|
||||
if (inputNode != null)
|
||||
{
|
||||
nodeList.Add(inputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
private static bool ActiveRootExists(AbstractMaterialNode node)
|
||||
{
|
||||
//if our active state has been explicitly set to a value use it
|
||||
switch (node.activeState)
|
||||
{
|
||||
case AbstractMaterialNode.ActiveState.Implicit:
|
||||
break;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitInactive:
|
||||
return false;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitActive:
|
||||
return true;
|
||||
}
|
||||
|
||||
List<AbstractMaterialNode> childNodes = GetChildNodes(node);
|
||||
//at this point we know we are not explicitly set to a state,
|
||||
//so there is no reason to be inactive
|
||||
if (childNodes.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool output = false;
|
||||
foreach (var child in childNodes)
|
||||
{
|
||||
output |= ActiveRootExists(child);
|
||||
if (output)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static void ActiveTreeExists(AbstractMaterialNode node, out bool activeLeaf, out bool activeRoot, out bool activeTree)
|
||||
{
|
||||
activeLeaf = ActiveLeafExists(node);
|
||||
activeRoot = ActiveRootExists(node);
|
||||
activeTree = activeRoot && activeLeaf;
|
||||
}
|
||||
|
||||
//First pass check if node is now active after a change, so just check if there is a valid "tree" : a valid upstream input path,
|
||||
// and a valid downstream output path, or "leaf" and "root". If this changes the node's active state, then anything connected may
|
||||
// change as well, so update the "forrest" or all connectected trees of this nodes leaves.
|
||||
// NOTE: I cannot think if there is any case where the entirety of the connected graph would need to change, but if there are bugs
|
||||
// on certain nodes farther away from the node not updating correctly, a possible solution may be to get the entirety of the connected
|
||||
// graph instead of just what I have declared as the "local" connected graph
|
||||
public static void ReevaluateActivityOfConnectedNodes(AbstractMaterialNode node, PooledHashSet<AbstractMaterialNode> changedNodes = null)
|
||||
{
|
||||
List<AbstractMaterialNode> forest = GetForest(node);
|
||||
ReevaluateActivityOfNodeList(forest, changedNodes);
|
||||
}
|
||||
|
||||
public static void ReevaluateActivityOfNodeList(IEnumerable<AbstractMaterialNode> nodes, PooledHashSet<AbstractMaterialNode> changedNodes = null)
|
||||
{
|
||||
bool getChangedNodes = changedNodes != null;
|
||||
foreach (AbstractMaterialNode n in nodes)
|
||||
{
|
||||
if (n.activeState != AbstractMaterialNode.ActiveState.Implicit)
|
||||
continue;
|
||||
ActiveTreeExists(n, out _, out _, out bool at);
|
||||
if (n.isActive != at && getChangedNodes)
|
||||
{
|
||||
changedNodes.Add(n);
|
||||
}
|
||||
n.SetActive(at, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Go to the leaves of the node, then get all trees with those leaves
|
||||
private static List<AbstractMaterialNode> GetForest(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> leaves = GetLeaves(node);
|
||||
List<AbstractMaterialNode> forrest = new List<AbstractMaterialNode>();
|
||||
foreach (var leaf in leaves)
|
||||
{
|
||||
if (!forrest.Contains(leaf))
|
||||
{
|
||||
forrest.Add(leaf);
|
||||
}
|
||||
foreach (var child in GetChildNodesRecursive(leaf))
|
||||
{
|
||||
if (!forrest.Contains(child))
|
||||
{
|
||||
forrest.Add(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return forrest;
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetChildNodesRecursive(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> output = new List<AbstractMaterialNode>() { node };
|
||||
List<AbstractMaterialNode> children = GetChildNodes(node);
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (!output.Contains(child))
|
||||
{
|
||||
output.Add(child);
|
||||
}
|
||||
foreach (var descendent in GetChildNodesRecursive(child))
|
||||
{
|
||||
if (!output.Contains(descendent))
|
||||
{
|
||||
output.Add(descendent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetLeaves(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> parents = GetParentNodes(node);
|
||||
List<AbstractMaterialNode> output = new List<AbstractMaterialNode>();
|
||||
if (parents.Count == 0)
|
||||
{
|
||||
output.Add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var parent in parents)
|
||||
{
|
||||
foreach (var leaf in GetLeaves(parent))
|
||||
{
|
||||
if (!output.Contains(leaf))
|
||||
{
|
||||
output.Add(leaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static void GetDownsteamNodesForNode(List<AbstractMaterialNode> nodeList, AbstractMaterialNode node)
|
||||
{
|
||||
// no where to start
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
// Recursively traverse downstream from the original node
|
||||
// Traverse down each edge and continue on any connected downstream nodes
|
||||
// Only nodes with no nodes further downstream are added to node list
|
||||
bool hasDownstream = false;
|
||||
var ids = node.GetOutputSlots<MaterialSlot>().Select(x => x.id);
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(node.FindSlot<MaterialSlot>(slot).slotReference))
|
||||
{
|
||||
var inputNode = ((Edge)edge).inputSlot.node;
|
||||
if (inputNode != null)
|
||||
{
|
||||
hasDownstream = true;
|
||||
GetDownsteamNodesForNode(nodeList, inputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No more nodes downstream from here
|
||||
if (!hasDownstream)
|
||||
nodeList.Add(node);
|
||||
}
|
||||
|
||||
public static void CollectNodeSet(HashSet<AbstractMaterialNode> nodeSet, MaterialSlot slot)
|
||||
{
|
||||
var node = slot.owner;
|
||||
var graph = node.owner;
|
||||
foreach (var edge in graph.GetEdges(node.GetSlotReference(slot.id)))
|
||||
{
|
||||
var outputNode = edge.outputSlot.node;
|
||||
if (outputNode != null)
|
||||
{
|
||||
CollectNodeSet(nodeSet, outputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CollectNodeSet(HashSet<AbstractMaterialNode> nodeSet, AbstractMaterialNode node)
|
||||
{
|
||||
if (!nodeSet.Add(node))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (ListPool<MaterialSlot>.Get(out var slots))
|
||||
{
|
||||
node.GetInputSlots(slots);
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
CollectNodeSet(nodeSet, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CollectNodesNodeFeedsInto(List<AbstractMaterialNode> nodeList, AbstractMaterialNode node, IncludeSelf includeSelf = IncludeSelf.Include)
|
||||
{
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
if (nodeList.Contains(node))
|
||||
return;
|
||||
|
||||
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(slot.slotReference))
|
||||
{
|
||||
var inputNode = edge.inputSlot.node;
|
||||
CollectNodesNodeFeedsInto(nodeList, inputNode);
|
||||
}
|
||||
}
|
||||
if (includeSelf == IncludeSelf.Include)
|
||||
nodeList.Add(node);
|
||||
}
|
||||
|
||||
public static string GetDocumentationString(string pageName)
|
||||
{
|
||||
return Documentation.GetPageLink(pageName.Replace(" ", "-") + NodeDocSuffix);
|
||||
}
|
||||
|
||||
static Stack<MaterialSlot> s_SlotStack = new Stack<MaterialSlot>();
|
||||
|
||||
public static ShaderStage GetEffectiveShaderStage(MaterialSlot initialSlot, bool goingBackwards)
|
||||
{
|
||||
var graph = initialSlot.owner.owner;
|
||||
s_SlotStack.Clear();
|
||||
s_SlotStack.Push(initialSlot);
|
||||
while (s_SlotStack.Any())
|
||||
{
|
||||
var slot = s_SlotStack.Pop();
|
||||
ShaderStage stage;
|
||||
if (slot.stageCapability.TryGetShaderStage(out stage))
|
||||
return stage;
|
||||
|
||||
if (goingBackwards && slot.isInputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.outputSlot.node;
|
||||
s_SlotStack.Push(node.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else if (!goingBackwards && slot.isOutputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.inputSlot.node;
|
||||
s_SlotStack.Push(node.FindInputSlot<MaterialSlot>(edge.inputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var ownerSlots = Enumerable.Empty<MaterialSlot>();
|
||||
if (goingBackwards && slot.isOutputSlot)
|
||||
ownerSlots = slot.owner.GetInputSlots<MaterialSlot>();
|
||||
else if (!goingBackwards && slot.isInputSlot)
|
||||
ownerSlots = slot.owner.GetOutputSlots<MaterialSlot>();
|
||||
foreach (var ownerSlot in ownerSlots)
|
||||
s_SlotStack.Push(ownerSlot);
|
||||
}
|
||||
}
|
||||
// We default to fragment shader stage if all connected nodes were compatible with both.
|
||||
return ShaderStage.Fragment;
|
||||
}
|
||||
|
||||
public static ShaderStageCapability GetEffectiveShaderStageCapability(MaterialSlot initialSlot, bool goingBackwards)
|
||||
{
|
||||
var graph = initialSlot.owner.owner;
|
||||
s_SlotStack.Clear();
|
||||
s_SlotStack.Push(initialSlot);
|
||||
while (s_SlotStack.Any())
|
||||
{
|
||||
var slot = s_SlotStack.Pop();
|
||||
ShaderStage stage;
|
||||
if (slot.stageCapability.TryGetShaderStage(out stage))
|
||||
return slot.stageCapability;
|
||||
|
||||
if (goingBackwards && slot.isInputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.outputSlot.node;
|
||||
s_SlotStack.Push(node.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else if (!goingBackwards && slot.isOutputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.inputSlot.node;
|
||||
s_SlotStack.Push(node.FindInputSlot<MaterialSlot>(edge.inputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var ownerSlots = Enumerable.Empty<MaterialSlot>();
|
||||
if (goingBackwards && slot.isOutputSlot)
|
||||
ownerSlots = slot.owner.GetInputSlots<MaterialSlot>();
|
||||
else if (!goingBackwards && slot.isInputSlot)
|
||||
ownerSlots = slot.owner.GetOutputSlots<MaterialSlot>();
|
||||
foreach (var ownerSlot in ownerSlots)
|
||||
s_SlotStack.Push(ownerSlot);
|
||||
}
|
||||
}
|
||||
|
||||
return ShaderStageCapability.All;
|
||||
}
|
||||
|
||||
public static string GetSlotDimension(ConcreteSlotValueType slotValue)
|
||||
{
|
||||
switch (slotValue)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
return String.Empty;
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
return "2";
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
return "3";
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
return "4";
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
return "2x2";
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
return "3x3";
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
return "4x4";
|
||||
default:
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: there are several bugs here.. we should use ConvertToValidHLSLIdentifier() instead
|
||||
public static string GetHLSLSafeName(string input)
|
||||
{
|
||||
char[] arr = input.ToCharArray();
|
||||
arr = Array.FindAll<char>(arr, (c => (Char.IsLetterOrDigit(c))));
|
||||
var safeName = new string(arr);
|
||||
if (safeName.Length > 1 && char.IsDigit(safeName[0]))
|
||||
{
|
||||
safeName = $"var{safeName}";
|
||||
}
|
||||
return safeName;
|
||||
}
|
||||
|
||||
static readonly string[] k_HLSLNumericKeywords =
|
||||
{
|
||||
"float",
|
||||
"half", // not technically in HLSL spec, but prob should be
|
||||
"real", // Unity thing, but included here
|
||||
"int",
|
||||
"uint",
|
||||
"bool",
|
||||
"min10float",
|
||||
"min16float",
|
||||
"min12int",
|
||||
"min16int",
|
||||
"min16uint"
|
||||
};
|
||||
|
||||
static readonly string[] k_HLSLNumericKeywordSuffixes =
|
||||
{
|
||||
"",
|
||||
"1", "2", "3", "4",
|
||||
"1x1", "1x2", "1x3", "1x4",
|
||||
"2x1", "2x2", "2x3", "2x4",
|
||||
"3x1", "3x2", "3x3", "3x4",
|
||||
"4x1", "4x2", "4x3", "4x4"
|
||||
};
|
||||
|
||||
static HashSet<string> m_ShaderLabKeywords = new HashSet<string>()
|
||||
{
|
||||
// these should all be lowercase, as shaderlab keywords are case insensitive
|
||||
"properties",
|
||||
"range",
|
||||
"bind",
|
||||
"bindchannels",
|
||||
"tags",
|
||||
"lod",
|
||||
"shader",
|
||||
"subshader",
|
||||
"category",
|
||||
"fallback",
|
||||
"dependency",
|
||||
"customeditor",
|
||||
"rect",
|
||||
"any",
|
||||
"float",
|
||||
"color",
|
||||
"int",
|
||||
"integer",
|
||||
"vector",
|
||||
"matrix",
|
||||
"2d",
|
||||
"cube",
|
||||
"3d",
|
||||
"2darray",
|
||||
"cubearray",
|
||||
"name",
|
||||
"settexture",
|
||||
"true",
|
||||
"false",
|
||||
"on",
|
||||
"off",
|
||||
"separatespecular",
|
||||
"offset",
|
||||
"zwrite",
|
||||
"zclip",
|
||||
"conservative",
|
||||
"ztest",
|
||||
"alphatest",
|
||||
"fog",
|
||||
"stencil",
|
||||
"colormask",
|
||||
"alphatomask",
|
||||
"cull",
|
||||
"front",
|
||||
"material",
|
||||
"ambient",
|
||||
"diffuse",
|
||||
"specular",
|
||||
"emission",
|
||||
"shininess",
|
||||
"blend",
|
||||
"blendop",
|
||||
"colormaterial",
|
||||
"lighting",
|
||||
"pass",
|
||||
"grabpass",
|
||||
"usepass",
|
||||
"gpuprogramid",
|
||||
"add",
|
||||
"sub",
|
||||
"revsub",
|
||||
"min",
|
||||
"max",
|
||||
"logicalclear",
|
||||
"logicalset",
|
||||
"logicalcopy",
|
||||
"logicalcopyinverted",
|
||||
"logicalnoop",
|
||||
"logicalinvert",
|
||||
"logicaland",
|
||||
"logicalnand",
|
||||
"logicalor",
|
||||
"logicalnor",
|
||||
"logicalxor",
|
||||
"logicalequiv",
|
||||
"logicalandreverse",
|
||||
"logicalandinverted",
|
||||
"logicalorreverse",
|
||||
"logicalorinverted",
|
||||
"multiply",
|
||||
"screen",
|
||||
"overlay",
|
||||
"darken",
|
||||
"lighten",
|
||||
"colordodge",
|
||||
"colorburn",
|
||||
"hardlight",
|
||||
"softlight",
|
||||
"difference",
|
||||
"exclusion",
|
||||
"hslhue",
|
||||
"hslsaturation",
|
||||
"hslcolor",
|
||||
"hslluminosity",
|
||||
"zero",
|
||||
"one",
|
||||
"dstcolor",
|
||||
"srccolor",
|
||||
"oneminusdstcolor",
|
||||
"srcalpha",
|
||||
"oneminussrccolor",
|
||||
"dstalpha",
|
||||
"oneminusdstalpha",
|
||||
"srcalphasaturate",
|
||||
"oneminussrcalpha",
|
||||
"constantcolor",
|
||||
"oneminusconstantcolor",
|
||||
"constantalpha",
|
||||
"oneminusconstantalpha",
|
||||
};
|
||||
|
||||
static HashSet<string> m_HLSLKeywords = new HashSet<string>()
|
||||
{
|
||||
"AppendStructuredBuffer",
|
||||
"asm",
|
||||
"asm_fragment",
|
||||
"auto",
|
||||
"BlendState",
|
||||
"break",
|
||||
"Buffer",
|
||||
"ByteAddressBuffer",
|
||||
"case",
|
||||
"catch",
|
||||
"cbuffer",
|
||||
"centroid",
|
||||
"char",
|
||||
"class",
|
||||
"column_major",
|
||||
"compile",
|
||||
"compile_fragment",
|
||||
"CompileShader",
|
||||
"const",
|
||||
"const_cast",
|
||||
"continue",
|
||||
"ComputeShader",
|
||||
"ConsumeStructuredBuffer",
|
||||
"default",
|
||||
"delete",
|
||||
"DepthStencilState",
|
||||
"DepthStencilView",
|
||||
"discard",
|
||||
"do",
|
||||
"double",
|
||||
"DomainShader",
|
||||
"dynamic_cast",
|
||||
"dword",
|
||||
"else",
|
||||
"enum",
|
||||
"explicit",
|
||||
"export",
|
||||
"extern",
|
||||
"false",
|
||||
"for",
|
||||
"friend",
|
||||
"fxgroup",
|
||||
"GeometryShader",
|
||||
"goto",
|
||||
"groupshared",
|
||||
"half",
|
||||
"Hullshader",
|
||||
"if",
|
||||
"in",
|
||||
"inline",
|
||||
"inout",
|
||||
"InputPatch",
|
||||
"interface",
|
||||
"line",
|
||||
"lineadj",
|
||||
"linear",
|
||||
"LineStream",
|
||||
"long",
|
||||
"matrix",
|
||||
"mutable",
|
||||
"namespace",
|
||||
"new",
|
||||
"nointerpolation",
|
||||
"noperspective",
|
||||
"NULL",
|
||||
"operator",
|
||||
"out",
|
||||
"OutputPatch",
|
||||
"packoffset",
|
||||
"pass",
|
||||
"pixelfragment",
|
||||
"PixelShader",
|
||||
"point",
|
||||
"PointStream",
|
||||
"precise",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"RasterizerState",
|
||||
"reinterpret_cast",
|
||||
"RenderTargetView",
|
||||
"return",
|
||||
"register",
|
||||
"row_major",
|
||||
"RWBuffer",
|
||||
"RWByteAddressBuffer",
|
||||
"RWStructuredBuffer",
|
||||
"RWTexture1D",
|
||||
"RWTexture1DArray",
|
||||
"RWTexture2D",
|
||||
"RWTexture2DArray",
|
||||
"RWTexture3D",
|
||||
"sample",
|
||||
"sampler",
|
||||
"SamplerState",
|
||||
"SamplerComparisonState",
|
||||
"shared",
|
||||
"short",
|
||||
"signed",
|
||||
"sizeof",
|
||||
"snorm",
|
||||
"stateblock",
|
||||
"stateblock_state",
|
||||
"static",
|
||||
"static_cast",
|
||||
"string",
|
||||
"struct",
|
||||
"switch",
|
||||
"StructuredBuffer",
|
||||
"tbuffer",
|
||||
"technique",
|
||||
"technique10",
|
||||
"technique11",
|
||||
"template",
|
||||
"texture",
|
||||
"Texture1D",
|
||||
"Texture1DArray",
|
||||
"Texture2D",
|
||||
"Texture2DArray",
|
||||
"Texture2DMS",
|
||||
"Texture2DMSArray",
|
||||
"Texture3D",
|
||||
"TextureCube",
|
||||
"TextureCubeArray",
|
||||
"this",
|
||||
"throw",
|
||||
"true",
|
||||
"try",
|
||||
"typedef",
|
||||
"typename",
|
||||
"triangle",
|
||||
"triangleadj",
|
||||
"TriangleStream",
|
||||
"uniform",
|
||||
"unorm",
|
||||
"union",
|
||||
"unsigned",
|
||||
"using",
|
||||
"vector",
|
||||
"vertexfragment",
|
||||
"VertexShader",
|
||||
"virtual",
|
||||
"void",
|
||||
"volatile",
|
||||
"while"
|
||||
};
|
||||
|
||||
static bool m_HLSLKeywordDictionaryBuilt = false;
|
||||
|
||||
public static bool IsHLSLKeyword(string id)
|
||||
{
|
||||
if (!m_HLSLKeywordDictionaryBuilt)
|
||||
{
|
||||
foreach (var numericKeyword in k_HLSLNumericKeywords)
|
||||
foreach (var suffix in k_HLSLNumericKeywordSuffixes)
|
||||
m_HLSLKeywords.Add(numericKeyword + suffix);
|
||||
|
||||
m_HLSLKeywordDictionaryBuilt = true;
|
||||
}
|
||||
|
||||
bool isHLSLKeyword = m_HLSLKeywords.Contains(id);
|
||||
|
||||
return isHLSLKeyword;
|
||||
}
|
||||
|
||||
public static bool IsShaderLabKeyWord(string id)
|
||||
{
|
||||
bool isShaderLabKeyword = m_ShaderLabKeywords.Contains(id.ToLower());
|
||||
return isShaderLabKeyword;
|
||||
}
|
||||
|
||||
public static string ConvertToValidHLSLIdentifier(string originalId, Func<string, bool> isDisallowedIdentifier = null)
|
||||
{
|
||||
// Converts " 1 var * q-30 ( 0 ) (1) " to "_1_var_q_30_0_1"
|
||||
if (originalId == null)
|
||||
originalId = "";
|
||||
|
||||
StringBuilder hlslId = new StringBuilder(originalId.Length);
|
||||
bool lastInvalid = false;
|
||||
for (int i = 0; i < originalId.Length; i++)
|
||||
{
|
||||
char c = originalId[i];
|
||||
|
||||
bool isLetter = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
bool isUnderscore = (c == '_');
|
||||
bool isDigit = (c >= '0' && c <= '9');
|
||||
|
||||
bool validChar = isLetter || isUnderscore || isDigit;
|
||||
|
||||
if (!validChar)
|
||||
{
|
||||
// when we see an invalid character, we just record that we saw it and go to the next character
|
||||
// this way we combine multiple invalid characters, and trailing ones just get dropped
|
||||
lastInvalid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// whenever we hit a valid character
|
||||
// if the last character was invalid, append an underscore
|
||||
// unless we're at the beginning of the string
|
||||
if (lastInvalid && (hlslId.Length > 0))
|
||||
hlslId.Append("_");
|
||||
|
||||
// HLSL ids can't start with a digit, prepend an underscore to prevent this
|
||||
if (isDigit && (hlslId.Length == 0))
|
||||
hlslId.Append("_");
|
||||
|
||||
hlslId.Append(c);
|
||||
|
||||
lastInvalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// empty strings not allowed -- append an underscore if it's empty
|
||||
if (hlslId.Length <= 0)
|
||||
hlslId.Append("_");
|
||||
|
||||
var result = hlslId.ToString();
|
||||
|
||||
while (IsHLSLKeyword(result))
|
||||
result = "_" + result;
|
||||
|
||||
if (isDisallowedIdentifier != null)
|
||||
while (isDisallowedIdentifier(result))
|
||||
result = "_" + result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetDisplaySafeName(string input)
|
||||
{
|
||||
//strip valid display characters from slot name
|
||||
//current valid characters are whitespace and ( ) _ separators
|
||||
StringBuilder cleanName = new StringBuilder();
|
||||
foreach (var c in input)
|
||||
{
|
||||
if (c != ' ' && c != '(' && c != ')' && c != '_')
|
||||
cleanName.Append(c);
|
||||
}
|
||||
|
||||
return cleanName.ToString();
|
||||
}
|
||||
|
||||
public static bool ValidateSlotName(string inName, out string errorMessage)
|
||||
{
|
||||
//check for invalid characters between display safe and hlsl safe name
|
||||
if (GetDisplaySafeName(inName) != GetHLSLSafeName(inName))
|
||||
{
|
||||
errorMessage = "Slot name(s) found invalid character(s). Valid characters: A-Z, a-z, 0-9, _ ( ) ";
|
||||
return true;
|
||||
}
|
||||
|
||||
//if clean, return null and false
|
||||
errorMessage = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string FloatToShaderValue(float value)
|
||||
{
|
||||
if (Single.IsPositiveInfinity(value))
|
||||
{
|
||||
return "1.#INF";
|
||||
}
|
||||
if (Single.IsNegativeInfinity(value))
|
||||
{
|
||||
return "-1.#INF";
|
||||
}
|
||||
if (Single.IsNaN(value))
|
||||
{
|
||||
return "NAN";
|
||||
}
|
||||
|
||||
return value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
// A number large enough to become Infinity (~FLOAT_MAX_VALUE * 10) + explanatory comment
|
||||
private const string k_ShaderLabInfinityAlternatrive = "3402823500000000000000000000000000000000 /* Infinity */";
|
||||
|
||||
// ShaderLab doesn't support Scientific Notion nor Infinity. To stop from generating a broken shader we do this.
|
||||
public static string FloatToShaderValueShaderLabSafe(float value)
|
||||
{
|
||||
if (Single.IsPositiveInfinity(value))
|
||||
{
|
||||
return k_ShaderLabInfinityAlternatrive;
|
||||
}
|
||||
if (Single.IsNegativeInfinity(value))
|
||||
{
|
||||
return "-" + k_ShaderLabInfinityAlternatrive;
|
||||
}
|
||||
if (Single.IsNaN(value))
|
||||
{
|
||||
return "NAN"; // A real error has occured, in this case we should break the shader.
|
||||
}
|
||||
|
||||
// For single point precision, reserve 54 spaces (e-45 min + ~9 digit precision). See floating-point-numeric-types (Microsoft docs).
|
||||
return value.ToString("0.######################################################", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
enum SlotType
|
||||
{
|
||||
Input,
|
||||
Output
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user