├── .bash_profile
├── .gitignore
├── LICENSE-APACHE
├── LICENSE-MIT
├── Makefile
├── README.md
├── katana
├── Macros
│ └── Material_v2_NMC.macro
└── UIPlugins
│ └── ShadingNodeMenu.py
├── osl
├── Makefile
├── include
│ ├── ikaConstants.h
│ └── ikaFunctions.h
└── material
│ ├── v2_Displacement.h
│ ├── v2_Displacement.osl
│ ├── v2_PxrSurface.h
│ ├── v2_PxrSurface.osl
│ ├── v2_PxrSurfaceAdapter.h
│ ├── v2_PxrSurfaceAdapter.osl
│ └── v2_PxrSurfaceModify.osl
├── ris
├── Makefile
├── displace
│ ├── Args
│ │ └── SetP.args
│ └── SetP.cpp
└── displayfilter
│ ├── Annotate.cpp
│ └── Args
│ └── Annotate.args
├── scene
├── Teapot.katana
└── Teapot_Annotated.katana
└── wiki_images
├── Annotate.params.png
├── Annotate.png
├── Material_v2_NMC.macro.png
├── Material_v2_NMC.params.png
├── Material_v2_Shaders.png
├── Teapot.katana.jpg
├── material_v2_PxrSurface.params.expanded.png
├── material_v2_PxrSurface.params.png
└── material_v2_PxrSurface.png
/.bash_profile:
--------------------------------------------------------------------------------
1 | # Shading-library installation location.
2 | export SHADING_LIBRARY="${HOME}/shading-library"
3 |
4 | # Pixar installation location.
5 | export PIXAR_ROOT="/opt/pixar"
6 |
7 | # RenderMan version.
8 | export RMAN_MAJOR="23"
9 | export RMAN_MINOR="2"
10 | export RMAN_MICRO=""
11 | export RMAN_VERSION="${RMAN_MAJOR}.${RMAN_MINOR}${RMAN_MICRO}"
12 |
13 | # Katana version.
14 | export KATANA_MAJOR="3"
15 | export KATANA_MINOR="2"
16 | export KATANA_MICRO="v4"
17 | export KATANA_SHORT_VERSION="${KATANA_MAJOR}.${KATANA_MINOR}"
18 |
19 | # RenderMan and shading-library software locations.
20 | export RMANTREE="${PIXAR_ROOT}/RenderManProServer-${RMAN_VERSION}"
21 | export RFK_LOCATION="${PIXAR_ROOT}/RenderManForKatana-${RMAN_VERSION}-katana${KATANA_SHORT_VERSION}"
22 | export RMAN_SHADERPATH="${SHADING_LIBRARY}/build:${RMANTREE}/lib/plugins:${RMANTREE}/lib/shaders"
23 | export RMAN_RIXPLUGINPATH="${SHADING_LIBRARY}/build:${RMANTREE}/lib/plugins"
24 |
25 | # Katana resource locations.
26 | export KATANA_RESOURCES="${RFK_LOCATION}/plugins/Resources/PRMan${RMAN_MAJOR}:${SHADING_LIBRARY}/katana"
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.so
3 | *.oso
4 | *.swp
5 | *.pyc
6 | /build
--------------------------------------------------------------------------------
/LICENSE-APACHE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright(c) 2018 Laika, LLC
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright(c) Laika, LLC
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a
4 | copy of this software and associated documentation files (the "Software"),
5 | to deal in the Software without restriction, including without limitation
6 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 | and/or sell copies of the Software, and to permit persons to whom the
8 | Software is furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # RMANTREE points to the RenderManProServer directory.
3 | # Set it if it's not already set in the environment.
4 | #
5 | RMANTREE ?= /opt/pixar/RenderManProServer-23.2
6 | export RMANTREE
7 |
8 | #
9 | # BUILD_DIR is where the built files will go.
10 | # Set it if it's not already set in the environment.
11 | #
12 | SRC_DIR ?= $(CURDIR)
13 | BUILD_DIR ?= $(SRC_DIR)/build
14 |
15 | #
16 | # Base command for copying files to the build directory.
17 | #
18 | COPY = rsync -rum --include "*/"
19 |
20 | #
21 | # Control variables.
22 | # These subdirectories will be built using their own Makefile.
23 | #
24 | SUBDIRS := osl ris
25 |
26 | #
27 | # Targets and prerequisites.
28 | # clean is the list of (phony) targets for cleaning the SUBDIRS directory contents.
29 | # install contains the (phony) targets for installing the SUBDIRS directory contents.
30 | #
31 | clean := $(patsubst %,%.clean,$(SUBDIRS))
32 | install := $(patsubst %,%.install,$(SUBDIRS))
33 |
34 | .PHONY : $(SUBDIRS) build
35 |
36 | build : $(SUBDIRS) install
37 |
38 | #
39 | # Rules.
40 | #
41 | clean : $(clean)
42 | -$(shell rm -rf $(BUILD_DIR))
43 |
44 | %.clean :
45 | $(MAKE) -C $(subst .clean,,$@) clean
46 |
47 | $(SUBDIRS) :
48 | $(MAKE) -C $@
49 |
50 | install : $(install)
51 | -$(shell mkdir -p $(BUILD_DIR))
52 | -$(COPY) --include="*.katana" --exclude="*" scene $(BUILD_DIR)
53 | -$(COPY) --include="*.macro" --exclude="*" katana $(BUILD_DIR)
54 | -$(COPY) --include="*.py" --exclude="*" katana $(BUILD_DIR)
55 |
56 | %.install : $(SUBDIRS)
57 | -$(COPY) --include="*.oso" --include="*.so" --include="*.args" --exclude="*" $(subst .install,,$@) $(BUILD_DIR)
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Production Shading Library
2 |
3 | [](LICENSE-APACHE)
4 | [](LICENSE-MIT)
5 |
6 | The Production Shading Library refers to [Laika's](https://www.laika.com) entire collection of VFX production shading capabilities. This repository will contain those portions of Laika's Production Shading Library that have been released as open source.
7 |
8 | This release contains a set of shading nodes based on [Pixar's](https://www.pixar.com) [RenderMan](https://renderman.pixar.com/product) that provide:
9 |
10 | - [Material Layering System](https://github.com/LaikaStudios/shading-library/wiki/prman_23.Home)
11 | - [Annotate displayfilter](https://github.com/LaikaStudios/shading-library/wiki/prman_23.Home)
12 |
13 | Please use the Discussions tab to provide any feedback or to initiate any other dialog about this repository.
14 |
15 | # Requirements
16 | * [Pixar's](https://www.pixar.com/renderman) [RenderMan 23](https://rmanwiki.pixar.com/display/REN23/RenderMan)
17 |
18 | * [Foundry's](https://www.foundry.com) [Katana](https://www.foundry.com/products/katana)
19 | * [Pixar's](https://www.pixar.com/renderman) [RenderMan 23 for Katana 3 or 4](https://rmanwiki.pixar.com/display/RFK23/RenderMan+23+for+Katana)
20 |
21 | * A c++14 compatible compiler (clang++ is specified in the [ris/Makefile](https://github.com/LaikaStudios/shading-library/blob/prman_23/ris/Makefile))
22 |
23 | # Documentation
24 | Documentation is on the [wiki page](https://github.com/LaikaStudios/shading-library/wiki/prman_23.Home).
25 |
26 | # Building Instructions
27 | The Production Shading Library at Laika is developed in a [Linux](https://en.wikipedia.org/wiki/Linux) environment.
28 | Specifically, [Fedora](https://getfedora.org). This initial release does not contain any facilities for building in other operating system environments.
29 | That said, as long as the necessary `c++` compatible compiler and `make` and `rsync` commands are available,
30 | it should be trivial to build the shading-library code on other platforms.
31 |
32 | To build the contents, execute
33 |
34 | make clean; make
35 |
36 | in your local checkout directory of the shading-library. This will put the built contents into a `build` sub-directory.
37 |
38 | # Environment
39 | Assuming you checked out this git repository to `~/shading-library` and have built it, katana's execution environment should have the following environment variables set. Make any alterations necessary for your specific set of software.
40 |
41 | Using `bash` shell:
42 |
43 | # Shading-library installation location.
44 | export SHADING_LIBRARY="${HOME}/shading-library"
45 |
46 | # Pixar installation location.
47 | export PIXAR_ROOT="/opt/pixar"
48 |
49 | # RenderMan version.
50 | export RMAN_MAJOR="23"
51 | export RMAN_MINOR="2"
52 | export RMAN_MICRO=""
53 | export RMAN_VERSION="${RMAN_MAJOR}.${RMAN_MINOR}${RMAN_MICRO}"
54 |
55 | # Katana version.
56 | export KATANA_MAJOR="3"
57 | export KATANA_MINOR="2"
58 | export KATANA_MICRO="v4"
59 | export KATANA_SHORT_VERSION="${KATANA_MAJOR}.${KATANA_MINOR}"
60 |
61 | # RenderMan and shading-library software locations.
62 | export RMANTREE="${PIXAR_ROOT}/RenderManProServer-${RMAN_VERSION}"
63 | export RFK_LOCATION="${PIXAR_ROOT}/RenderManForKatana-${RMAN_VERSION}-katana${KATANA_SHORT_VERSION}"
64 | export RMAN_RIXPLUGINPATH="${SHADING_LIBRARY}/build:${RMANTREE}/lib/plugins"
65 | export RMAN_SHADERPATH="${SHADING_LIBRARY}/build:${RMANTREE}/lib/plugins:${RMANTREE}/lib/shaders"
66 |
67 | # Katana resource locations.
68 | export KATANA_RESOURCES="${RFK_LOCATION}/plugins/Resources/PRMan${RMAN_MAJOR}:${SHADING_LIBRARY}/katana"
69 |
70 | # License
71 | Licensed under either of
72 |
73 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
74 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
75 |
76 | at your option.
77 |
--------------------------------------------------------------------------------
/katana/Macros/Material_v2_NMC.macro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/katana/Macros/Material_v2_NMC.macro
--------------------------------------------------------------------------------
/katana/UIPlugins/ShadingNodeMenu.py:
--------------------------------------------------------------------------------
1 | # From katana plugins/Src/Resources/Examples/UIPlugins/CustomLayeredMenuExample.py
2 | # Modified for use with Laika Shading Library.
3 |
4 | """
5 | Alt+P shading node menu.
6 | Generates a sorted and searchable list of shading nodes in the Node Graph.
7 | """
8 |
9 | from Katana import UI4, NodegraphAPI, LayeredMenuAPI, RenderingAPI, DrawingModule
10 | from RenderingAPI import RenderPlugins
11 |
12 |
13 | # A list of shading nodes that exist, but that are legacy'd or we otherwise want to hide.
14 | excludeList = [
15 | 'osl/material/v2_PxrSurfaceAdapter',
16 | 'ris/displace/SetP'
17 | ]
18 |
19 | # A list of shading nodes that should not typically be used.
20 | # Flag them with a yellow color in the displayed list.
21 | yellowList = []
22 |
23 | # The list of shading nodes that are preferred replacements for existing shading nodes.
24 | # Typically, these replace those in the yellow list.
25 | blueList = []
26 |
27 | # Color dict.
28 | # Sets the node color per shader category.
29 | # 'integrator' :[ 0.00, 0.00, 0.00 ],
30 | # 'lightfilter' :[ 0.00, 0.00, 0.00 ],
31 | colorDict = {
32 | 'bxdf' :[ 0.2380, 0.3196, 0.4420 ],
33 | 'convert' :[ 0.3900, 0.2910, 0.2100 ],
34 | 'data' :[ 0.2139, 0.3773, 0.4061 ],
35 | 'displace' :[ 0.2482, 0.2380, 0.4420 ],
36 | 'displayfilter':[ 0.3000, 0.3900, 0.2100 ],
37 | 'manifold' :[ 0.3968, 0.2232, 0.2232 ],
38 | 'material' :[ 0.3918, 0.2324, 0.4316 ],
39 | 'parameter' :[ 0.2821, 0.2170, 0.4030 ],
40 | 'pattern' :[ 0.2100, 0.3900, 0.3360 ],
41 | 'samplefilter' :[ 0.3900, 0.2100, 0.3180 ],
42 | 'string' :[ 0.3810, 0.3900, 0.2100 ],
43 | 'texture' :[ 0.2100, 0.3900, 0.2280 ],
44 | 'utility' :[ 0.3900, 0.3450, 0.2100 ],
45 | 'vector' :[ 0.4030, 0.2170, 0.3286 ]
46 | }
47 |
48 |
49 | def IkaPopulateCallback( layeredMenu ):
50 | """
51 | Callback for the layered menu, which adds entries to the given
52 | C{layeredMenu} based on the available shading nodes.
53 |
54 | @type layeredMenu: L{LayeredMenuAPI.LayeredMenu}
55 | @param layeredMenu: The layered menu to add entries to.
56 | """
57 | # Obtain a list of names of available PRMan shaders from the PRMan renderer info plug-in.
58 | rendererInfoPlugin = RenderPlugins.GetInfoPlugin( 'prman' )
59 | shaderType = RenderingAPI.RendererInfo.kRendererObjectTypeShader
60 | shaderNames = rendererInfoPlugin.getRendererObjectNames( shaderType )
61 |
62 | # Iterate over the names of shaders and add a menu entry for each of them to the given layered menu.
63 | # Note: Can set text to whatever I want the user to see when selecting a shading node.
64 | for shaderName in shaderNames:
65 | if( shaderName in excludeList ): continue
66 |
67 | if( shaderName.lower().find( 'lightfilter' ) != -1 ): continue
68 | if( shaderName.startswith( 'Pxr' ) and shaderName.endswith( 'Light' )): continue
69 |
70 | if( shaderName in yellowList ):
71 | layeredMenu.addEntry( shaderName, text=shaderName, color=(0.7, 0.7, 0.1) )
72 |
73 | elif( shaderName in blueList ):
74 | layeredMenu.addEntry( shaderName, text=shaderName, color=(0.4, 0.4, 1.0) )
75 |
76 | elif( shaderName.startswith( 'osl' )):
77 | layeredMenu.addEntry( shaderName, text=shaderName, color=(0.3, 0.77, 0.57) )
78 |
79 | elif( shaderName.startswith( 'ris' )):
80 | layeredMenu.addEntry( shaderName, text=shaderName, color=(0.3, 0.65, 0.73) )
81 |
82 | else:
83 | layeredMenu.addEntry( shaderName, text=shaderName, color=(0.7, 0.3, 0.3) )
84 |
85 |
86 | def ActionCallback( value ):
87 | """
88 | Callback for the layered menu, which creates a PrmanShadingNode node and
89 | sets its B{nodeType} parameter to the given C{value}, which is the name of
90 | a PRMan shader as set for the menu entry in L{IkaPopulateCallback()}.
91 |
92 | @type value: C{str}
93 | @rtype: C{object}
94 | @param value: An arbitrary object that the menu entry that was chosen
95 | represents. In our case here, this is the name of a PRMan shader as
96 | passed to the L{LayeredMenuAPI.LayeredMenu.addEntry()} function in
97 | L{IkaPopulateCallback()}.
98 | @return: An arbitrary object. In our case here, we return the created
99 | PrmanShadingNode node, which is then placed in the B{Node Graph} tab
100 | because it is a L{NodegraphAPI.Node} instance.
101 | """
102 |
103 | # Remove ris/ or osl/ prefix from the node name.
104 | if( value.find( 'ris/' ) == 0 or value.find( 'osl/' ) == 0 ):
105 | name = value[ 4: ]
106 | else:
107 | name = value
108 |
109 | # Create a node containing the chosen type.
110 | if( name.find( 'integrator' ) == 0 ):
111 | node = NodegraphAPI.CreateNode( 'PrmanIntegratorSettings', NodegraphAPI.GetRootNode() )
112 |
113 | else:
114 | node = NodegraphAPI.CreateNode( 'PrmanShadingNode', NodegraphAPI.GetRootNode() )
115 | node.getParameter( 'nodeType' ).setValue( value, 0 )
116 |
117 | # Set the node's name.
118 | node.setName( name )
119 | node.getParameter( 'name' ).setValue( node.getName(), 0 )
120 |
121 | # Set the node's color based on its shader category.
122 | for category in colorDict:
123 | if( category in name ):
124 | color = colorDict[ category ]
125 | DrawingModule.SetCustomNodeColor( node, color[0], color[1], color[2] )
126 | break
127 |
128 | # Update the Node Graph.
129 | for tab in UI4.App.Tabs.GetTabsByType( 'Node Graph' ):
130 | tab.update()
131 |
132 | return node
133 |
134 |
135 | # Laika Shading Nodes
136 | ikaLayeredMenu = LayeredMenuAPI.LayeredMenu( IkaPopulateCallback, ActionCallback, 'Alt+P',
137 | alwaysPopulate = False,
138 | onlyMatchWordStart = False
139 | )
140 | LayeredMenuAPI.RegisterLayeredMenu( ikaLayeredMenu, 'Shading Nodes' )
141 |
--------------------------------------------------------------------------------
/osl/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # RMANTREE points to the RenderManProServer directory.
3 | # Set it if it's not already set in the environment.
4 | #
5 | RMANTREE ?= /opt/pixar/RenderManProServer-23.2
6 |
7 | #
8 | # Compiler settings.
9 | #
10 | CC = ${RMANTREE}/bin/oslc
11 | CFLAGS =
12 | INCLUDE = -I. -I./include
13 |
14 | #
15 | # Control variables.
16 | # These subdirectories will be searched for .osl files, which will then be built into .oso files.
17 | #
18 | SUBDIRS := material
19 |
20 | # These shaders won't be built. Use 'subdirectory/basename'.
21 | EXCLUDE :=
22 |
23 | #
24 | # Make functionality.
25 | # src will be the list of .osl files to build from.
26 | # obj will be the list of .oso files to build.
27 | #
28 | src := $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.osl))
29 |
30 | EXCLUDE := $(basename $(EXCLUDE))
31 | EXCLUDE := $(addsuffix .osl, $(EXCLUDE))
32 |
33 | src := $(filter-out $(EXCLUDE), $(src))
34 | obj := $(src:%.osl=%.oso)
35 |
36 | #
37 | # Targets and prerequisites.
38 | #
39 | all: $(obj)
40 |
41 | #
42 | # Rules.
43 | #
44 | clean:
45 | -$(shell rm -f $(shell find . -name "*.oso" -print))
46 |
47 | show_src:
48 | @echo $(src)
49 |
50 | show_obj:
51 | @echo $(obj)
52 |
53 | #
54 | # Build rules.
55 | #
56 | %.oso : %.osl
57 | $(CC) $(CFLAGS) $(INCLUDE) -o $@ $<
58 |
--------------------------------------------------------------------------------
/osl/include/ikaConstants.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | #ifndef IKA_CONSTANTS_H
10 | #define IKA_CONSTANTS_H
11 |
12 | //----------------------------------------------------------------------
13 | // Constants
14 | //----------------------------------------------------------------------
15 | #define IKA_MAXDIST 1.0e30
16 | #define IKA_EPSILON 1.0e-6
17 |
18 | #define IKA_PI 3.141592653589793
19 | #define IKA_INVPI 0.318309886183791
20 | #define IKA_INVPISQ 0.101321183642338
21 | #define IKA_TWOPI 6.283185307179586
22 | #define IKA_INVTWOPI 0.159154943091895
23 | #define IKA_HALFPI 1.570796326794897
24 | #define IKA_SQRTPI 1.772453850905516
25 | #define IKA_SQRT2 1.414213562373095
26 | #define IKA_SQRT3 1.732050807568877
27 | #define IKA_INVSQRT2 0.707106781186547
28 | #define IKA_INVSQRT3 0.577350269189626
29 | #define IKA_SQRTTWOPI 2.506628274631000
30 |
31 | #define IKA_UNITVECTOR vector( IKA_INVSQRT3 )
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/osl/include/ikaFunctions.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2019 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | #ifndef IKA_FUNCTIONS_H
10 | #define IKA_FUNCTIONS_H
11 |
12 | #include "ikaConstants.h"
13 |
14 | //----------------------------------------------------------------------
15 | // Macros
16 | //----------------------------------------------------------------------
17 | #define IKA_DEGREES(R) degrees(R)
18 | #define IKA_RADIANS(D) radians(D)
19 |
20 |
21 | //----------------------------------------------------------------------
22 | // bumped normal compensation
23 | //
24 | // If a bump makes a front facing N back facing, those surfaces would not
25 | // be visible in a displaced surface; but they are with a bumped normal,
26 | // which typically produces a black response.
27 | // This function prevents the normal from becoming backfacing along I,
28 | // but allows it to rotate around I, maintaining its curvature
29 | // perpendicular to I, thus preserving its appearance.
30 | // Based on RixAdjustNormal().
31 | // Note: back facing normals that becoming front facing are not visible.
32 | //----------------------------------------------------------------------
33 | normal ikaBumpCompensation( normal n )
34 | {
35 | normal Nb = n;
36 |
37 | if( dot( I,N ) < 0.0 ) // Front facing surface.
38 | {
39 | vector In = normalize( I );
40 | float IdotN = dot( In, n );
41 | if( IdotN > 0.0 )
42 | {
43 | Nb -= 1.001*IdotN * In; // Make Nb roughly perpendicular to I.
44 | Nb = normalize( Nb );
45 | }
46 | }
47 |
48 | return Nb;
49 | }
50 |
51 |
52 | //----------------------------------------------------------------------
53 | // CreateOrthonormalBasis from RiTypesHelper.h
54 | // Based on the paper Building an Orthonormal Basis, Revisited in
55 | // the Journal of Computer Graphics Techniques Vol. 6, No. 1, 2017
56 | // http://jcgt.org/published/0006/01/01/
57 | //----------------------------------------------------------------------
58 | void ikaCreateOrthonormalBasis(
59 | vector Nn,
60 | output vector Tn,
61 | output vector Bn
62 | )
63 | {
64 | float sign = select( -1.0, 1.0, Nn[2] >= 0.0 );
65 | float a = -1.0 / ( sign + Nn[2] );
66 |
67 | Bn = vector( Nn[0]*Nn[1]*a, sign + Nn[1]*Nn[1]*a, -Nn[1] );
68 | Tn = vector( 1.0 + sign*Nn[0]*Nn[0]*a, sign*Bn[0], -sign*Nn[0] );
69 | }
70 |
71 |
72 | //----------------------------------------------------------------------
73 | // max
74 | //----------------------------------------------------------------------
75 | color ikaMax( float a, color b )
76 | {
77 | return max( color(a), b );
78 | }
79 |
80 | color ikaMax( color a, float b )
81 | {
82 | return max( a, color(b) );
83 | }
84 |
85 | #endif
86 |
--------------------------------------------------------------------------------
/osl/material/v2_Displacement.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2019 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | #ifndef MATERIAL_V2_DISPLACEMENT_H
10 | #define MATERIAL_V2_DISPLACEMENT_H
11 |
12 | #define DISPLACE_FLOAT_UI_DECLARE(NAME) \
13 | int Displacement_Float_On ## NAME = 0 \
14 | [[ \
15 | int connectable = 0, \
16 | string page = "Displacement.Float", \
17 | string label = "On " #NAME, \
18 | string widget = "mapper", \
19 | string options = "Off:0|On:1|Invert Input:-1", \
20 | string help = \
21 | "Turns the use of the Input " #NAME " displacement On, " \
22 | "Off, or can Invert the Input value before " \
23 | "it's used: Input -> 1-Input. " \
24 | ]], \
25 | float Displacement_Float_Input ## NAME = 0.5 \
26 | [[ \
27 | string page = "Displacement.Float", \
28 | string label = "Input " #NAME, \
29 | string help = \
30 | "A (0,1) ranged value that determines this displacement's pattern. " \
31 | "Combined with the Position and Magnitude " \
32 | "(and optionally Mask), " \
33 | "it determines the location and amount of displacement along the surface normal. " \
34 | ]], \
35 | float Displacement_Float_Position ## NAME = 0.0 \
36 | [[ \
37 | string page = "Displacement.Float", \
38 | string label = "Position " #NAME, \
39 | int slider = 1, float slidermin = -1.0, float slidermax = 1.0, \
40 | string help = \
41 | "Position sets the vertical location of this displacement relative to the " \
42 | "existing surface. This will allow it to produce only peaks, a combination of peaks and valleys, " \
43 | "or just valleys. " \
44 | "
" \
45 | "With a Position of 1, this will result in the Input (0,1) " \
46 | "values creating displacement only above the current surface. " \
47 | "
" \
48 | "A Position of 0 will result in the Input " \
49 | "values (adjusted to the range -.5,+.5) producing displacement peaks above, and valleys below, " \
50 | "the current surface. " \
51 | "
" \
52 | "A Position of -1 will shift the Input values (to -1,0) " \
53 | "so they will only create valleys below the current surface. " \
54 | ]], \
55 | float Displacement_Float_Magnitude ## NAME = 1.0 \
56 | [[ \
57 | string page = "Displacement.Float", \
58 | string label = "Magnitude " #NAME, \
59 | int slider = 1, float slidermin = 0.0, float slidermax = 10.0, float slidercenter = 1.0, \
60 | string help = \
61 | "The peak-to-valley distance produced by this displacement. " \
62 | "
" \
63 | "The assumption is that the Input pattern will range from 0 to 1; " \
64 | "so this parameter controls the actual displacement amount (in displacement " \
65 | "Mag Space units). " \
66 | "
" \
67 | "Note: you can use a negative value here to invert the Input pattern " \
68 | "and displacement direction (to -N). " \
69 | ]], \
70 | float Displacement_Float_Mask ## NAME = 1.0 \
71 | [[ \
72 | string page = "Displacement.Float", \
73 | string label = "Mask " #NAME, \
74 | int slider = 1, float slidermin = 0, float slidermax = 1, \
75 | string help = \
76 | "Controls how this displacement combines/composites " \
77 | "with the other Input displacements. " \
78 | "
" \
79 | "For example, if you want this displacement to exist only in the peaks " \
80 | "or valleys of another, you can connect a function of the other displacement's " \
81 | "Input here. " \
82 | "
" \
83 | "Alternatively, Mask values > 1 can be used to accentuate this " \
84 | "displacement in the desired areas. " \
85 | "Negative Mask values will invert this displacement. " \
86 | "
" \
87 | "Note: Mask values > 1 may result in displacements larger than " \
88 | "the Magnitude value. " \
89 | ]]
90 |
91 |
92 | #define DISPLACE_VECTOR_UI_DECLARE(NAME) \
93 | int Displacement_Vector_On ## NAME = 0 \
94 | [[ \
95 | int connectable = 0, \
96 | string page = "Displacement.Vector", \
97 | string label = "On " #NAME, \
98 | string widget = "checkBox", \
99 | string help = \
100 | "Turns the use of the Input " #NAME " displacement On or Off. " \
101 | ]], \
102 | vector Displacement_Vector_Input ## NAME = vector(0.0) \
103 | [[ \
104 | string page = "Displacement.Vector", \
105 | string label = "Input " #NAME, \
106 | string help = \
107 | "A vector value that determines this displacement's direction and amount. " \
108 | "Typically, vectors have (-1,1) ranged component values. " \
109 | "Combined with the Mode and Magnitude " \
110 | "(and optionally Mask), " \
111 | "it determines how the surface is displaced. " \
112 | ]], \
113 | int Displacement_Vector_Mode ## NAME = 1 \
114 | [[ \
115 | int connectable = 0, \
116 | string page = "Displacement.Vector", \
117 | string label = "Mode " #NAME, \
118 | string widget = "mapper", \
119 | string options = "+:1|-:-1|+/-:0", \
120 | string help = \
121 | "+ mode displaces in the Input vector direction. " \
122 | "
" \
123 | "- mode displaces in the opposite direction (-Input). " \
124 | "
" \
125 | "+/- takes an Input vector with (0,1) ranged values " \
126 | "and remaps them to (-1,+1). " \
127 | "
" \
128 | "Note: +/- Mode produces double the displacement range " \
129 | "of that produced by + or - for the same " \
130 | "Input data. " \
131 | ]], \
132 | float Displacement_Vector_Magnitude ## NAME = 1.0 \
133 | [[ \
134 | string page = "Displacement.Vector", \
135 | string label = "Magnitude " #NAME, \
136 | int slider = 1, float slidermin = 0.0, float slidermax = 10.0, float slidercenter = 1.0, \
137 | string help = \
138 | "The magnitude (vector length scale) of the displacement. " \
139 | "
" \
140 | "The assumption is that the Input vector will have a maximum length " \
141 | "of 1; so this parameter controls the actual displacement amount (in displacement " \
142 | "Mag Space units). " \
143 | ]], \
144 | float Displacement_Vector_Mask ## NAME = 1.0 \
145 | [[ \
146 | string page = "Displacement.Vector", \
147 | string label = "Mask " #NAME, \
148 | int slider = 1, float slidermin = 0, float slidermax = 1, \
149 | string help = \
150 | "Controls how this displacement combines/composites " \
151 | "with the other Input displacements. " \
152 | "
" \
153 | "For example, if you want this displacement to exist only in the peaks " \
154 | "or valleys of another, you can connect a function of the other displacement's " \
155 | "Input here. " \
156 | "
" \
157 | "Alternatively, Mask values > 1 can be used to accentuate this " \
158 | "displacement in the desired areas. " \
159 | "Negative Mask values will invert this displacement. " \
160 | "
" \
161 | "Note: Mask magnitudes > 1 may result in displacements larger than " \
162 | "the Magnitude value. " \
163 | ]]
164 |
165 |
166 | float displace_float_pattern(
167 | int mode, // 0=Off, 1=On, -1=Invert
168 | float input,
169 | float magnitude,
170 | float mask
171 | )
172 | {
173 | float result = 0.0;
174 |
175 | if( mode == 1 ) result = input*magnitude*mask;
176 | else if( mode == -1 ) result = ( 1.0-input )*magnitude*mask;
177 |
178 | return result;
179 | }
180 |
181 | float displace_float_amount(
182 | int mode, // 0=Off, 1=On, -1=Invert
183 | float input,
184 | float position,
185 | float magnitude,
186 | float mask
187 | )
188 | {
189 | float result = 0.0;
190 |
191 | if( mode == 1 ) result = ( input + mix( -0.5, 0.0, position ))*magnitude*mask;
192 | else if( mode == -1 ) result = (( 1.0-input ) + mix( -0.5, 0.0, position ))*magnitude*mask;
193 |
194 | return result;
195 | }
196 |
197 | #define DISPLACE_FLOAT_MAG(NAME) \
198 | (( Displacement_Float_On ## NAME ) ? abs( Displacement_Float_Magnitude ## NAME ) : 0.0 )
199 |
200 | #define DISPLACE_FLOAT_PATTERN(NAME) \
201 | displace_float_pattern( \
202 | Displacement_Float_On ## NAME, \
203 | Displacement_Float_Input ## NAME, \
204 | Displacement_Float_Magnitude ## NAME, \
205 | Displacement_Float_Mask ## NAME \
206 | )
207 |
208 | #define DISPLACE_FLOAT_AMOUNT(NAME) \
209 | displace_float_amount( \
210 | Displacement_Float_On ## NAME, \
211 | Displacement_Float_Input ## NAME, \
212 | Displacement_Float_Position ## NAME, \
213 | Displacement_Float_Magnitude ## NAME, \
214 | Displacement_Float_Mask ## NAME \
215 | )
216 |
217 |
218 | // Computes a common space displacement vector with
219 | // the given orientation and directional magnitude.
220 | vector displace_vector(
221 | vector input,
222 | int mode, // -1=Negate, 1=None, 0=Expand
223 | string directionSpace,
224 | string magnitudeSpace,
225 | float magnitude,
226 | float mask
227 | )
228 | {
229 | vector in = input;
230 |
231 | // Remapping modes.
232 | // in = select( in, mix( vector(-1.0), vector(1.0), in ), mode > 1 ); // Expand.
233 | // in = select( in, -in, mode == 1 || mode == 3 ); // Negate.
234 | if( mode == -1 )
235 | {
236 | in = -in;
237 | }
238 | else if( mode == 0 )
239 | {
240 | in = mix( vector(-1.0), vector(1.0), in );
241 | }
242 |
243 | // Determine the Magnitude Space scale relative to a common space vector.
244 | // Note: must use a vector transform to get the proper orienation,
245 | // and a normal transform to get the proper scale.
246 | normal Vmag = normalize( transform( directionSpace, "common", in )); // vector
247 | float magScale = length( transform( "common", magnitudeSpace, Vmag )); // normal
248 |
249 | // Common space displacement vector with the original vector length.
250 | vector Vdir = Vmag * length( in );
251 |
252 | // Apply the Magnitude Space scaling, plus the unitless UI controls.
253 | vector result = Vdir * magScale * magnitude * mask;
254 |
255 | // Done.
256 | return result;
257 | }
258 |
259 |
260 | #define DISPLACE_VECTOR_MAG(NAME) \
261 | (( Displacement_Vector_On ## NAME ) ? length( Displacement_Vector_Input ## NAME ) * Displacement_Vector_Magnitude ## NAME * Displacement_Vector_Mask ## NAME : 0.0 )
262 |
263 | #define DISPLACE_VECTOR_PATTERN(NAME) \
264 | (( Displacement_Vector_On ## NAME ) ? 0.5*(dot( N, Displacement_Vector_Input ## NAME )+1.0) * Displacement_Vector_Magnitude ## NAME * Displacement_Vector_Mask ## NAME : 0.0 )
265 |
266 | #define DISPLACE_VECTOR_AMOUNT(NAME,DIRSPACE,MAGSPACE) ( \
267 | Displacement_Vector_On ## NAME \
268 | ? displace_vector( \
269 | Displacement_Vector_Input ## NAME, \
270 | Displacement_Vector_Mode ## NAME, \
271 | DIRSPACE, \
272 | MAGSPACE, \
273 | Displacement_Vector_Magnitude ## NAME, \
274 | Displacement_Vector_Mask ## NAME \
275 | ) \
276 | : vector(0.0) \
277 | )
278 |
279 | #endif
280 |
--------------------------------------------------------------------------------
/osl/material/v2_Displacement.osl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2020 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | /*
10 | Duplicate material displacement only.
11 | */
12 | #include "ikaConstants.h"
13 | #include "material/v2_Displacement.h"
14 | #include "material/v2_PxrSurface.h"
15 |
16 | shader v2_Displacement
17 | [[
18 | int rfm_nodeid = 1234002,
19 | string rfm_classification = "rendernode/RenderMan/pattern/material",
20 | string help =
21 | "Creates a Material layer that has only Displacement. "
22 | "
"
23 | "Note: Displacements will affect other Material "
24 | "layer displacements based on their layer order, Thickness, "
25 | "and Mask values. "
26 | ]]
27 | (
28 | string Notes = ""
29 | [[
30 | int connectable = 0,
31 | string help =
32 | "Creates a Material layer that has only Displacement. "
33 | "
"
34 | "Note: Displacements will affect other Material "
35 | "layer displacements based on their layer order, Thickness, "
36 | "and Mask values. "
37 | "
"
38 | ]],
39 |
40 | /*
41 | * The Input Material data set.
42 | *
43 | * This consists of a vstruct parameter, a material struct parameter, and a set
44 | * of enable parameters for each response. The material struct and response enable
45 | * parameters are members of the vstruct parameter.
46 | */
47 | // The vstruct parameter. This is the single material connection point
48 | // for all the material parameters in the material struct.
49 | PXRSURFACE_MATERIAL_VSTRUCT( MaterialInput, Material Input,
50 | The connected Material Input layers OVER this one:
51 | connect a PxrSurface Material Output here to
52 | layer it OVER this material.
53 | ),
54 |
55 | // The material struct parameter.
56 | PXRSURFACE_MATERIAL_STRUCT( MaterialInput, MatIn ),
57 |
58 | // The response Enable parameters. These are linked to a vstructmember of the vstruct parameter.
59 | ALL_ENABLE_PARAMS( MaterialInput, ClearCoat ),
60 | ALL_ENABLE_PARAMS( MaterialInput, PrimarySpecular ),
61 | ALL_ENABLE_PARAMS( MaterialInput, SecondarySpecular ),
62 | RESPONSE_ENABLE_PARAM( MaterialInput, Iridescence ),
63 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Iridescence ),
64 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Iridescence ),
65 | RESPONSE_ENABLE_PARAM( MaterialInput, Fuzz ),
66 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Fuzz ),
67 | RESPONSE_ENABLE_PARAM( MaterialInput, Diffuse ),
68 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Diffuse ),
69 | RESPONSE_ENABLE_PARAM( MaterialInput, Scatter ),
70 | RESPONSE_ENABLE_PARAM( MaterialInput, Subsurface ),
71 | RESPONSE_ENABLE_PARAM( MaterialInput, Glass ),
72 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Glass ),
73 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Glass ),
74 | RESPONSE_ENABLE_PARAM( MaterialInput, Glow ),
75 |
76 | /*
77 | * This material's user interface parameters.
78 | */
79 | int Enable = 1
80 | [[
81 | int connectable = 0,
82 | string label = "Enable",
83 | string widget = "checkBox",
84 | string help =
85 | "Turns the computation of this Displacement On/Off. "
86 | ]],
87 |
88 | float Mask = 1.0
89 | [[
90 | string label = "Mask",
91 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
92 | string help =
93 | "This material Mask (a.k.a. Opacity, Alpha, Matte, Presence, etc.) "
94 | "determines the distribution of this material layer: where it is versus where it isn't. "
95 | "Specifically, it controls the blend between this material and the material "
96 | "composited UNDER it. "
97 | ]],
98 |
99 | //
100 | // Displacement parameters start here.
101 | //
102 | float Displacement_Thickness = 0.0
103 | [[
104 | string page = "Displacement",
105 | string label = "Thickness",
106 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
107 | string help =
108 | "Thickness determines the degree to which this material will "
109 | "cover over the displacement of the underlying material (the one connected to "
110 | "Material Output). "
111 | "
"
112 | "When 0, this material has no thickness, so it will be applied directly "
113 | "to, and exactly follow, the underlying material's displaced surface. "
114 | "
"
115 | "When 1, this material is completely 'thick', so it will be applied to the underlying "
116 | "material's smooth Covering Height surface. "
117 | ]],
118 |
119 | float Displacement_BumpPercent = 1.0
120 | [[
121 | string page = "Displacement",
122 | string label = "Bump Percent",
123 | int slider = 1, float slidermin = 0.0, float slidermax = 2.0,
124 | string help =
125 | "How much of the displaced surface normal is used in shading? "
126 | "
"
127 | "Values greater than 1 accentuate the shading effects of the displacement. "
128 | "
"
129 | "Values less than 1 diminish the shading effects of any displacement. "
130 | "The result of this can be used as a simple substitute for subsurface scattering effects. "
131 | "
"
132 | "Note: any time the shading normal doesn't match the geometry's normal "
133 | "(Bump Percent ≠ 1), there is the possibility "
134 | "of artifacts in the shaded result - particularly when Bump Percent > 1. "
135 | "You've been warned. "
136 | ]],
137 |
138 | float Displacement_CoveringHeight = 0.0
139 | [[
140 | string page = "Displacement",
141 | string label = "Covering Height",
142 | int slider = 1, float slidermin = 0.0, float slidermax = 5.0, float slidercenter = 0.5,
143 | string help =
144 | "Sets the height (in Mag Space) of a uniformly displaced surface that's "
145 | "produced when this material is completely covered by an overlying material: i.e. when that "
146 | "material's Thickness = 1. "
147 | "
"
148 | "It is the height of a level surface that's intended to cover the peaks of this "
149 | "material's displacement. "
150 | "A good starting number is (0.25 + 0.5*Position)*(Magnitude), or, assuming Position=0, "
151 | "0.25*Magnitude. "
152 | "
"
153 | "If Covering Height is left at 0, the original geometric surface is used. "
154 | ]],
155 |
156 | string Displacement_MagSpace = "world"
157 | [[
158 | int connectable = 0,
159 | string page = "Displacement",
160 | string label = "Mag Space",
161 | string widget = "popup", int editable = 1,
162 | string options = "common|world|object",
163 | string help =
164 | "Selects the Space in which the Displacement Covering Height "
165 | "and Float and Vector Magnitude units are specified. "
166 | ]],
167 |
168 | float Displacement_MagScale = 1.0
169 | [[
170 | string page = "Displacement",
171 | string label = "Mag Scale",
172 | int slider = 1, float slidermin = 0.0, float slidermax = 10.0, float slidercenter = 1.0,
173 | string help =
174 | "An overall Scale applied to all the Input Float "
175 | "and Vector Magnitudes. "
176 | ]],
177 |
178 | // Float displacements.
179 | normal Displacement_Float_Nn = normal(0.0)
180 | [[
181 | string page = "Displacement.Float",
182 | string label = "Nn",
183 | string help =
184 | "Use this common space surface normal for the Float displacement "
185 | "directions. Defaults to the surface normal N if left un-connected. "
186 | "
"
187 | "Note: this must be connected to set it: "
188 | "manually entering values will not work. "
189 | ]],
190 |
191 | DISPLACE_FLOAT_UI_DECLARE(0),
192 | DISPLACE_FLOAT_UI_DECLARE(1),
193 | DISPLACE_FLOAT_UI_DECLARE(2),
194 | DISPLACE_FLOAT_UI_DECLARE(3),
195 | DISPLACE_FLOAT_UI_DECLARE(4),
196 |
197 | // Vector displacements.
198 | string Displacement_Vector_DirSpace = "Mag Space Value"
199 | [[
200 | int connectable = 0,
201 | string page = "Displacement.Vector",
202 | string label = "Dir Space",
203 | string widget = "popup", int editable = 1,
204 | string options = "Mag Space Value|common|world|object",
205 | string help =
206 | "The coordinate system in which the Vector Input Directions are specified. "
207 | "You may also enter the name of your own coordinate system. "
208 | "
"
209 | "Note: it is assumed the Input vectors have a maximum length of 1. "
210 | "Mag Space and Magnitude therefore determine their "
211 | "amount of displacement. "
212 | "
"
213 | "Dir Space however, specifies their orientation (direction): "
214 | "vector direction and magnitude are separate characteristics. "
215 | ]],
216 |
217 | DISPLACE_VECTOR_UI_DECLARE(0),
218 | DISPLACE_VECTOR_UI_DECLARE(1),
219 | DISPLACE_VECTOR_UI_DECLARE(2),
220 | DISPLACE_VECTOR_UI_DECLARE(3),
221 | DISPLACE_VECTOR_UI_DECLARE(4),
222 |
223 | // Utility socket.
224 | int Socket = 0
225 | [[
226 | string help =
227 | "Connect a shading node's Plug output here in order to execute that node and "
228 | "any shading tree connected to it. "
229 | ]],
230 |
231 | /*
232 | * The Output Material data set.
233 | *
234 | * This consists of a vstruct parameter, a material struct parameter, and a set
235 | * of enable parameters for each response. The material struct and response enable
236 | * parameters are members of the vstruct parameter.
237 | */
238 | output PXRSURFACE_MATERIAL_VSTRUCT( MaterialOutput, Material Output,
239 | Connect this to a PxrSurface Material shader's Material Input
240 | to layer this OVER it.
241 |
242 | If this is the last Material in the layer chain connect this to a
243 | PxrSurface_Material node.
244 | ),
245 |
246 | // The struct parameter.
247 | output PXRSURFACE_MATERIAL_STRUCT( MaterialOutput, MatOut ),
248 |
249 | // Set the output vstruct Enable parameters based on the input Enable value and user parameter settings.
250 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, ClearCoat ),
251 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, PrimarySpecular ),
252 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, SecondarySpecular ),
253 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
254 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
255 | SET_ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
256 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Fuzz ),
257 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Fuzz ),
258 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Diffuse ),
259 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Diffuse ),
260 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Scatter ),
261 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Subsurface ),
262 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
263 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
264 | SET_ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
265 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Glow ),
266 |
267 | // This material's masks, as possibly modified by a pattern ramp.
268 | output float dispMask = 1.0 [[ string widget = "null" ]]
269 | )
270 | /*
271 | * Material functionality: Output = Input OVER this.
272 | */
273 | {
274 | // Pull on the Socket to make sure it's evaluated.
275 | MatOut.socket = Socket;
276 |
277 | // Bxdf data is passed through.
278 | MatOut = MatIn;
279 |
280 | // Short-circuit this material.
281 | if( Enable != 0 )
282 | {
283 |
284 | // Initialize this material's mask values.
285 | dispMask = Mask; // this_dispMask
286 |
287 |
288 | //
289 | // Displacement.
290 | //
291 | vector this_deltaP;
292 | vector this_coverV;
293 |
294 | // The covering height surface offset vector for this material.
295 | // Nmag is common space direction with length relative to Mag Space.
296 | // Note: must use a normal transform to get the proper scale.
297 | normal Nn = normalize(N);
298 | normal Nmag = Nn * length( transform( "common", Displacement_MagSpace, Nn )); // normal
299 |
300 | this_coverV = Nmag * Displacement_CoveringHeight;
301 |
302 | // Float displacements.
303 | if( isconnected( Displacement_Float_Nn ))
304 | {
305 | Nn = Displacement_Float_Nn;
306 | Nmag = Nn * length( transform( "common", Displacement_MagSpace, Nn )); // normal
307 | }
308 |
309 | // Add float displacements to the deltaP displacement vector.
310 | float floatDisp = DISPLACE_FLOAT_AMOUNT(0)
311 | + DISPLACE_FLOAT_AMOUNT(1)
312 | + DISPLACE_FLOAT_AMOUNT(2)
313 | + DISPLACE_FLOAT_AMOUNT(3)
314 | + DISPLACE_FLOAT_AMOUNT(4);
315 |
316 | this_deltaP = Nmag * floatDisp;
317 |
318 | // Vector displacements.
319 | // Magnitude and Direction are handled separately.
320 | string directionSpace = ( Displacement_Vector_DirSpace != "Mag Space Value" )
321 | ? Displacement_Vector_DirSpace : Displacement_MagSpace;
322 |
323 | // Add vector displacements to the deltaP displacement vector.
324 | vector vectorDisp = DISPLACE_VECTOR_AMOUNT( 0, directionSpace, Displacement_MagSpace )
325 | + DISPLACE_VECTOR_AMOUNT( 1, directionSpace, Displacement_MagSpace )
326 | + DISPLACE_VECTOR_AMOUNT( 2, directionSpace, Displacement_MagSpace )
327 | + DISPLACE_VECTOR_AMOUNT( 3, directionSpace, Displacement_MagSpace )
328 | + DISPLACE_VECTOR_AMOUNT( 4, directionSpace, Displacement_MagSpace );
329 |
330 | this_deltaP += vectorDisp;
331 |
332 | // Globally scale the displacement. Displacement_MagScale is unitless.
333 | this_deltaP *= Displacement_MagScale;
334 |
335 | // Pre-multiply by the displacement mask.
336 | this_deltaP *= dispMask;
337 | this_coverV *= dispMask;
338 |
339 | // Note: coverV is not composited. It is only communicated
340 | // with the immediately overlying material layer.
341 | MatOut.coverV = this_coverV;
342 |
343 | // Displacement compositing.
344 | // Note: displacement is NOT Porter-Duff OVER operation composited.
345 | MatOut.deltaP = MatIn.deltaP + mix(
346 | this_deltaP,
347 | this_coverV,
348 | MatIn.thickness
349 | );
350 |
351 | // Thickness accumulates through all the layers, since layer displacements all accumulate.
352 | // Any overlying layer's thickness will apply to all layers below it, so always pass on the
353 | // largest thickness value.
354 | MatOut.thickness = max( MatIn.thickness, Displacement_Thickness*dispMask );
355 |
356 | // Handle BumpPercent. Just use dispMask - no need for all the bxdfMask controls.
357 | PARAM_OVER( MatOut, MatIn, Displacement, BumpPercent, dispMask );
358 |
359 | }
360 | }
361 |
--------------------------------------------------------------------------------
/osl/material/v2_PxrSurface.osl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2020 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | /*
10 | Material: a single node that combines bxdf and displacement controls.
11 | Each material node has a Material Input connection which is composited OVER
12 | this material's parameter settings, and the result is returned in Material Output.
13 | */
14 | #include "ikaConstants.h"
15 |
16 | #include "material/v2_Displacement.h"
17 | #include "material/v2_PxrSurface.h"
18 |
19 | shader v2_PxrSurface
20 | [[
21 | int rfm_nodeid = 1234034,
22 | string rfm_classification = "rendernode/RenderMan/pattern/material",
23 | string help =
24 | "A Material "
25 | "defines its response to light, its surface displacement, and its presence. "
26 | "Other materials of the same type can be composited together to produce a single layered material. "
27 | "The composited result is returned as a Material Output. "
28 | "
"
29 | "Note: a material that's connected to this one's Material Input "
30 | "is composited OVER this one. "
31 | "
"
32 | "Material Input
"
33 | " ↓
"
34 | " This Material
"
35 | " ↓
"
36 | "Material Output"
37 | "
"
38 | "The output of the final Material node in the chain is connected to a "
39 | "Material_v2_Shaders Shading Group, which produces a "
40 | "prmanBxdf and a prmanDisplacement output. "
41 | ]]
42 | (
43 | string Notes = ""
44 | [[
45 | int connectable = 0,
46 | string help =
47 | "A Material "
48 | "defines its response to light, its surface displacement, and its presence. "
49 | "Other materials of the same type can be composited together to produce a single layered material. "
50 | "The composited result is returned as a Material Output. "
51 | "
"
52 | "Note: a material that's connected to this one's Material Input "
53 | "is composited OVER this one. "
54 | "
"
55 | "Material Input
"
56 | " ↓
"
57 | " This Material
"
58 | " ↓
"
59 | "Material Output"
60 | "
"
61 | "The output of the final Material node in the chain is connected to a "
62 | "Material_v2_Shaders Shading Group, which produces a "
63 | "prmanBxdf and a prmanDisplacement output. "
64 | ]],
65 |
66 | /*
67 | * The Input Material data set.
68 | *
69 | * This consists of a vstruct parameter, a material struct parameter, and a set
70 | * of enable parameters for each response. The material struct and response enable
71 | * parameters are members of the vstruct parameter.
72 | */
73 | // The vstruct parameter. This is the single material connection point
74 | // for all the material parameters in the material struct.
75 | PXRSURFACE_MATERIAL_VSTRUCT( MaterialInput, Material Input,
76 | The connected Material Input layers OVER this one:
77 | connect a v2_PxrSurface Material Output here to
78 | layer it OVER this material.
79 | ),
80 |
81 | // The material struct parameter.
82 | PXRSURFACE_MATERIAL_STRUCT( MaterialInput, MatIn ),
83 |
84 | // The response Enable parameters. These are linked to a vstructmember of the vstruct parameter.
85 | ALL_ENABLE_PARAMS( MaterialInput, ClearCoat ),
86 | ALL_ENABLE_PARAMS( MaterialInput, PrimarySpecular ),
87 | ALL_ENABLE_PARAMS( MaterialInput, SecondarySpecular ),
88 | RESPONSE_ENABLE_PARAM( MaterialInput, Iridescence ),
89 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Iridescence ),
90 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Iridescence ),
91 | RESPONSE_ENABLE_PARAM( MaterialInput, Fuzz ),
92 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Fuzz ),
93 | RESPONSE_ENABLE_PARAM( MaterialInput, Diffuse ),
94 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Diffuse ),
95 | RESPONSE_ENABLE_PARAM( MaterialInput, Scatter ),
96 | RESPONSE_ENABLE_PARAM( MaterialInput, Subsurface ),
97 | RESPONSE_ENABLE_PARAM( MaterialInput, Glass ),
98 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Glass ),
99 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Glass ),
100 | RESPONSE_ENABLE_PARAM( MaterialInput, Glow ),
101 |
102 | /*
103 | * This material's user interface parameters.
104 | */
105 | int Enable = 1
106 | [[
107 | int connectable = 0,
108 | string label = "Enable",
109 | string widget = "checkBox",
110 | string help =
111 | "Turns the computation of this Material On/Off. "
112 | "When disabled, this material will not be included in any layered set of materials: its "
113 | "Material Input will be copied directly to its Material Output. "
114 | ]],
115 |
116 | float Mask = 1.0
117 | [[
118 | string label = "Mask",
119 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
120 | string help =
121 | "This material Mask (a.k.a. Opacity, Alpha, Matte, Presence, etc.) "
122 | "determines the distribution of this material layer: where it is versus where it isn't. "
123 | "Specifically, it controls the blend between this material and the material "
124 | "composited UNDER it. "
125 | ]],
126 |
127 | //
128 | // Bxdf parameters start here.
129 | //
130 | normal Global_ShadingNormal = normal( 0.0 )
131 | [[
132 | string page = "Global",
133 | string label = "Shading Normal",
134 | string help =
135 | "An alternate shading normal to use for all responses. "
136 | "If an individual response specifies its own shading normal values, "
137 | "they will override these settings. "
138 | ]],
139 |
140 | float Global_UseShadingNormal = 1.0
141 | [[
142 | string page = "Global",
143 | string label = "Use Shading Normal",
144 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
145 | string help =
146 | "How much of the connected Shading Normal is used? "
147 | "This is a mix between the regular (potentially displaced) shading normal N, "
148 | "and the connected Shading Normal value. "
149 | "
"
150 | "Note: this has no effect if the Shading Normal is unconnected. "
151 | ]],
152 |
153 | color Global_ShadowColor = color( 0.0 )
154 | [[
155 | string page = "Global",
156 | string label = "Shadow Color",
157 | string help =
158 | "Sets the color of the shadows cast by this material. "
159 | ]],
160 |
161 | color Global_UserColor = color( 0.0 )
162 | [[
163 | string page = "Global",
164 | string label = "User Color",
165 | string help =
166 | "User Color is output in LPE user lobe 4: U4 "
167 | ]],
168 |
169 | // Clearcoat response.
170 | CLEARCOAT_UI_DECLARE( Clear Coat, ClearCoat,
171 | Clear Coat represents a clear specular layer applied over all the other
172 | responses. It can be truly clear. Or it can optionally absorb colored light from the layers
173 | below it to tint the overall response.
174 | , ClearCoat_RoughnessUIDefault ),
175 |
176 | // Primary specular response.
177 | SPECULAR_UI_DECLARE( Primary Specular, PrimarySpecular,
178 | Primary Specular is the first of two 'standard' specular responses.
179 | It is capable of producing a broad range of response types from artistic
180 | to physically based and dielectric to metallic.
181 | , PrimarySpecular_RoughnessUIDefault ),
182 |
183 | // Secondary specular response.
184 | SPECULAR_UI_DECLARE( Secondary Specular, SecondarySpecular,
185 | Secondary Specular is the second of two 'standard' specular responses.
186 | It is capable of producing a broad range of response types from artistic
187 | to physically based and dielectric to metallic.
188 | , SecondarySpecular_RoughnessUIDefault ),
189 |
190 | // Iridescence response.
191 | IRIDESCENCE_UI_DECLARE(
192 | Iridescence is a special type of specular response.
193 | It produces the effects of thin-film interference and can be controlled
194 | using Artistic or Physically based controls.
195 | ),
196 |
197 | // Fuzz response.
198 | FUZZ_UI_DECLARE(
199 | Fuzz produces scattering of the illumination in
200 | a boundry layer on the surface. It is implemented as a Marschner
201 | hair primary reflection response (R component) where the hair fibers
202 | are oriented in the direction of the shading normal.
203 | ),
204 |
205 | // Diffuse response.
206 | DIFFUSE_UI_DECLARE(
207 | Diffuse uses an Oren-Nayar response model employing
208 | a Roughness parameter to control the deviation of micro-facet normals.
209 | ),
210 |
211 | // Scatter response.
212 | SCATTER_UI_DECLARE(
213 | Scatter produces (single) scattering through the interior
214 | of an object. It has many controls for altering the physical and artistic
215 | characteristics of the response.
216 | Its main feature is the ability to alter the directionality of the scattering
217 | from forward to backward to isotropic.
218 | ),
219 |
220 | // Subsurface response.
221 | SUBSURFACE_UI_DECLARE(
222 | Subsurface produces multiple scattering through the interior
223 | of an object. It has many controls for altering the physical and artistic
224 | characteristics of the response.
225 | ),
226 |
227 | // Scatter & Subsurface controls.
228 | color ScatterAndSubsurface_IlluminationTint = color( 1.0 )
229 | [[
230 | string page = "Scatter And Subsurface",
231 | string label = "Illumination Tint",
232 | string help =
233 | "Tints the incoming illumination prior to being used in the "
234 | "Scatter and Subsurface response computations. "
235 | "In light linear space. "
236 | ]],
237 |
238 | float ScatterAndSubsurface_Roughness = 0.0
239 | [[
240 | string page = "Scatter And Subsurface",
241 | string label = "Roughness",
242 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
243 | string help =
244 | "Controls the diffuse micro-facet surface roughness used in the "
245 | "Scatter and Subsurface response computations. "
246 | "Increasing Roughness causes the rays penetrating into "
247 | "the material to have an increasingly broader range of directions than lower "
248 | "Roughness values. This tends to slightly darken the overall response, "
249 | "as the light is more widely dispersed prior to entering the material. "
250 | ]],
251 |
252 | // Glass response.
253 | GLASS_UI_DECLARE(
254 | Glass produces a physically-based glass that
255 | includes Reflection and Refraction.
256 | It has many controls for altering the physical properties of the glass
257 | including its interior.
258 | ),
259 |
260 |
261 | // Glow response.
262 | EGC_UI_DECLARE( Glow, Glow,
263 | Glow can make an object appear to emit light.
264 |
265 | Note: this is not an efficient way to illuminate a scene and would require
266 | indirect bounces to be at least 2 to be effective. This should instead be
267 | used simply as a shading effect and not for actual lighting.
268 | ),
269 |
270 | //
271 | // Displacement parameters start here.
272 | //
273 | float Displacement_Thickness = 0.0
274 | [[
275 | string page = "Displacement",
276 | string label = "Thickness",
277 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
278 | string help =
279 | "Thickness determines the degree to which this material will "
280 | "cover over the displacement of the underlying material (the one connected to "
281 | "Material Output). "
282 | "
"
283 | "When 0, this material has no thickness, so it will be applied directly "
284 | "to, and exactly follow, the underlying material's displaced surface. "
285 | "
"
286 | "When 1, this material is completely 'thick', so it will be applied to the underlying "
287 | "material's smooth Covering Height surface. "
288 | ]],
289 |
290 | float Displacement_BumpPercent = 1.0
291 | [[
292 | string page = "Displacement",
293 | string label = "Bump Percent",
294 | int slider = 1, float slidermin = 0.0, float slidermax = 2.0,
295 | string help =
296 | "How much of the displaced surface normal is used in shading? "
297 | "
"
298 | "Values greater than 1 accentuate the shading effects of the displacement. "
299 | "
"
300 | "Values less than 1 diminish the shading effects of any displacement. "
301 | "The result of this can be used as a simple substitute for subsurface scattering effects. "
302 | "
"
303 | "Note: any time the shading normal doesn't match the geometry's normal "
304 | "(Bump Percent ≠ 1), there is the possibility "
305 | "of artifacts in the shaded result - particularly when Bump Percent > 1. "
306 | "You've been warned. "
307 | ]],
308 |
309 | float Displacement_CoveringHeight = 0.0
310 | [[
311 | string page = "Displacement",
312 | string label = "Covering Height",
313 | int slider = 1, float slidermin = 0.0, float slidermax = 5.0, float slidercenter = 0.5,
314 | string help =
315 | "Sets the height (in Mag Space) of a uniformly displaced surface that's "
316 | "produced when this material is completely covered by an overlying material: i.e. when that "
317 | "material's Thickness = 1. "
318 | "
"
319 | "It is the height of a level surface that's intended to cover the peaks of this "
320 | "material's displacement. "
321 | "A good starting number is (0.25 + 0.5*Position)*(Magnitude), or, assuming Position=0, "
322 | "0.25*Magnitude. "
323 | "
"
324 | "If Covering Height is left at 0, the original geometric surface is used. "
325 | ]],
326 |
327 | string Displacement_MagSpace = "world"
328 | [[
329 | int connectable = 0,
330 | string page = "Displacement",
331 | string label = "Mag Space",
332 | string widget = "popup", int editable = 1,
333 | string options = "common|world|object",
334 | string help =
335 | "Selects the Space in which the Displacement Covering Height "
336 | "and Float and Vector Magnitude units are specified. "
337 | ]],
338 |
339 | float Displacement_MagScale = 1.0
340 | [[
341 | string page = "Displacement",
342 | string label = "Mag Scale",
343 | int slider = 1, float slidermin = 0.0, float slidermax = 10.0, float slidercenter = 1.0,
344 | string help =
345 | "An overall Scale applied to all the Input Float "
346 | "and Vector Magnitudes. "
347 | ]],
348 |
349 | // Float displacements.
350 | normal Displacement_Float_Nn = normal(0.0)
351 | [[
352 | string page = "Displacement.Float",
353 | string label = "Nn",
354 | string help =
355 | "Use this common space surface normal for the Float displacement "
356 | "directions. Defaults to the surface normal N if left un-connected. "
357 | "
"
358 | "Note: this must be connected to set it: "
359 | "manually entering values will not work. "
360 | ]],
361 |
362 | DISPLACE_FLOAT_UI_DECLARE(0),
363 | DISPLACE_FLOAT_UI_DECLARE(1),
364 | DISPLACE_FLOAT_UI_DECLARE(2),
365 | DISPLACE_FLOAT_UI_DECLARE(3),
366 | DISPLACE_FLOAT_UI_DECLARE(4),
367 |
368 | // Vector displacements.
369 | string Displacement_Vector_DirSpace = "Mag Space Value"
370 | [[
371 | int connectable = 0,
372 | string page = "Displacement.Vector",
373 | string label = "Dir Space",
374 | string widget = "popup", int editable = 1,
375 | string options = "Mag Space Value|common|world|object",
376 | string help =
377 | "The coordinate system in which the Vector Input Directions are specified. "
378 | "You may also enter the name of your own coordinate system. "
379 | "
"
380 | "Note: it is assumed the Input vectors have a maximum length of 1. "
381 | "Mag Space and Magnitude therefore determine their "
382 | "amount of displacement. "
383 | "
"
384 | "Dir Space however, specifies their orientation (direction): "
385 | "vector direction and magnitude are separate characteristics. "
386 | ]],
387 |
388 | DISPLACE_VECTOR_UI_DECLARE(0),
389 | DISPLACE_VECTOR_UI_DECLARE(1),
390 | DISPLACE_VECTOR_UI_DECLARE(2),
391 | DISPLACE_VECTOR_UI_DECLARE(3),
392 | DISPLACE_VECTOR_UI_DECLARE(4),
393 |
394 | // Utility socket.
395 | int Socket = 0
396 | [[
397 | string help =
398 | "Connect a shading node's Plug output here in order to execute that node and "
399 | "any shading tree connected to it. "
400 | ]],
401 |
402 | /*
403 | * The Output Material data set.
404 | *
405 | * This consists of a vstruct parameter, a material struct parameter, and a set
406 | * of enable parameters for each response. The material struct and response enable
407 | * parameters are members of the vstruct parameter.
408 | */
409 | output PXRSURFACE_MATERIAL_VSTRUCT( MaterialOutput, Material Output,
410 | Connect this to another v2_PxrSurface material shader's Material Input
411 | to layer this OVER it.
412 |
413 | If this is the last in the material layering chain - connect it to a
414 | v2_PxrSurfaceAdapter node.
415 | ),
416 |
417 | // The struct parameter.
418 | output PXRSURFACE_MATERIAL_STRUCT( MaterialOutput, MatOut ),
419 |
420 | // Set the output vstruct Enable parameters based on the input Enable value and user parameter settings.
421 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, ClearCoat ),
422 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, PrimarySpecular ),
423 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, SecondarySpecular ),
424 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
425 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
426 | SET_ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
427 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Fuzz ),
428 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Fuzz ),
429 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Diffuse ),
430 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Diffuse ),
431 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Scatter ),
432 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Subsurface ),
433 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
434 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
435 | SET_ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
436 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Glow )
437 | )
438 | /*
439 | * Material functionality: Output = Input OVER this.
440 | */
441 | {
442 | // Pull on the Socket to make sure it's evaluated.
443 | MatOut.socket = Socket;
444 |
445 | // Short-circuit this material.
446 | if( Enable == 0 )
447 | {
448 | MatOut = MatIn;
449 | }
450 |
451 | // Note: using a return statement in the if case above breaks functionality,
452 | // so must use this else clause.
453 | // My guess is the osl optimizer is mucking with the proper behavior.
454 | else
455 | {
456 |
457 | // Max of all active material Mask values.
458 | MatOut.maxMask = max( Mask, MatIn.maxMask );
459 |
460 | // Initialize this material's mask values.
461 | float bxdfMask = Mask; // this_bxdfMask
462 | float dispMask = Mask; // this_dispMask
463 |
464 | //
465 | // Displacement.
466 | //
467 | vector this_deltaP;
468 | vector this_coverV;
469 |
470 | // The covering height surface offset vector for this material.
471 | // Nmag is common space direction with length relative to Mag Space.
472 | // Note: must use a normal transform to get the proper scale.
473 | normal Nn = normalize(N);
474 | normal Nmag = Nn * length( transform( "common", Displacement_MagSpace, Nn )); // normal
475 |
476 | this_coverV = Nmag * Displacement_CoveringHeight;
477 |
478 | // Float displacements.
479 | if( isconnected( Displacement_Float_Nn ))
480 | {
481 | Nn = Displacement_Float_Nn;
482 | Nmag = Nn * length( transform( "common", Displacement_MagSpace, Nn )); // normal
483 | }
484 |
485 | // Add float displacements to the deltaP displacement vector.
486 | float floatDisp = DISPLACE_FLOAT_AMOUNT(0)
487 | + DISPLACE_FLOAT_AMOUNT(1)
488 | + DISPLACE_FLOAT_AMOUNT(2)
489 | + DISPLACE_FLOAT_AMOUNT(3)
490 | + DISPLACE_FLOAT_AMOUNT(4);
491 |
492 | this_deltaP = Nmag * floatDisp;
493 |
494 | // Vector displacements.
495 | // Magnitude and Direction are handled separately.
496 | string directionSpace = ( Displacement_Vector_DirSpace != "Mag Space Value" )
497 | ? Displacement_Vector_DirSpace : Displacement_MagSpace;
498 |
499 | // Add vector displacements to the deltaP displacement vector.
500 | vector vectorDisp = DISPLACE_VECTOR_AMOUNT( 0, directionSpace, Displacement_MagSpace )
501 | + DISPLACE_VECTOR_AMOUNT( 1, directionSpace, Displacement_MagSpace )
502 | + DISPLACE_VECTOR_AMOUNT( 2, directionSpace, Displacement_MagSpace )
503 | + DISPLACE_VECTOR_AMOUNT( 3, directionSpace, Displacement_MagSpace )
504 | + DISPLACE_VECTOR_AMOUNT( 4, directionSpace, Displacement_MagSpace );
505 |
506 | this_deltaP += vectorDisp;
507 |
508 | // Globally scale the displacement. Displacement_MagScale is unitless.
509 | this_deltaP *= Displacement_MagScale;
510 |
511 | // Pre-multiply by the displacement mask.
512 | this_deltaP *= dispMask;
513 | this_coverV *= dispMask;
514 |
515 | // Note: coverV is not composited. It is only communicated
516 | // with the immediately overlying material layer.
517 | MatOut.coverV = this_coverV;
518 |
519 | // Displacement compositing.
520 | // Note: displacement is NOT Porter-Duff OVER operation composited.
521 | MatOut.deltaP = MatIn.deltaP + mix(
522 | this_deltaP,
523 | this_coverV,
524 | MatIn.thickness
525 | );
526 |
527 | // Thickness accumulates through all the layers, since layer displacements all accumulate.
528 | // Any overlying layer's thickness will apply to all layers below it, so always pass on the
529 | // largest thickness value.
530 | MatOut.thickness = max( MatIn.thickness, Displacement_Thickness*dispMask );
531 |
532 | // Composite the dispMask.
533 | MatOut.dispMask = MatIn.dispMask + dispMask*( 1.0 - MatIn.dispMask );
534 |
535 |
536 | //
537 | // Bxdf shader parameters start here.
538 | // Note: Gain = 1.0, and Color = Gain*Color. This eliminates false
539 | // colors resulting from interpolating these parameters separately.
540 | //
541 | // Porter-Duff pre-multiplied alpha(mask) compositing OVER operation.
542 | // Out = In over Ui:
543 | // Out = In*In_Mask*1 + Ui*Ui_Mask*(1 - In_Mask)
544 | // Out_Mask = In_Mask*1 + Ui_Mask*(1 - In_Mask)
545 | //
546 | // Composited output mask defines where the input material and this material exist.
547 | MatOut.bxdfMask = MatIn.bxdfMask + bxdfMask*( 1.0 - MatIn.bxdfMask );
548 |
549 | PARAM_OVER( MatOut, MatIn, Displacement, BumpPercent, bxdfMask );
550 | PARAM_OVER( MatOut, MatIn, Global, ShadowColor, bxdfMask );
551 | PARAM_OVER( MatOut, MatIn, Global, UserColor, bxdfMask );
552 | PARAM_OVER( MatOut, MatIn, Global, ShadingNormal, bxdfMask );
553 |
554 | // This material's Global_UseShadingNormal value is 0 if its Global_ShadingNormal is not connected.
555 | float useShadingNormal = isconnected( Global_ShadingNormal ) ? Global_UseShadingNormal : 0.0;
556 | MatOut.Global_UseShadingNormal = MatIn.Global_UseShadingNormal
557 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
558 |
559 | // ClearCoat
560 | if( ClearCoat_Enable )
561 | {
562 | MatOut.ClearCoat_CG = MatIn.ClearCoat_CG
563 | + ( ClearCoat_Gain*ClearCoat_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
564 |
565 | MatOut.ClearCoat_FaceCG = MatIn.ClearCoat_FaceCG
566 | + ( ClearCoat_Gain*ClearCoat_FaceColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
567 |
568 | MatOut.ClearCoat_RefractionCI = MatIn.ClearCoat_RefractionCI
569 | + ( ClearCoat_RefractionIndex*ClearCoat_RefractionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
570 |
571 | PARAM_OVER( MatOut, MatIn, ClearCoat, FresnelExponent, bxdfMask );
572 | PARAM_OVER( MatOut, MatIn, ClearCoat, LayerThickness, bxdfMask );
573 | PARAM_OVER( MatOut, MatIn, ClearCoat, LayerColor, bxdfMask );
574 | PARAM_OVER( MatOut, MatIn, ClearCoat, Roughness, bxdfMask );
575 | PARAM_OVER( MatOut, MatIn, ClearCoat, Anisotropy, bxdfMask );
576 | PARAM_OVER( MatOut, MatIn, ClearCoat, AnisotropyDirection, bxdfMask );
577 | PARAM_OVER( MatOut, MatIn, ClearCoat, ShadingNormal, bxdfMask );
578 |
579 | float useAnisotropyDirection = isconnected( ClearCoat_AnisotropyDirection ) ? 1.0 : 0.0;
580 | MatOut.ClearCoat_UseAnisotropyDirection = MatIn.ClearCoat_UseAnisotropyDirection
581 | + useAnisotropyDirection*bxdfMask*( 1.0 - MatIn.bxdfMask );
582 |
583 | float useShadingNormal = isconnected( ClearCoat_ShadingNormal ) ? ClearCoat_UseShadingNormal : 0.0;
584 | MatOut.ClearCoat_UseShadingNormal = MatIn.ClearCoat_UseShadingNormal
585 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
586 | }
587 | else
588 | {
589 | CLEARCOAT_COPY( MatOut, MatIn, ClearCoat );
590 | }
591 |
592 | // PrimarySpecular
593 | if( PrimarySpecular_Enable )
594 | {
595 | MatOut.PrimarySpecular_CG = MatIn.PrimarySpecular_CG
596 | + ( PrimarySpecular_Gain*PrimarySpecular_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
597 |
598 | MatOut.PrimarySpecular_FaceCG = MatIn.PrimarySpecular_FaceCG
599 | + ( PrimarySpecular_Gain*PrimarySpecular_FaceColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
600 |
601 | MatOut.PrimarySpecular_RefractionCI = MatIn.PrimarySpecular_RefractionCI
602 | + ( PrimarySpecular_RefractionIndex*PrimarySpecular_RefractionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
603 |
604 | MatOut.PrimarySpecular_ExtinctionCC = MatIn.PrimarySpecular_ExtinctionCC
605 | + ( PrimarySpecular_ExtinctionCoeff*PrimarySpecular_ExtinctionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
606 |
607 | PARAM_OVER( MatOut, MatIn, PrimarySpecular, FresnelExponent, bxdfMask );
608 | PARAM_OVER( MatOut, MatIn, PrimarySpecular, Roughness, bxdfMask );
609 | PARAM_OVER( MatOut, MatIn, PrimarySpecular, Anisotropy, bxdfMask );
610 | PARAM_OVER( MatOut, MatIn, PrimarySpecular, AnisotropyDirection, bxdfMask );
611 | PARAM_OVER( MatOut, MatIn, PrimarySpecular, ShadingNormal, bxdfMask );
612 |
613 | float useAnisotropyDirection = isconnected( PrimarySpecular_AnisotropyDirection ) ? 1.0 : 0.0;
614 | MatOut.PrimarySpecular_UseAnisotropyDirection = MatIn.PrimarySpecular_UseAnisotropyDirection
615 | + useAnisotropyDirection*bxdfMask*( 1.0 - MatIn.bxdfMask );
616 |
617 | float useShadingNormal = isconnected( PrimarySpecular_ShadingNormal ) ? PrimarySpecular_UseShadingNormal : 0.0;
618 | MatOut.PrimarySpecular_UseShadingNormal = MatIn.PrimarySpecular_UseShadingNormal
619 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
620 | }
621 | else
622 | {
623 | SPECULAR_COPY( MatOut, MatIn, PrimarySpecular );
624 | }
625 |
626 | // SecondarySpecular
627 | if( SecondarySpecular_Enable )
628 | {
629 | MatOut.SecondarySpecular_CG = MatIn.SecondarySpecular_CG
630 | + ( SecondarySpecular_Gain*SecondarySpecular_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
631 |
632 | MatOut.SecondarySpecular_FaceCG = MatIn.SecondarySpecular_FaceCG
633 | + ( SecondarySpecular_Gain*SecondarySpecular_FaceColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
634 |
635 | MatOut.SecondarySpecular_RefractionCI = MatIn.SecondarySpecular_RefractionCI
636 | + ( SecondarySpecular_RefractionIndex*SecondarySpecular_RefractionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
637 |
638 | MatOut.SecondarySpecular_ExtinctionCC = MatIn.SecondarySpecular_ExtinctionCC
639 | + ( SecondarySpecular_ExtinctionCoeff*SecondarySpecular_ExtinctionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
640 |
641 | PARAM_OVER( MatOut, MatIn, SecondarySpecular, FresnelExponent, bxdfMask );
642 | PARAM_OVER( MatOut, MatIn, SecondarySpecular, Roughness, bxdfMask );
643 | PARAM_OVER( MatOut, MatIn, SecondarySpecular, Anisotropy, bxdfMask );
644 | PARAM_OVER( MatOut, MatIn, SecondarySpecular, AnisotropyDirection, bxdfMask );
645 | PARAM_OVER( MatOut, MatIn, SecondarySpecular, ShadingNormal, bxdfMask );
646 |
647 | float useAnisotropyDirection = isconnected( SecondarySpecular_AnisotropyDirection ) ? 1.0 : 0.0;
648 | MatOut.SecondarySpecular_UseAnisotropyDirection = MatIn.SecondarySpecular_UseAnisotropyDirection
649 | + useAnisotropyDirection*bxdfMask*( 1.0 - MatIn.bxdfMask );
650 |
651 | float useShadingNormal = isconnected( SecondarySpecular_ShadingNormal ) ? SecondarySpecular_UseShadingNormal : 0.0;
652 | MatOut.SecondarySpecular_UseShadingNormal = MatIn.SecondarySpecular_UseShadingNormal
653 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
654 | }
655 | else
656 | {
657 | SPECULAR_COPY( MatOut, MatIn, SecondarySpecular );
658 | }
659 |
660 | // Iridescence
661 | if( Iridescence_Enable )
662 | {
663 | PARAM_OVER( MatOut, MatIn, Iridescence, Gain, bxdfMask );
664 | PARAM_OVER( MatOut, MatIn, Iridescence, FaceColor, bxdfMask );
665 | PARAM_OVER( MatOut, MatIn, Iridescence, EdgeColor, bxdfMask );
666 | PARAM_OVER( MatOut, MatIn, Iridescence, Exponent, bxdfMask );
667 | PARAM_OVER( MatOut, MatIn, Iridescence, Repetitions, bxdfMask );
668 | PARAM_OVER( MatOut, MatIn, Iridescence, Thickness, bxdfMask );
669 | PARAM_OVER( MatOut, MatIn, Iridescence, Roughness, bxdfMask );
670 | PARAM_OVER( MatOut, MatIn, Iridescence, Anisotropy, bxdfMask );
671 | PARAM_OVER( MatOut, MatIn, Iridescence, AnisotropyDirection, bxdfMask );
672 | PARAM_OVER( MatOut, MatIn, Iridescence, ShadingNormal, bxdfMask );
673 |
674 | float useAnisotropyDirection = isconnected( Iridescence_AnisotropyDirection ) ? 1.0 : 0.0;
675 | MatOut.Iridescence_UseAnisotropyDirection = MatIn.Iridescence_UseAnisotropyDirection
676 | + useAnisotropyDirection*bxdfMask*( 1.0 - MatIn.bxdfMask );
677 |
678 | float useShadingNormal = isconnected( Iridescence_ShadingNormal ) ? Iridescence_UseShadingNormal : 0.0;
679 | MatOut.Iridescence_UseShadingNormal = MatIn.Iridescence_UseShadingNormal
680 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
681 | }
682 | else
683 | {
684 | IRIDESCENCE_COPY( MatOut, MatIn, Iridescence );
685 | }
686 |
687 | // Fuzz
688 | if( Fuzz_Enable )
689 | {
690 | MatOut.Fuzz_CG = MatIn.Fuzz_CG
691 | + ( Fuzz_Gain*Fuzz_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
692 |
693 | PARAM_OVER( MatOut, MatIn, Fuzz, ConeAngle, bxdfMask );
694 | PARAM_OVER( MatOut, MatIn, Fuzz, ShadingNormal, bxdfMask );
695 |
696 | float useShadingNormal = isconnected( Fuzz_ShadingNormal ) ? Fuzz_UseShadingNormal : 0.0;
697 | MatOut.Fuzz_UseShadingNormal = MatIn.Fuzz_UseShadingNormal
698 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
699 | }
700 | else
701 | {
702 | FUZZ_COPY( MatOut, MatIn, Fuzz );
703 | }
704 |
705 | // Diffuse
706 | if( Diffuse_Enable )
707 | {
708 | MatOut.Diffuse_CG = MatIn.Diffuse_CG
709 | + ( Diffuse_Gain*Diffuse_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
710 |
711 | MatOut.Diffuse_BackfaceCG = MatIn.Diffuse_BackfaceCG
712 | + ( Diffuse_BackfaceGain*Diffuse_BackfaceColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
713 |
714 | MatOut.Diffuse_TransmitCG = MatIn.Diffuse_TransmitCG
715 | + ( Diffuse_TransmitGain*Diffuse_TransmitColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
716 |
717 | PARAM_OVER( MatOut, MatIn, Diffuse, Roughness, bxdfMask );
718 | PARAM_OVER( MatOut, MatIn, Diffuse, Exponent, bxdfMask );
719 | PARAM_OVER( MatOut, MatIn, Diffuse, ShadingNormal, bxdfMask );
720 |
721 | float useShadingNormal = isconnected( Diffuse_ShadingNormal ) ? Diffuse_UseShadingNormal : 0.0;
722 | MatOut.Diffuse_UseShadingNormal = MatIn.Diffuse_UseShadingNormal
723 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
724 | }
725 | else
726 | {
727 | DIFFUSE_COPY( MatOut, MatIn, Diffuse );
728 | }
729 |
730 | // Scatter
731 | if( Scatter_Enable )
732 | {
733 | MatOut.Scatter_CG = MatIn.Scatter_CG
734 | + ( Scatter_Gain*Scatter_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
735 |
736 | // Backside_CG = (Backside) IlluminationGain * (Backside) IlluminationTint
737 | MatOut.Scatter_BacksideCG = MatIn.Scatter_BacksideCG
738 | + ( Scatter_IlluminationGain*Scatter_IlluminationTint*bxdfMask )*( 1.0 - MatIn.bxdfMask );
739 |
740 | PARAM_OVER( MatOut, MatIn, Scatter, PathLength, bxdfMask );
741 | PARAM_OVER( MatOut, MatIn, Scatter, PathColor, bxdfMask );
742 | PARAM_OVER( MatOut, MatIn, Scatter, Direction, bxdfMask );
743 | PARAM_OVER( MatOut, MatIn, Scatter, Roughness, bxdfMask );
744 | PARAM_OVER( MatOut, MatIn, Scatter, RefractionIndex, bxdfMask );
745 | }
746 | else
747 | {
748 | SCATTER_COPY( MatOut, MatIn, Scatter );
749 | }
750 |
751 | // Subsurface
752 | if( Subsurface_Enable )
753 | {
754 | PARAM_OVER( MatOut, MatIn, Subsurface, Gain, bxdfMask );
755 | PARAM_OVER( MatOut, MatIn, Subsurface, Color, bxdfMask );
756 | PARAM_OVER( MatOut, MatIn, Subsurface, PathLength, bxdfMask );
757 | PARAM_OVER( MatOut, MatIn, Subsurface, PathColor, bxdfMask );
758 | PARAM_OVER( MatOut, MatIn, Subsurface, PostTint, bxdfMask );
759 | PARAM_OVER( MatOut, MatIn, Subsurface, TransmitGain, bxdfMask );
760 | PARAM_OVER( MatOut, MatIn, Subsurface, ShortGain, bxdfMask );
761 | PARAM_OVER( MatOut, MatIn, Subsurface, ShortColor, bxdfMask );
762 | PARAM_OVER( MatOut, MatIn, Subsurface, ShortLength, bxdfMask );
763 | PARAM_OVER( MatOut, MatIn, Subsurface, LongGain, bxdfMask );
764 | PARAM_OVER( MatOut, MatIn, Subsurface, LongColor, bxdfMask );
765 | PARAM_OVER( MatOut, MatIn, Subsurface, LongLength, bxdfMask );
766 | PARAM_OVER( MatOut, MatIn, Subsurface, Directionality, bxdfMask );
767 | // XXX PARAM_OVER( MatOut, MatIn, Subsurface, DiffuseBlend, bxdfMask );
768 | PARAM_OVER( MatOut, MatIn, Subsurface, Bleed, bxdfMask );
769 | }
770 | else
771 | {
772 | SUBSURFACE_COPY( MatOut, MatIn, Subsurface );
773 | }
774 |
775 | // Scatter & Subsurface
776 | if( Scatter_Enable || Subsurface_Enable )
777 | {
778 | PARAM_OVER( MatOut, MatIn, ScatterAndSubsurface, IlluminationTint, bxdfMask );
779 | PARAM_OVER( MatOut, MatIn, ScatterAndSubsurface, Roughness, bxdfMask );
780 | }
781 | else
782 | {
783 | MatOut.ScatterAndSubsurface_IlluminationTint = MatIn.ScatterAndSubsurface_IlluminationTint;
784 | MatOut.ScatterAndSubsurface_Roughness = MatIn.ScatterAndSubsurface_Roughness;
785 | }
786 |
787 | // Glass
788 | if( Glass_Enable )
789 | {
790 | PARAM_OVER( MatOut, MatIn, Glass, ReflectionGain, bxdfMask );
791 | PARAM_OVER( MatOut, MatIn, Glass, Roughness, bxdfMask );
792 | PARAM_OVER( MatOut, MatIn, Glass, Anisotropy, bxdfMask );
793 | PARAM_OVER( MatOut, MatIn, Glass, AnisotropyDirection, bxdfMask );
794 | PARAM_OVER( MatOut, MatIn, Glass, ShadingNormal, bxdfMask );
795 |
796 | float useAnisotropyDirection = isconnected( Glass_AnisotropyDirection ) ? 1.0 : 0.0;
797 | MatOut.Glass_UseAnisotropyDirection = MatIn.Glass_UseAnisotropyDirection
798 | + useAnisotropyDirection*bxdfMask*( 1.0 - MatIn.bxdfMask );
799 |
800 | float useShadingNormal = isconnected( Glass_ShadingNormal ) ? Glass_UseShadingNormal : 0.0;
801 | MatOut.Glass_UseShadingNormal = MatIn.Glass_UseShadingNormal
802 | + useShadingNormal*bxdfMask*( 1.0 - MatIn.bxdfMask );
803 |
804 | // Refraction.
805 | MatOut.Glass_RefractionCG = MatIn.Glass_RefractionCG
806 | + ( Glass_RefractionGain*Glass_RefractionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
807 |
808 | MatOut.Glass_ExtinctionCC = MatIn.Glass_ExtinctionCC
809 | + ( Glass_ExtinctionCoeff*Glass_ExtinctionColor*bxdfMask )*( 1.0 - MatIn.bxdfMask );
810 |
811 | PARAM_OVER( MatOut, MatIn, Glass, RefractionIndex, bxdfMask );
812 | PARAM_OVER( MatOut, MatIn, Glass, ScatterColor, bxdfMask );
813 | PARAM_OVER( MatOut, MatIn, Glass, ManifoldExplorationIOR, bxdfMask );
814 | }
815 | else
816 | {
817 | GLASS_COPY( MatOut, MatIn, Glass );
818 | }
819 |
820 | // Glow
821 | if( Glow_Enable )
822 | {
823 | MatOut.Glow_CG = MatIn.Glow_CG
824 | + ( Glow_Gain*Glow_Color*bxdfMask )*( 1.0 - MatIn.bxdfMask );
825 | }
826 | else
827 | {
828 | GLOW_COPY( MatOut, MatIn, Glow );
829 | }
830 |
831 | // This bxdfMask is only where this material is.
832 | bxdfMask = bxdfMask*( 1.0 - MatIn.bxdfMask );
833 |
834 | }
835 | }
836 |
--------------------------------------------------------------------------------
/osl/material/v2_PxrSurfaceAdapter.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2020 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | /*
10 | Defines the vstruct connection made with the PxrSurface bxdf.
11 | */
12 | #ifndef MATERIAL_V2_PXRSURFACEADAPTOR_H
13 | #define MATERIAL_V2_PXRSURFACEADAPTOR_H
14 |
15 | #include "material/v2_PxrSurface.h"
16 |
17 |
18 | //
19 | // Copy input struct member to the corresponding output parameter.
20 | //
21 | #define COPY_PARAM(VSTRUCTIN,PREFIX,NAME) \
22 | PREFIX##_##NAME = VSTRUCTIN.PREFIX##_##NAME
23 |
24 | /**************************************************************************************************
25 | * vstruct Output Parameters
26 | **************************************************************************************************/
27 |
28 | //
29 | // These macros examine the vstruct Enable parameters to determine what is connected
30 | // to the bxdf node.
31 | //
32 | #define PARAM_OUTPUT(VSTRUCTIN,VSTRUCTOUT,PREFIX,TYPE,PARAM,VSTRUCTMEMBER) \
33 | output TYPE PREFIX##_##PARAM = TYPE(0.0) \
34 | [[ \
35 | string widget = "null", \
36 | string vstructmember = #VSTRUCTOUT "." #VSTRUCTMEMBER, \
37 | string vstructConditionalExpr = "connect if " #VSTRUCTIN "_" #PREFIX "_Enable == 1" \
38 | ]]
39 |
40 | #define PARAM_OUTPUT_ENABLE(VSTRUCTIN,VSTRUCTOUT,PREFIX,TYPE,PARAM,VSTRUCTMEMBER) \
41 | output TYPE PREFIX##_##PARAM = TYPE(0.0) \
42 | [[ \
43 | string widget = "null", \
44 | string vstructmember = #VSTRUCTOUT "." #VSTRUCTMEMBER, \
45 | string vstructConditionalExpr = "connect if " #VSTRUCTIN "_" #PREFIX "_" #PARAM "_Enable == 1" \
46 | ]]
47 |
48 | //
49 | // Gain parameters are set to 1 or 0 depending on whether the response is enabled or not.
50 | // Their corresponding color value is used to control the actual response intensity.
51 | // This is done to avoid hue aliasing when two material layers are blended and one has
52 | // a low gain value.
53 | //
54 | #define PARAM_OUTPUT_SET_GAIN(VSTRUCTIN,VSTRUCTOUT,PREFIX,PARAM,VSTRUCTMEMBER) \
55 | output float PREFIX##_##PARAM = 0.0 \
56 | [[ \
57 | string widget = "null", \
58 | string vstructmember = #VSTRUCTOUT "." #VSTRUCTMEMBER, \
59 | string vstructConditionalExpr = "set 1.0 if " #VSTRUCTIN "_" #PREFIX "_Enable == 1 else set 0.0" \
60 | ]]
61 |
62 |
63 | #define CLEARCOAT_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
64 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, clearcoatEdgeColor ), \
65 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, FaceCG, clearcoatFaceColor ), \
66 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, FresnelExponent, clearcoatFresnelShape ), \
67 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, RefractionCI, clearcoatIor ), \
68 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, LayerThickness, clearcoatThickness ), \
69 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, LayerColor, clearcoatAborptionTint ), \
70 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, clearcoatRoughness ), \
71 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Anisotropy, clearcoatAnisotropy ), \
72 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, clearcoatBumpNormal ), \
73 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, vector, AnisotropyDirection, clearcoatAnisotropyDirection )
74 |
75 | #define PRIMARYSPECULAR_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
76 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, specularEdgeColor ), \
77 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, FaceCG, specularFaceColor ), \
78 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, FresnelExponent, specularFresnelShape ), \
79 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, RefractionCI, specularIor ), \
80 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, ExtinctionCC, specularExtinctionCoeff ), \
81 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, specularRoughness ), \
82 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Anisotropy, specularAnisotropy ), \
83 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, specularBumpNormal ), \
84 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, vector, AnisotropyDirection, specularAnisotropyDirection )
85 |
86 | #define SECONDARYSPECULAR_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
87 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, roughSpecularEdgeColor ), \
88 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, FaceCG, roughSpecularFaceColor ), \
89 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, FresnelExponent, roughSpecularFresnelShape ), \
90 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, RefractionCI, roughSpecularIor ), \
91 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, ExtinctionCC, roughSpecularExtinctionCoeff ), \
92 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, roughSpecularRoughness ), \
93 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Anisotropy, roughSpecularAnisotropy ), \
94 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, roughSpecularBumpNormal ), \
95 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, vector, AnisotropyDirection, roughSpecularAnisotropyDirection )
96 |
97 | #define IRIDESCENCE_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
98 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, FaceGain, iridescenceFaceGain ), \
99 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, EdgeGain, iridescenceEdgeGain ), \
100 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, FaceColor, iridescencePrimaryColor ), \
101 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, EdgeColor, iridescenceSecondaryColor ), \
102 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Exponent, iridescenceCurve ), \
103 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Repetitions, iridescenceScale ), \
104 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Thickness, iridescenceThickness ), \
105 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, iridescenceRoughness ), \
106 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Anisotropy, iridescenceAnisotropy ), \
107 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, iridescenceBumpNormal ), \
108 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, vector, AnisotropyDirection, iridescenceAnisotropyDirection )
109 |
110 | #define FUZZ_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
111 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, Gain, fuzzGain ), \
112 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, fuzzColor ), \
113 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, ConeAngle, fuzzConeAngle ), \
114 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, fuzzBumpNormal )
115 |
116 | #define DIFFUSE_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
117 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, Gain, diffuseGain ), \
118 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, TransmitGain, diffuseTransmitGain ), \
119 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, diffuseBumpNormal ), \
120 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, diffuseColor ), \
121 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, diffuseRoughness ), \
122 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Exponent, diffuseExponent ), \
123 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, BackfaceCG, diffuseBackColor ), \
124 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, TransmitCG, diffuseTransmitColor )
125 |
126 | #define SCATTER_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
127 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, Gain, singlescatterGain ), \
128 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, DirectGain, singlescatterDirectGain ), \
129 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, singlescatterColor ), \
130 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, PathLength, singlescatterMfp ), \
131 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, PathColor, singlescatterMfpColor ), \
132 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Direction, singlescatterDirectionality ), \
133 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, singlescatterBlur ), \
134 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, RefractionIndex, singlescatterIor ), \
135 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, BacksideCG, singlescatterDirectGainTint )
136 |
137 | #define SUBSURFACE_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
138 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Gain, subsurfaceGain ), \
139 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, Color, subsurfaceColor ), \
140 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, PathLength, subsurfaceDmfp ), \
141 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, PathColor, subsurfaceDmfpColor ), \
142 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, PostTint, subsurfacePostTint ), \
143 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, TransmitGain, subsurfaceTransmitGain ), \
144 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, ShortGain, shortSubsurfaceGain ), \
145 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, ShortColor, shortSubsurfaceColor ), \
146 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, ShortLength, shortSubsurfaceDmfp ), \
147 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, LongGain, longSubsurfaceGain ), \
148 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, LongColor, longSubsurfaceColor ), \
149 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, LongLength, longSubsurfaceDmfp ), \
150 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Directionality, subsurfaceDirectionality ), \
151 | /* XXX Not Really Connectable! PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, DiffuseBlend, subsurfaceDiffuseBlend ), */ \
152 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Bleed, subsurfaceBleed )
153 |
154 | #define GLASS_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
155 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, Gain, refractionGain ), \
156 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, ReflectionGain, reflectionGain ), \
157 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Roughness, glassRoughness ), \
158 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, Anisotropy, glassAnisotropy ), \
159 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, RefractionCG, refractionColor ), \
160 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, RefractionIndex, glassIor ), \
161 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, float, ManifoldExplorationIOR, mwIor ), \
162 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, normal, ShadingNormal, glassBumpNormal ), \
163 | PARAM_OUTPUT_ENABLE( VSTRUCTIN, VSTRUCTOUT, PREFIX, vector, AnisotropyDirection, glassAnisotropyDirection ), \
164 | \
165 | /* No vstructmember for ssAlbedo parameter in PxrSurface.args */ \
166 | output color PREFIX##_ssAlbedo = color(0.0) [[ string widget = "null" ]], \
167 | \
168 | /* No vstructmember for extinction parameter in PxrSurface.args */ \
169 | output color PREFIX##_extinction = color(0.0) [[ string widget = "null" ]]
170 |
171 | #define GLOW_OUTPUT_PARAMS(VSTRUCTIN,VSTRUCTOUT,PREFIX) \
172 | PARAM_OUTPUT_SET_GAIN( VSTRUCTIN, VSTRUCTOUT, PREFIX, Gain, glowGain ), \
173 | PARAM_OUTPUT( VSTRUCTIN, VSTRUCTOUT, PREFIX, color, CG, glowColor )
174 |
175 | #endif
176 |
--------------------------------------------------------------------------------
/osl/material/v2_PxrSurfaceAdapter.osl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2020 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | /*
10 | * This adapts the Material Output of a material shader to a
11 | * displacement and its corresponding bxdf shader's parameters:
12 | * PxrSurface in this case.
13 | */
14 | #include "ikaFunctions.h"
15 |
16 | #include "material/v2_PxrSurface.h"
17 | #include "material/v2_PxrSurfaceAdapter.h"
18 |
19 | shader v2_PxrSurfaceAdapter
20 | [[
21 | int rfm_nodeid = 1234036,
22 | string rfm_classification = "rendernode/RenderMan/pattern/material",
23 | string label = "PxrSurface Adapter",
24 | string help =
25 | "This adapts the Material Output of a v2_PxrSurface material "
26 | "to a SetP displacement shader and a PxrSurface bxdf's "
27 | "Input Material connection. "
28 | ]]
29 | (
30 | string Notes = ""
31 | [[
32 | int connectable = 0,
33 | string help =
34 | "This adapts the Material Output of a v2_PxrSurface material "
35 | "to a SetP displacement shader and a PxrSurface bxdf's "
36 | "Input Material connection. "
37 | ]],
38 |
39 | /*
40 | * The input material.
41 | */
42 | // The vstruct parameter. This is the single material connection point
43 | // for all the material parameters in the material struct.
44 | PXRSURFACE_MATERIAL_VSTRUCT( MaterialInput, Material Input,
45 | Connect a v2_PxrSurface Material shader's Material Output here.
46 | ),
47 |
48 | // The struct parameter.
49 | PXRSURFACE_MATERIAL_STRUCT( MaterialInput, MatIn ),
50 |
51 | // The Enable parameters.
52 | ALL_ENABLE_PARAMS( MaterialInput, ClearCoat ),
53 | ALL_ENABLE_PARAMS( MaterialInput, PrimarySpecular ),
54 | ALL_ENABLE_PARAMS( MaterialInput, SecondarySpecular ),
55 | RESPONSE_ENABLE_PARAM( MaterialInput, Iridescence ),
56 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Iridescence ),
57 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Iridescence ),
58 | RESPONSE_ENABLE_PARAM( MaterialInput, Fuzz ),
59 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Fuzz ),
60 | RESPONSE_ENABLE_PARAM( MaterialInput, Diffuse ),
61 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Diffuse ),
62 | RESPONSE_ENABLE_PARAM( MaterialInput, Scatter ),
63 | RESPONSE_ENABLE_PARAM( MaterialInput, Subsurface ),
64 | RESPONSE_ENABLE_PARAM( MaterialInput, Glass ),
65 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Glass ),
66 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Glass ),
67 | RESPONSE_ENABLE_PARAM( MaterialInput, Glow ),
68 |
69 |
70 | /*
71 | * This output Material vstruct is connected to a PxrSurface bxdf shader.
72 | */
73 | output float MaterialOutput = 0.0
74 | [[
75 | string label = "Material Output",
76 | string widget = "null",
77 | string tag = "vstruct",
78 | string help =
79 | "Connect this to a PxrSurface bxdf shader's Material Input. "
80 | ]],
81 |
82 | /*
83 | * Displaced P output.
84 | */
85 | output point out_P = point(0.0)
86 | [[
87 | string widget = "null",
88 | string tag = "point",
89 | string help =
90 | "This represents the displaced surface and is connected to a SetP displacement shader."
91 | ]],
92 |
93 | /*
94 | * Composited Mask outputs.
95 | */
96 | output float maxMask = 1.0 [[ string widget = "null" ]],
97 |
98 | /*
99 | * Utility Plug output.
100 | */
101 | output int Plug = 0 [[ string widget = "null" ]],
102 |
103 | /*
104 | * Output PxrSurface (vstruct) shader parameters start here.
105 | */
106 | output normal Global_ShadingNormal = normal( 0.0 )
107 | [[
108 | string widget = "null",
109 | string vstructmember = "MaterialOutput.bumpNormal"
110 | ]],
111 |
112 | output color Global_ShadowColor = color( 0.0 )
113 | [[
114 | string widget = "null",
115 | string vstructmember = "MaterialOutput.shadowColor"
116 | ]],
117 |
118 | // Clear Coat
119 | CLEARCOAT_OUTPUT_PARAMS( MaterialInput, MaterialOutput, ClearCoat ),
120 |
121 | // Primay Specular
122 | PRIMARYSPECULAR_OUTPUT_PARAMS( MaterialInput, MaterialOutput, PrimarySpecular ),
123 |
124 | // Secondary Specular
125 | SECONDARYSPECULAR_OUTPUT_PARAMS( MaterialInput, MaterialOutput, SecondarySpecular ),
126 |
127 | // Iridescence
128 | IRIDESCENCE_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Iridescence ),
129 |
130 | // Fuzz
131 | FUZZ_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Fuzz ),
132 |
133 | // Diffuse
134 | DIFFUSE_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Diffuse ),
135 |
136 | // Scatter
137 | SCATTER_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Scatter ),
138 |
139 | // Subsurface
140 | SUBSURFACE_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Subsurface ),
141 |
142 | // Scatter & Subsurface
143 | output color ScatterAndSubsurface_IlluminationTint = color( 1.0 )
144 | [[
145 | string widget = "null",
146 | string vstructmember = "MaterialOutput.irradianceTint",
147 | string vstructConditionalExpr = "connect if "
148 | "MaterialInput_Scatter_Enable == 1 or MaterialInput_Subsurface_Enable == 1"
149 | ]],
150 |
151 | output float ScatterAndSubsurface_Roughness = 0.0
152 | [[
153 | string widget = "null",
154 | string vstructmember = "MaterialOutput.irradianceRoughness",
155 | string vstructConditionalExpr = "connect if "
156 | "MaterialInput_Scatter_Enable == 1 or MaterialInput_Subsurface_Enable == 1"
157 | ]],
158 |
159 | // Glass
160 | GLASS_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Glass ),
161 |
162 | // Glow
163 | GLOW_OUTPUT_PARAMS( MaterialInput, MaterialOutput, Glow )
164 | )
165 | /*
166 | * Adapter functionality.
167 | * vstruct connections from the output parameters to the PxrSurface parameter vstructmembers
168 | * are specified in the output parameter declarations.
169 | */
170 | {
171 | Plug = MatIn.socket;
172 | maxMask = MatIn.maxMask;
173 |
174 | //
175 | // Displacement.
176 | //
177 | point Po;
178 | getattribute( "builtin", "Po", Po );
179 |
180 | out_P = Po + MatIn.deltaP;
181 |
182 |
183 | //
184 | // Bxdf responses.
185 | //
186 | // When enabled, simply copy the response's parameter values
187 | // to their corresponding vstruct output parameters.
188 | //
189 |
190 | // UVTangent default output.
191 | // When out_P has been connected to a displacement, Nn becomes the post-displacement normal.
192 | normal Nn = normalize( N );
193 | vector Tn, Bn;
194 | ikaCreateOrthonormalBasis( Nn, Tn, Bn );
195 |
196 | vector defaultAnisotropyDirection = Tn;
197 |
198 | // Always the un-displaced normal.
199 | normal Non;
200 | getattribute( "builtin", "Non", Non );
201 |
202 | vector deltaN = MatIn.Displacement_BumpPercent * vector( Nn - Non );
203 | normal bumpShadingNormal = normalize( Non + deltaN );
204 |
205 | // global Shading Normal -> PxrSurface BumpNormal.
206 | Global_ShadingNormal = normalize( mix(
207 | bumpShadingNormal,
208 | MatIn.Global_ShadingNormal,
209 | MatIn.Global_UseShadingNormal
210 | ));
211 | Global_ShadingNormal = ikaBumpCompensation( Global_ShadingNormal );
212 |
213 | // global ShadowColor -> PxrSurface ShadowColor.
214 | Global_ShadowColor = MatIn.Global_ShadowColor;
215 |
216 | // Clear Coat
217 | if( MaterialInput_ClearCoat_Enable )
218 | {
219 | COPY_PARAM( MatIn, ClearCoat, CG );
220 | COPY_PARAM( MatIn, ClearCoat, FaceCG );
221 | COPY_PARAM( MatIn, ClearCoat, FresnelExponent );
222 | COPY_PARAM( MatIn, ClearCoat, LayerThickness );
223 | COPY_PARAM( MatIn, ClearCoat, LayerColor );
224 | COPY_PARAM( MatIn, ClearCoat, Roughness );
225 | COPY_PARAM( MatIn, ClearCoat, Anisotropy );
226 |
227 | // Can't allow IOR to go below 1.
228 | ClearCoat_RefractionCI = ikaMax( 1.0, MatIn.ClearCoat_RefractionCI );
229 |
230 | ClearCoat_ShadingNormal = normalize( mix(
231 | Global_ShadingNormal,
232 | ikaBumpCompensation( MatIn.ClearCoat_ShadingNormal ),
233 | MatIn.ClearCoat_UseShadingNormal
234 | ));
235 |
236 | ClearCoat_AnisotropyDirection = mix(
237 | defaultAnisotropyDirection,
238 | MatIn.ClearCoat_AnisotropyDirection,
239 | MatIn.ClearCoat_UseAnisotropyDirection
240 | );
241 | }
242 |
243 | // Primary Specular
244 | if( MaterialInput_PrimarySpecular_Enable )
245 | {
246 | COPY_PARAM( MatIn, PrimarySpecular, CG );
247 | COPY_PARAM( MatIn, PrimarySpecular, FaceCG );
248 | COPY_PARAM( MatIn, PrimarySpecular, FresnelExponent );
249 | COPY_PARAM( MatIn, PrimarySpecular, ExtinctionCC );
250 | COPY_PARAM( MatIn, PrimarySpecular, Roughness );
251 | COPY_PARAM( MatIn, PrimarySpecular, Anisotropy );
252 |
253 | // Can't allow IOR to go below 1.
254 | PrimarySpecular_RefractionCI = ikaMax( 1.0, MatIn.PrimarySpecular_RefractionCI );
255 |
256 | PrimarySpecular_ShadingNormal = normalize( mix(
257 | Global_ShadingNormal,
258 | ikaBumpCompensation( MatIn.PrimarySpecular_ShadingNormal ),
259 | MatIn.PrimarySpecular_UseShadingNormal
260 | ));
261 |
262 | PrimarySpecular_AnisotropyDirection = mix(
263 | defaultAnisotropyDirection,
264 | MatIn.PrimarySpecular_AnisotropyDirection,
265 | MatIn.PrimarySpecular_UseAnisotropyDirection
266 | );
267 | }
268 |
269 | // Secondary Specular
270 | if( MaterialInput_SecondarySpecular_Enable )
271 | {
272 | COPY_PARAM( MatIn, SecondarySpecular, CG );
273 | COPY_PARAM( MatIn, SecondarySpecular, FaceCG );
274 | COPY_PARAM( MatIn, SecondarySpecular, FresnelExponent );
275 | COPY_PARAM( MatIn, SecondarySpecular, ExtinctionCC );
276 | COPY_PARAM( MatIn, SecondarySpecular, Roughness );
277 | COPY_PARAM( MatIn, SecondarySpecular, Anisotropy );
278 |
279 | // Can't allow IOR to go below 1.
280 | SecondarySpecular_RefractionCI = ikaMax( 1.0, MatIn.SecondarySpecular_RefractionCI );
281 |
282 | SecondarySpecular_ShadingNormal = normalize( mix(
283 | Global_ShadingNormal,
284 | ikaBumpCompensation( MatIn.SecondarySpecular_ShadingNormal ),
285 | MatIn.SecondarySpecular_UseShadingNormal
286 | ));
287 |
288 | SecondarySpecular_AnisotropyDirection = mix(
289 | defaultAnisotropyDirection,
290 | MatIn.SecondarySpecular_AnisotropyDirection,
291 | MatIn.SecondarySpecular_UseAnisotropyDirection
292 | );
293 | }
294 |
295 | // Iridescence
296 | if( MaterialInput_Iridescence_Enable )
297 | {
298 | Iridescence_FaceGain = MatIn.Iridescence_Gain;
299 | Iridescence_EdgeGain = MatIn.Iridescence_Gain;
300 |
301 | COPY_PARAM( MatIn, Iridescence, FaceColor );
302 | COPY_PARAM( MatIn, Iridescence, EdgeColor );
303 | COPY_PARAM( MatIn, Iridescence, Exponent );
304 | COPY_PARAM( MatIn, Iridescence, Repetitions );
305 | COPY_PARAM( MatIn, Iridescence, Thickness );
306 | COPY_PARAM( MatIn, Iridescence, Roughness );
307 | COPY_PARAM( MatIn, Iridescence, Anisotropy );
308 |
309 | Iridescence_ShadingNormal = normalize( mix(
310 | Global_ShadingNormal,
311 | MatIn.Iridescence_ShadingNormal,
312 | MatIn.Iridescence_UseShadingNormal
313 | ));
314 |
315 | Iridescence_AnisotropyDirection = mix(
316 | defaultAnisotropyDirection,
317 | MatIn.Iridescence_AnisotropyDirection,
318 | MatIn.Iridescence_UseAnisotropyDirection
319 | );
320 | }
321 |
322 | // Fuzz
323 | if( MaterialInput_Fuzz_Enable )
324 | {
325 | COPY_PARAM( MatIn, Fuzz, CG );
326 | COPY_PARAM( MatIn, Fuzz, ConeAngle );
327 |
328 | Fuzz_ShadingNormal = normalize( mix(
329 | Global_ShadingNormal,
330 | ikaBumpCompensation( MatIn.Fuzz_ShadingNormal ),
331 | MatIn.Fuzz_UseShadingNormal
332 | ));
333 | }
334 |
335 | // Diffuse
336 | if( MaterialInput_Diffuse_Enable )
337 | {
338 | COPY_PARAM( MatIn, Diffuse, CG );
339 | COPY_PARAM( MatIn, Diffuse, Roughness );
340 | COPY_PARAM( MatIn, Diffuse, Exponent );
341 | COPY_PARAM( MatIn, Diffuse, BackfaceCG );
342 | COPY_PARAM( MatIn, Diffuse, TransmitCG );
343 |
344 | Diffuse_ShadingNormal = normalize( mix(
345 | Global_ShadingNormal,
346 | ikaBumpCompensation( MatIn.Diffuse_ShadingNormal ),
347 | MatIn.Diffuse_UseShadingNormal
348 | ));
349 | }
350 |
351 | // Scatter
352 | if( MaterialInput_Scatter_Enable )
353 | {
354 | COPY_PARAM( MatIn, Scatter, CG );
355 | COPY_PARAM( MatIn, Scatter, PathLength );
356 | COPY_PARAM( MatIn, Scatter, PathColor );
357 | COPY_PARAM( MatIn, Scatter, Direction );
358 | COPY_PARAM( MatIn, Scatter, Roughness );
359 | COPY_PARAM( MatIn, Scatter, BacksideCG );
360 |
361 | // Can't allow IOR to go below 1.
362 | Scatter_RefractionIndex = max( 1.0, MatIn.Scatter_RefractionIndex );
363 | }
364 |
365 | // Subsurface
366 | if( MaterialInput_Subsurface_Enable )
367 | {
368 | COPY_PARAM( MatIn, Subsurface, Gain );
369 | COPY_PARAM( MatIn, Subsurface, Color );
370 | COPY_PARAM( MatIn, Subsurface, PathLength );
371 | COPY_PARAM( MatIn, Subsurface, PathColor );
372 | COPY_PARAM( MatIn, Subsurface, PostTint );
373 | COPY_PARAM( MatIn, Subsurface, TransmitGain );
374 | COPY_PARAM( MatIn, Subsurface, ShortGain );
375 | COPY_PARAM( MatIn, Subsurface, ShortColor );
376 | COPY_PARAM( MatIn, Subsurface, ShortLength );
377 | COPY_PARAM( MatIn, Subsurface, LongGain );
378 | COPY_PARAM( MatIn, Subsurface, LongColor );
379 | COPY_PARAM( MatIn, Subsurface, LongLength );
380 | COPY_PARAM( MatIn, Subsurface, Directionality );
381 | // XXX Not Really Connectable! COPY_PARAM( MatIn, Subsurface, DiffuseBlend );
382 | COPY_PARAM( MatIn, Subsurface, Bleed );
383 | }
384 |
385 | // Scatter & Subsurface
386 | if( MaterialInput_Scatter_Enable || MaterialInput_Subsurface_Enable )
387 | {
388 | COPY_PARAM( MatIn, ScatterAndSubsurface, IlluminationTint );
389 | COPY_PARAM( MatIn, ScatterAndSubsurface, Roughness );
390 | }
391 |
392 | // Glass
393 | if( MaterialInput_Glass_Enable )
394 | {
395 | COPY_PARAM( MatIn, Glass, ReflectionGain );
396 | COPY_PARAM( MatIn, Glass, Roughness );
397 | COPY_PARAM( MatIn, Glass, Anisotropy );
398 | COPY_PARAM( MatIn, Glass, RefractionCG );
399 | COPY_PARAM( MatIn, Glass, ManifoldExplorationIOR );
400 |
401 | Glass_ShadingNormal = normalize( mix(
402 | Global_ShadingNormal,
403 | ikaBumpCompensation( MatIn.Glass_ShadingNormal ),
404 | MatIn.Glass_UseShadingNormal
405 | ));
406 |
407 | Glass_AnisotropyDirection = mix(
408 | defaultAnisotropyDirection,
409 | MatIn.Glass_AnisotropyDirection,
410 | MatIn.Glass_UseAnisotropyDirection
411 | );
412 |
413 | // Can't allow GlassIor to go below 1.0.
414 | Glass_RefractionIndex = max( 1.0, MatIn.Glass_RefractionIndex );
415 |
416 | /* No vstructmember for ssAlbedo parameter in PxrSurface.args */
417 | Glass_ssAlbedo = MatIn.Glass_ScatterColor;
418 | /* No vstructmember for extinction parameter in PxrSurface.args */
419 | Glass_extinction = MatIn.Glass_ExtinctionCC;
420 | }
421 |
422 | // Glow
423 | if( MaterialInput_Glow_Enable )
424 | {
425 | COPY_PARAM( MatIn, Glow, CG );
426 | }
427 | }
428 |
--------------------------------------------------------------------------------
/osl/material/v2_PxrSurfaceModify.osl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2020 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | #include "material/v2_PxrSurface.h"
10 |
11 | shader v2_PxrSurfaceModify
12 | [[
13 | int rfm_nodeid = 1234052,
14 | string rfm_classification = "rendernode/RenderMan/pattern/material"
15 | ]]
16 | (
17 | string Notes = ""
18 | [[
19 | int connectable = 0,
20 | string help =
21 | "Modifies the Diffuse and Specular responses of a "
22 | "material_v2_PxrSurface. "
23 | ]],
24 |
25 | /*
26 | * The Input Material data set.
27 | *
28 | * This consists of a vstruct parameter, a material struct parameter, and a set
29 | * of enable parameters for each response. The material struct and response enable
30 | * parameters are members of the vstruct parameter.
31 | */
32 | // The vstruct parameter. This is the single material connection point
33 | // for all the material parameters in the material struct.
34 | PXRSURFACE_MATERIAL_VSTRUCT( MaterialInput, Material Input,
35 | The Material whose responses will be Modified.
36 | ),
37 |
38 | // The material struct parameter.
39 | PXRSURFACE_MATERIAL_STRUCT( MaterialInput, MatIn ),
40 |
41 | // The response Enable parameters. These are linked to a vstructmember of the vstruct parameter.
42 | ALL_ENABLE_PARAMS( MaterialInput, ClearCoat ),
43 | ALL_ENABLE_PARAMS( MaterialInput, PrimarySpecular ),
44 | ALL_ENABLE_PARAMS( MaterialInput, SecondarySpecular ),
45 | RESPONSE_ENABLE_PARAM( MaterialInput, Iridescence ),
46 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Iridescence ),
47 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Iridescence ),
48 | RESPONSE_ENABLE_PARAM( MaterialInput, Fuzz ),
49 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Fuzz ),
50 | RESPONSE_ENABLE_PARAM( MaterialInput, Diffuse ),
51 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Diffuse ),
52 | RESPONSE_ENABLE_PARAM( MaterialInput, Scatter ),
53 | RESPONSE_ENABLE_PARAM( MaterialInput, Subsurface ),
54 | RESPONSE_ENABLE_PARAM( MaterialInput, Glass ),
55 | SHADINGNORMAL_ENABLE_PARAM( MaterialInput, Glass ),
56 | ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialInput, Glass ),
57 | RESPONSE_ENABLE_PARAM( MaterialInput, Glow ),
58 |
59 | /*
60 | * This material's user interface parameters.
61 | */
62 | int Enable = 1
63 | [[
64 | int connectable = 0,
65 | string label = "Enable",
66 | string widget = "checkBox",
67 | string help =
68 | "Turns the modifications On/Off. "
69 | ]],
70 |
71 | float Mask = 1.0
72 | [[
73 | string label = "Mask",
74 | int slider = 1, float slidermin = 0.0, float slidermax = 1.0,
75 | string help =
76 | "Determines where the modifications will be applied. "
77 | ]],
78 |
79 | //
80 | // Specular Modifications.
81 | //
82 | float SpecularHue = 0.0
83 | [[
84 | string page = "Specular",
85 | string label = "Hue",
86 | int slider = 1, float slidermin = -0.5, float slidermax = 0.5,
87 | string help =
88 | "Shift the Hue by this amount. Hue is cyclical, so shifting by an integer "
89 | "amount causes no change. To invert the Hue, shift it by +/- .5. "
90 | ]],
91 |
92 | float SpecularSaturation = 1.0
93 | [[
94 | string page = "Specular",
95 | string label = "Saturation",
96 | int slider = 1, float slidermin = 0.0, float slidermax = 2.0,
97 | string help =
98 | "Scale the Saturation by this amount. "
99 | ]],
100 |
101 | float SpecularExposure = 0.0
102 | [[
103 | string page = "Specular",
104 | string label = "Exposure",
105 | int slider = 1, float slidermin = -4.0, float slidermax = 4.0,
106 | string help =
107 | "Adjust the Exposure by this amount. "
108 | ]],
109 |
110 | float SpecularGain = 1.0
111 | [[
112 | string page = "Specular",
113 | string label = "Gain",
114 | int slider = 1, float slidermin = 0.0, float slidermax = 2.0,
115 | string help =
116 | "Scale the Gain by this amount. "
117 | ]],
118 |
119 | color SpecularTint = color( 1.0 )
120 | [[
121 | string page = "Specular",
122 | string label = "Tint",
123 | string help =
124 | "Scale the color with this Tint. "
125 | ]],
126 |
127 | float SpecularRoughness = 0.0
128 | [[
129 | string page = "Specular",
130 | string label = "Roughness",
131 | int slider = 1, float slidermin = -1.0, float slidermax = 1.0,
132 | string help =
133 | "Modifies the material's Roughness values: "
134 | "
"
135 | "+ values increase Roughness. "
136 | "
"
137 | "- values decrease Roughness. "
138 | ]],
139 |
140 | //
141 | // Diffuse Modifications.
142 | //
143 | float DiffuseHue = 0.0
144 | [[
145 | string page = "Diffuse",
146 | string label = "Hue",
147 | int slider = 1, float slidermin = -0.5, float slidermax = 0.5,
148 | string help =
149 | "Shift the Hue by this amount. Hue is cyclical, so shifting by an integer "
150 | "amount causes no change. To invert the Hue, shift it by +/- .5. "
151 | ]],
152 |
153 | float DiffuseSaturation = 1.0
154 | [[
155 | string page = "Diffuse",
156 | string label = "Saturation",
157 | int slider = 1, float slidermin = 0.0, float slidermax = 2.0,
158 | string help =
159 | "Scale the Saturation by this amount. "
160 | ]],
161 |
162 | float DiffuseExposure = 0.0
163 | [[
164 | string page = "Diffuse",
165 | string label = "Exposure",
166 | int slider = 1, float slidermin = -4.0, float slidermax = 4.0,
167 | string help =
168 | "Adjust the Exposure by this amount. "
169 | ]],
170 |
171 | float DiffuseGain = 1.0
172 | [[
173 | string page = "Diffuse",
174 | string label = "Gain",
175 | int slider = 1, float slidermin = 0.0, float slidermax = 2.0,
176 | string help =
177 | "Scale the Gain by this amount. "
178 | ]],
179 |
180 | color DiffuseTint = color( 1.0 )
181 | [[
182 | string page = "Diffuse",
183 | string label = "Tint",
184 | string help =
185 | "Scale the color with this Tint. "
186 | ]],
187 |
188 | //
189 | // Utility socket.
190 | //
191 | int Socket = 0
192 | [[
193 | string help =
194 | "Connect a shading node's Plug output here in order to execute that node and "
195 | "any shading tree connected to it. "
196 | ]],
197 |
198 | /*
199 | * The Output Material data set.
200 | *
201 | * This consists of a vstruct parameter, a material struct parameter, and a set
202 | * of enable parameters for each response. The material struct and response enable
203 | * parameters are members of the vstruct parameter.
204 | */
205 | output PXRSURFACE_MATERIAL_VSTRUCT( MaterialOutput, Material Output,
206 | The modified Material.
207 | ),
208 |
209 | // The struct parameter.
210 | output PXRSURFACE_MATERIAL_STRUCT( MaterialOutput, MatOut ),
211 |
212 | // Set the output vstruct Enable parameters based on the input Enable value and user parameter settings.
213 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, ClearCoat ),
214 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, PrimarySpecular ),
215 | SET_ALL_ENABLE_PARAMS( MaterialOutput, MaterialInput, SecondarySpecular ),
216 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
217 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
218 | SET_ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialOutput, MaterialInput, Iridescence ),
219 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Fuzz ),
220 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Fuzz ),
221 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Diffuse ),
222 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Diffuse ),
223 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Scatter ),
224 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Subsurface ),
225 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
226 | SET_SHADINGNORMAL_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
227 | SET_ANISOTROPYDIRECTION_ENABLE_PARAM( MaterialOutput, MaterialInput, Glass ),
228 | SET_RESPONSE_ENABLE_PARAM( MaterialOutput, MaterialInput, Glow )
229 | )
230 | {
231 | // Function Definitions.
232 | float GainCorrect( float in, float Mask, float Expo, float Gain )
233 | {
234 | float out = in;
235 |
236 | out *= pow( 2.0, Expo ) * Gain;
237 |
238 | return mix( in, out, Mask );
239 | }
240 |
241 | color ColorCorrect( color in, float Mask, float Hue, float Sat, float Expo, float Gain, color Tint )
242 | {
243 | color RGB = in;
244 |
245 | color hsl = transformc( "rgb", "hsl", RGB );
246 | hsl[0] += Hue;
247 | hsl[1] *= Sat;
248 | RGB = transformc( "hsl", "rgb", hsl );
249 |
250 | RGB *= pow( 2.0, Expo ) * Gain * Tint;
251 |
252 | return mix( in, RGB, Mask );
253 | }
254 |
255 | float RoughnessCorrect( float in, float Mask, float Rough )
256 | {
257 | float r = mix(
258 | mix( 0.0, 1.0 + Rough, in ),
259 | mix( Rough, 1.0, in ),
260 | step( 0.0, Rough )
261 | );
262 |
263 | return clamp( r, 0.0, 1.0 );
264 | }
265 |
266 |
267 | // Output = Input.
268 | MatOut = MatIn;
269 |
270 | // Pull on the Socket to make sure it's evaluated.
271 | MatOut.socket = Socket;
272 |
273 | // Modify the Output material.
274 | if( Enable == 1 && Mask != 0.0 )
275 | {
276 | // ClearCoat.
277 | MatOut.ClearCoat_CG = ColorCorrect( MatOut.ClearCoat_CG, Mask,
278 | SpecularHue,
279 | SpecularSaturation,
280 | SpecularExposure,
281 | SpecularGain,
282 | SpecularTint
283 | );
284 |
285 | MatOut.ClearCoat_FaceCG = ColorCorrect( MatOut.ClearCoat_FaceCG, Mask,
286 | SpecularHue,
287 | SpecularSaturation,
288 | SpecularExposure,
289 | SpecularGain,
290 | SpecularTint
291 | );
292 |
293 | MatOut.ClearCoat_Roughness = RoughnessCorrect( MatOut.ClearCoat_Roughness, Mask,
294 | SpecularRoughness
295 | );
296 |
297 | // PrimarySpecular.
298 | MatOut.PrimarySpecular_CG = ColorCorrect( MatOut.PrimarySpecular_CG, Mask,
299 | SpecularHue,
300 | SpecularSaturation,
301 | SpecularExposure,
302 | SpecularGain,
303 | SpecularTint
304 | );
305 |
306 | MatOut.PrimarySpecular_FaceCG = ColorCorrect( MatOut.PrimarySpecular_FaceCG, Mask,
307 | SpecularHue,
308 | SpecularSaturation,
309 | SpecularExposure,
310 | SpecularGain,
311 | SpecularTint
312 | );
313 |
314 | MatOut.PrimarySpecular_Roughness = RoughnessCorrect( MatOut.PrimarySpecular_Roughness, Mask,
315 | SpecularRoughness
316 | );
317 |
318 | // SecondarySpecular.
319 | MatOut.SecondarySpecular_CG = ColorCorrect( MatOut.SecondarySpecular_CG, Mask,
320 | SpecularHue,
321 | SpecularSaturation,
322 | SpecularExposure,
323 | SpecularGain,
324 | SpecularTint
325 | );
326 |
327 | MatOut.SecondarySpecular_FaceCG = ColorCorrect( MatOut.SecondarySpecular_FaceCG, Mask,
328 | SpecularHue,
329 | SpecularSaturation,
330 | SpecularExposure,
331 | SpecularGain,
332 | SpecularTint
333 | );
334 |
335 | MatOut.SecondarySpecular_Roughness = RoughnessCorrect( MatOut.SecondarySpecular_Roughness, Mask,
336 | SpecularRoughness
337 | );
338 |
339 | // Iridescence.
340 | MatOut.Iridescence_FaceColor = ColorCorrect( MatOut.Iridescence_FaceColor, Mask,
341 | SpecularHue,
342 | SpecularSaturation,
343 | SpecularExposure,
344 | SpecularGain,
345 | SpecularTint
346 | );
347 |
348 | MatOut.Iridescence_EdgeColor = ColorCorrect( MatOut.Iridescence_EdgeColor, Mask,
349 | SpecularHue,
350 | SpecularSaturation,
351 | SpecularExposure,
352 | SpecularGain,
353 | SpecularTint
354 | );
355 |
356 | MatOut.Iridescence_Roughness = RoughnessCorrect( MatOut.Iridescence_Roughness, Mask,
357 | SpecularRoughness
358 | );
359 |
360 | // Glass.
361 | MatOut.Glass_ReflectionGain = GainCorrect( MatOut.Glass_ReflectionGain, Mask,
362 | SpecularExposure,
363 | SpecularGain
364 | );
365 |
366 | MatOut.Glass_RefractionCG = ColorCorrect( MatOut.Glass_RefractionCG, Mask,
367 | SpecularHue,
368 | SpecularSaturation,
369 | SpecularExposure,
370 | SpecularGain,
371 | SpecularTint
372 | );
373 |
374 | MatOut.Glass_Roughness = RoughnessCorrect( MatOut.Glass_Roughness, Mask,
375 | SpecularRoughness
376 | );
377 |
378 | // Fuzz.
379 | MatOut.Fuzz_CG = ColorCorrect( MatOut.Fuzz_CG, Mask,
380 | DiffuseHue,
381 | DiffuseSaturation,
382 | DiffuseExposure,
383 | DiffuseGain,
384 | DiffuseTint
385 | );
386 |
387 | // Diffuse.
388 | MatOut.Diffuse_CG = ColorCorrect( MatOut.Diffuse_CG, Mask,
389 | DiffuseHue,
390 | DiffuseSaturation,
391 | DiffuseExposure,
392 | DiffuseGain,
393 | DiffuseTint
394 | );
395 |
396 | MatOut.Diffuse_BackfaceCG = ColorCorrect( MatOut.Diffuse_BackfaceCG, Mask,
397 | DiffuseHue,
398 | DiffuseSaturation,
399 | DiffuseExposure,
400 | DiffuseGain,
401 | DiffuseTint
402 | );
403 |
404 | MatOut.Diffuse_TransmitCG = ColorCorrect( MatOut.Diffuse_TransmitCG, Mask,
405 | DiffuseHue,
406 | DiffuseSaturation,
407 | DiffuseExposure,
408 | DiffuseGain,
409 | DiffuseTint
410 | );
411 |
412 | // Scatter.
413 | MatOut.Scatter_CG = ColorCorrect( MatOut.Scatter_CG, Mask,
414 | DiffuseHue,
415 | DiffuseSaturation,
416 | DiffuseExposure,
417 | DiffuseGain,
418 | DiffuseTint
419 | );
420 |
421 | MatOut.Scatter_BacksideCG = ColorCorrect( MatOut.Scatter_BacksideCG, Mask,
422 | DiffuseHue,
423 | DiffuseSaturation,
424 | DiffuseExposure,
425 | DiffuseGain,
426 | DiffuseTint
427 | );
428 |
429 | // Subsurface.
430 | MatOut.Subsurface_Gain = GainCorrect( MatOut.Subsurface_Gain, Mask,
431 | DiffuseExposure,
432 | DiffuseGain
433 | );
434 |
435 | MatOut.Subsurface_ShortGain = GainCorrect( MatOut.Subsurface_ShortGain, Mask,
436 | DiffuseExposure,
437 | DiffuseGain
438 | );
439 |
440 | MatOut.Subsurface_LongGain = GainCorrect( MatOut.Subsurface_LongGain, Mask,
441 | DiffuseExposure,
442 | DiffuseGain
443 | );
444 | }
445 | }
446 |
--------------------------------------------------------------------------------
/ris/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # RMANTREE points to the RenderManProServer directory.
3 | # Set it if it's not already set in the environment.
4 | #
5 | RMANTREE ?= /opt/pixar/RenderManProServer-23.2
6 |
7 | #
8 | # Compiler and linker settings.
9 | #
10 | CC = clang++
11 | CFLAGS = -Wall -Wno-switch -Wno-reorder -Wno-sign-compare -Wno-narrowing -Wno-deprecated-declarations -fPIC -std=c++14 -O3
12 | INCLUDE = -I. -I./include -I${RMANTREE}/include -I/usr/include/freetype2
13 |
14 | LD = clang++
15 | LFLAGS = -shared
16 | LIBS = -lfreetype
17 |
18 | #
19 | # Control variables.
20 | # These subdirectories will be searched for .cpp files, which will then be built into .so files.
21 | #
22 | SUBDIRS := displace displayfilter
23 |
24 | # These shaders won't be built. Use 'subdirectory/basename'.
25 | EXCLUDE :=
26 |
27 | #
28 | # Make functionality.
29 | # src will be the list of .cpp files to build from.
30 | #
31 | src := $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.cpp))
32 |
33 | EXCLUDE := $(basename $(EXCLUDE))
34 | EXCLUDE := $(addsuffix .cpp, $(EXCLUDE))
35 |
36 | src := $(filter-out $(EXCLUDE), $(src))
37 |
38 | #
39 | # Create target lists.
40 | #
41 | obj := $(src:%.cpp=%.o)
42 | dso := $(src:%.cpp=%.so)
43 |
44 | #
45 | # Targets and prerequisites.
46 | #
47 | all: $(dso)
48 |
49 | $(obj): ${RMANTREE}/include/*.h
50 |
51 | #
52 | # Rules.
53 | #
54 | clean:
55 | -$(shell rm -f $(shell find . -name "*.so" -print) $(shell find . -name "*.o" -print))
56 |
57 | show_src:
58 | @echo $(src)
59 |
60 | show_obj:
61 | @echo $(obj)
62 |
63 | show_dso:
64 | @echo $(dso)
65 |
66 | #
67 | # Build rules.
68 | #
69 | %.o : %.cpp
70 | $(CC) $(CFLAGS) $(INCLUDE) -o $@ -c $<
71 |
72 | %.so : %.o
73 | $(LD) $(LFLAGS) $(LIBS) -o $@ $<
74 |
--------------------------------------------------------------------------------
/ris/displace/Args/SetP.args:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Directly sets the value of P.
16 |
17 |
18 |
22 |
23 |
24 | The new value of P.
25 |
26 |
27 |
28 |
32 |
33 |
34 | How much effect will this have on the displacement?
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ris/displace/SetP.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2019 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This program may not be copied, modified, or distributed except according to those terms.
8 | */
9 | /*
10 | * P = mix( P, Q, Enable ). That's it.
11 | */
12 | #include "RixDisplacement.h"
13 | #include "RixShadingUtils.h"
14 |
15 | /*
16 | * RixDisplacementFactory class declaration.
17 | */
18 | class SetPFactory : public RixDisplacementFactory
19 | {
20 | private:
21 |
22 | enum ui_Id
23 | {
24 | ui_Enable,
25 | ui_Q
26 | };
27 |
28 | // Default shader parameter values.
29 | RtFloat default_Enable;
30 | RtPoint3 default_Q;
31 |
32 | public:
33 |
34 | SetPFactory()
35 | {
36 | default_Enable = RtFloat( 1.0f );
37 | default_Q = RtPoint3( 0.0f );
38 | }
39 | ~SetPFactory() {}
40 |
41 |
42 | // GetParamTable() method.
43 | const RixSCParamInfo* GetParamTable()
44 | {
45 | static RixSCParamInfo s_ptable[] =
46 | {
47 | RixSCParamInfo( RtUString( "Enable" ), k_RixSCFloat ),
48 | RixSCParamInfo( RtUString( "Q" ), k_RixSCPoint ),
49 |
50 | RixSCParamInfo()
51 | };
52 |
53 | return &s_ptable[0];
54 | }
55 |
56 | // BeginDisplacement() declaration.
57 | RixDisplacement* BeginDisplacement(
58 | const RixShadingContext *,
59 | RixSCShadingMode,
60 | RtPointer
61 | );
62 | void EndDisplacement( RixDisplacement* ) {}
63 |
64 | // Parent class virtual methods, so must define them even though they're no-ops.
65 | int Init( RixContext &, RtUString const ) { return 0; }
66 | void Finalize( RixContext & ) {}
67 | void Synchronize( RixContext&, RixSCSyncMsg, const RixParameterList* ) {}
68 | #if _PRMANAPI_VERSION_ > 22
69 | void CreateInstanceData( RixContext&, const RtUString, const RixParameterList*, InstanceData* ) {}
70 | #else
71 | int CreateInstanceData( RixContext&, const RtUString, const RixParameterList*, InstanceData* ) { return 0; }
72 | #endif
73 | };
74 |
75 |
76 | /*
77 | * RixDisplacement class declaration.
78 | */
79 | class SetPDisp : public RixDisplacement
80 | {
81 | private:
82 | // Shader-specific parameter(s).
83 | const RixSCDetail m_detail_Enable;
84 | const RtFloat* m_Enable;
85 | const RixSCConnectionInfo m_cinfo_Q;
86 | const RtPoint3* m_Q;
87 |
88 | public:
89 | // Class constructor.
90 | // An instance of this class is created in BeginDisplacement().
91 | // The constructor's purpose is to set its class method variables
92 | // for use in its GetDisplacement() method.
93 | SetPDisp(
94 | const RixShadingContext* sCtx,
95 | RixDisplacementFactory* dFac,
96 |
97 | const RixSCDetail detail_Enable,
98 | const RtFloat* Enable,
99 | const RixSCConnectionInfo cinfo_Q,
100 | const RtPoint3* Q
101 | ) :
102 | // Sets the protected RixDisplacement class variables
103 | // 'shadingCtx' to sCtx, and 'displacementFactory' to dFac.
104 | RixDisplacement( sCtx, dFac ),
105 |
106 | // Sets user parameter variables.
107 | m_detail_Enable( detail_Enable ),
108 | m_Enable( Enable ),
109 | m_cinfo_Q( cinfo_Q ),
110 | m_Q( Q )
111 | { }
112 |
113 | // The class destructor is a no-op.
114 | ~SetPDisp() {}
115 |
116 |
117 | // RixDisplacement::GetDisplacement() method.
118 | // Called by the renderer to affect P.
119 | // XXX What is the value of P: P or Po?
120 | bool GetDisplacement( RtPoint3* P )
121 | {
122 | // Leave P alone if Q is not connected.
123 | if( m_cinfo_Q != k_RixSCNetworkValue ) return false;
124 |
125 | if( m_detail_Enable == k_RixSCUniform )
126 | {
127 | if( m_Enable[0] == 0.0f ) return false;
128 |
129 | for( int i=0; i < shadingCtx->numPts; ++i ) P[i] = RixMix( P[i], m_Q[i], m_Enable[0] );
130 | }
131 | else
132 | {
133 | for( int i=0; i < shadingCtx->numPts; ++i ) P[i] = RixMix( P[i], m_Q[i], m_Enable[i] );
134 | }
135 |
136 | return true;
137 | }
138 | };
139 |
140 |
141 | /*
142 | * RixDisplacementFactory::BeginDisplacement()
143 | *
144 | * The BeginDisplacement method returns an instance of this shader's RixDisplacement class.
145 | * It also computes any class variables needed by the RixDisplacement class and passes them
146 | * to its constructor. Such variables typically come from user parameters that are used to
147 | * control the shader's functionality.
148 | */
149 | RixDisplacement* SetPFactory::BeginDisplacement(
150 | const RixShadingContext* sCtx,
151 | RixSCShadingMode shadingMode,
152 | RtPointer instanceData
153 | ) {
154 | // SetPDisp() parameters.
155 | RixSCDetail detail_Enable;
156 | const RtFloat* Enable;
157 | RixSCConnectionInfo cinfo_Q;
158 | const RtPoint3* Q = NULL;
159 |
160 | // Get the parameter data.
161 | detail_Enable = sCtx->EvalParam( ui_Enable, -1, &Enable, &default_Enable, false );
162 | assert( detail_Enable == k_RixSCUniform || detail_Enable == k_RixSCVarying );
163 |
164 | RixSCType type = k_RixSCPoint;
165 | sCtx->GetParamInfo( ui_Q, &type, &cinfo_Q );
166 |
167 | if( detail_Enable != k_RixSCUniform || Enable[0] != 0.0f )
168 | {
169 | sCtx->EvalParam( ui_Q, -1, &Q, &default_Q, true );
170 | }
171 | // XXX else what? Leaves Q = NULL.
172 |
173 | // Allocate memory for this shader's RixDisplacement object in the
174 | // renderer's Displacement (shares Bxdf) shading context memory pool.
175 | RixShadingContext::Allocator pool( sCtx );
176 | void* mem = pool.AllocForBxdf< SetPDisp >(1);
177 |
178 | // Create an instance of this shader's RixDisplacement object
179 | // and pass its parameter data to it.
180 | SetPDisp* disp = new (mem) SetPDisp( sCtx, this,
181 | detail_Enable,
182 | Enable,
183 | cinfo_Q,
184 | Q
185 | );
186 |
187 | return disp;
188 | }
189 |
190 |
191 | /*
192 | * These are the entrypoints to the plugin from the renderer.
193 | */
194 | extern "C" PRMANEXPORT RixDisplacementFactory* CreateRixDisplacementFactory( RtConstString hint )
195 | {
196 | return new SetPFactory();
197 | }
198 |
199 | extern "C" PRMANEXPORT void DestroyRixDisplacementFactory( RixDisplacementFactory* dFac )
200 | {
201 | delete static_cast< SetPFactory* >( dFac );
202 | }
203 |
--------------------------------------------------------------------------------
/ris/displayfilter/Annotate.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Laika, LLC. Authored by Mitch Prater.
3 | *
4 | * Licensed under the Apache License Version 2.0 http://apache.org/licenses/LICENSE-2.0,
5 | * or the MIT license http://opensource.org/licenses/MIT, at your option.
6 | *
7 | * This file may not be copied, modified, or distributed except according to those terms.
8 | */
9 | /*
10 | * Annotates the rendered image with the supplied text.
11 | */
12 | #include
13 | #include FT_FREETYPE_H
14 | #include FT_GLYPH_H
15 |
16 | #include "RixPredefinedStrings.hpp"
17 | #include "RixDisplayFilter.h"
18 | #include "RixIntegrator.h"
19 |
20 | class Annotate : public RixDisplayFilter
21 | {
22 | private:
23 |
24 | RixMessages* rixMsg;
25 |
26 | // InstanceData Definition.
27 | struct textImage
28 | {
29 | // text upper left corner display pixel location.
30 | int xpos;
31 | int ypos;
32 |
33 | // 8 bit rendered text image.
34 | int xsize;
35 | int ysize;
36 | unsigned char* alpha;
37 | };
38 |
39 | struct localInstanceData
40 | {
41 | static void Delete( RtPointer );
42 | RixChannelId InputId;
43 | RixChannelId OutputId;
44 | RixChannelId AlphaId;
45 | RtColorRGB Color;
46 | textImage Text;
47 | };
48 |
49 | void setInstanceData(
50 | RixContext &,
51 | const RtUString,
52 | const RixParameterList *,
53 | InstanceData *
54 | );
55 |
56 | // GenerateTextImage() declaration.
57 | void GenerateTextImage(
58 | const RixParameterList*,
59 | FT_Face,
60 | int,
61 | int,
62 | int,
63 | int,
64 | int,
65 | int,
66 | textImage*
67 | );
68 |
69 | // WriteTextPixel() declaration.
70 | void WriteTextPixel(
71 | const textImage*,
72 | const RtColorRGB*,
73 | const int,
74 | const int,
75 | const bool,
76 | RtColorRGB*,
77 | RtFloat*
78 | );
79 |
80 | enum ui_Id
81 | {
82 | ui_Text = 0,
83 | ui_Color,
84 | ui_Top,
85 | ui_Left,
86 | ui_Height,
87 | ui_Font,
88 |
89 | ui_Input,
90 | ui_Output,
91 | ui_Alpha
92 | };
93 |
94 | public:
95 |
96 | Annotate() {}
97 | ~Annotate() {}
98 |
99 | const RixSCParamInfo* GetParamTable()
100 | {
101 | static RixSCParamInfo s_ptable[] =
102 | {
103 | // inputs.
104 | RixSCParamInfo( RtUString( "Text" ), k_RixSCString ),
105 | RixSCParamInfo( RtUString( "Color" ), k_RixSCColor ),
106 | RixSCParamInfo( RtUString( "Top" ), k_RixSCFloat ),
107 | RixSCParamInfo( RtUString( "Left" ), k_RixSCFloat ),
108 | RixSCParamInfo( RtUString( "Height" ), k_RixSCFloat ),
109 | RixSCParamInfo( RtUString( "Font" ), k_RixSCString ),
110 |
111 | RixSCParamInfo( RtUString( "Input" ), k_RixSCString ),
112 | RixSCParamInfo( RtUString( "Output" ), k_RixSCString ),
113 | RixSCParamInfo( RtUString( "Alpha" ), k_RixSCInteger ),
114 |
115 | RixSCParamInfo()
116 | };
117 |
118 | return &s_ptable[0];
119 | }
120 |
121 | // Create and Synchronize InstanceData definitions.
122 | void CreateInstanceData(
123 | RixContext& Ctx,
124 | const RtUString plugNodeName,
125 | const RixParameterList* pList,
126 | InstanceData* instanceData
127 | ) {
128 | instanceData->synchronizeHints = RixShadingPlugin::SynchronizeHints::k_All;
129 | }
130 |
131 | void SynchronizeInstanceData(
132 | RixContext& Ctx,
133 | const RtUString plugNodeName,
134 | const RixParameterList* pList,
135 | uint32_t editHints,
136 | InstanceData* instanceData
137 | ) {
138 | setInstanceData( Ctx, plugNodeName, pList, instanceData );
139 | return;
140 | }
141 |
142 | // Get pointers to Rix interfaces.
143 | int Init( RixContext& Ctx, RtUString const plugPathName )
144 | {
145 | rixMsg = static_cast< RixMessages* >( Ctx.GetRixInterface( k_RixMessages ));
146 | return ( !rixMsg ) ? -1 : 0;
147 | }
148 |
149 | // Filter() declaration.
150 | void Filter(
151 | RixDisplayFilterContext &,
152 | RtPointer
153 | );
154 |
155 | // Parent class virtual methods, so must define them even though they're no-ops.
156 | void Finalize( RixContext& ) {}
157 | void Synchronize( RixContext&, RixSCSyncMsg, const RixParameterList* ) { }
158 | };
159 |
160 | /*
161 | * GenerateTextImage definition.
162 | */
163 | void Annotate::GenerateTextImage(
164 | const RixParameterList* pList,
165 | const FT_Face face,
166 | const int size,
167 | const int xres,
168 | const int yres,
169 | const int ui_Text,
170 | const int ui_Top,
171 | const int ui_Left,
172 | textImage* TextImage
173 | ) {
174 | RtUString Text( Rix::k_empty );
175 | pList->EvalParam( ui_Text, 0, &Text );
176 |
177 | // Short-circuit for an empty Text string.
178 | if( Text == Rix::k_empty )
179 | {
180 | TextImage->alpha = NULL;
181 | return;
182 | }
183 |
184 | // Get the x,y display position for the Text.
185 | RtFloat Top( 0.0f );
186 | pList->EvalParam( ui_Top, 0, &Top );
187 |
188 | RtFloat Left( 0.0f );
189 | pList->EvalParam( ui_Left, 0, &Left );
190 |
191 | TextImage->ypos = std::round( Top * yres );
192 | TextImage->xpos = std::round( Left * xres );
193 |
194 | // Convert Text to C string.
195 | const char* text = Text.CStr();
196 | const int textLen = Text.Length();
197 |
198 | //
199 | // Determine the text's alpha image dimensions based on the Text's characters.
200 | //
201 | // Set the glyph image transformation to zero.
202 | FT_Vector pen;
203 | pen.x = 0;
204 | pen.y = 0;
205 | FT_Set_Transform( face, NULL, &pen );
206 |
207 | // Render the first character's glyph bitmap into the face->glyph "slot".
208 | FT_Load_Char( face, text[0], FT_LOAD_RENDER );
209 | const FT_GlyphSlot slot = face->glyph;
210 |
211 | // Save its alpha image starting x offset.
212 | const int xstart = -( slot->bitmap_left );
213 |
214 | // Save its character width (in 1/64 pixel units).
215 | FT_Pos textWidth = slot->advance.x;
216 |
217 | // Highest pixel above the baseline (baseline=0, + is up).
218 | int textTop = int( slot->bitmap_top );
219 |
220 | // Lowest pixel below the baseline, minus 1 (baseline=0. Would need to add 1 to get the actual pixel location).
221 | int textBottom = int( slot->bitmap_top - slot->bitmap.rows );
222 |
223 | // Process the remaining characters.
224 | for( int c=1; c < textLen; ++c )
225 | {
226 | // Render the character's glyph bitmap into the face->glyph "slot".
227 | FT_Load_Char( face, text[c], FT_LOAD_RENDER );
228 | const FT_GlyphSlot slot = face->glyph;
229 |
230 | // Accumulate the character width (in 1/64 pixel units).
231 | textWidth += slot->advance.x;
232 |
233 | // Highest pixel above the baseline (baseline=0, + is up).
234 | textTop = std::max( textTop, int( slot->bitmap_top ));
235 |
236 | // Lowest pixel below the baseline, minus 1 (baseline=0. Would need to add 1 to get the actual pixel location).
237 | textBottom = std::min( textBottom, int( slot->bitmap_top - slot->bitmap.rows ));
238 | }
239 |
240 | //
241 | // Generate the Text string's bitmap alpha image.
242 | //
243 | const int xsize = int( textWidth >> 6 ) + 1; // Convert to pixels.
244 | const int ysize = textTop - textBottom; // Since we didn't add 1 when computing textBottom,
245 | // we don't need to add 1 to ysize.
246 | // Save the text image dimensions.
247 | TextImage->xsize = xsize;
248 | TextImage->ysize = ysize;
249 |
250 | // Allocate the text image memory.
251 | const int alphaSize = xsize * ysize;
252 | TextImage->alpha = new unsigned char[ alphaSize ];
253 |
254 | // Convenience pointer.
255 | unsigned char* alphaImage = TextImage->alpha;
256 | for( int i=0; i < alphaSize; ++i ) alphaImage[i] = 0; // Zero data.
257 |
258 | // Reset the pen position.
259 | // Start at the xstart offset of the first character. pen is in 1/64 pixel units.
260 | // We could also set this to 0, and add xstart to the alphaIndex (x), but this is more optimized.
261 | pen.x = xstart << 6;
262 | pen.y = 0;
263 |
264 | // For each character.
265 | for( int c=0; c < textLen; ++c )
266 | {
267 | // Set the glyph image transformation to the current pen location.
268 | FT_Set_Transform( face, NULL, &pen );
269 |
270 | // Render the character's glyph bitmap into the face->glyph "slot".
271 | FT_Load_Char( face, text[c], FT_LOAD_RENDER );
272 | const FT_GlyphSlot slot = face->glyph;
273 |
274 | // Left edge of this character.
275 | int x = slot->bitmap_left;
276 | // Offset from the image top (y=0) to put this character's baseline at the image's baseline row.
277 | int y = textTop - slot->bitmap_top;
278 |
279 | // Loop over this glpyh's bitmap and merge it into the text image.
280 | const FT_Bitmap bitmap = slot->bitmap;
281 | for( int j=0; j < bitmap.rows; ++j ) for( int i=0; i < bitmap.width; ++i )
282 | {
283 | const int alphaIndex = x+i + (y+j)*xsize;
284 | if( 0 <= alphaIndex && alphaIndex < alphaSize )
285 | {
286 | alphaImage[ alphaIndex ] = std::max( alphaImage[ alphaIndex ], bitmap.buffer[ i + j*bitmap.width ] );
287 | }
288 | }
289 |
290 | // Advance the pen position.
291 | pen.x += slot->advance.x;
292 | }
293 | }
294 |
295 | /*
296 | * WriteTextPixel definition.
297 | */
298 | void Annotate::WriteTextPixel(
299 | const textImage* TextImage,
300 | const RtColorRGB* Color,
301 | const RtInt x,
302 | const RtInt y,
303 | const bool useAlpha,
304 | RtColorRGB* Input,
305 | RtFloat* Alpha
306 | ) {
307 | if( TextImage->alpha )
308 | {
309 | const int xsize = TextImage->xsize;
310 | const int ysize = TextImage->ysize;
311 | const int xpos = TextImage->xpos;
312 | const int ypos = TextImage->ypos;
313 |
314 | // Is the x,y display pixel within the text image?
315 | if( xpos <= x && x < xpos+xsize && ypos <= y && y < ypos+ysize )
316 | {
317 | // Get the text image pixel's alpha value.
318 | const unsigned char* alpha = TextImage->alpha;
319 | const float a = float( alpha[ x-xpos + (y-ypos)*xsize ] )/255.0f;
320 |
321 | // Modify the display pixel.
322 | *Input = RixMix( *Input, *Color, a );
323 | if( useAlpha ) *Alpha = a + *Alpha*( 1.0f-a );
324 | }
325 | }
326 | }
327 |
328 | /*
329 | * Delete and Set Instance Data.
330 | */
331 | void Annotate::localInstanceData::Delete( RtPointer data )
332 | {
333 | localInstanceData* iData = static_cast< localInstanceData* >( data );
334 |
335 | if( iData->Text.alpha ){ delete[] iData->Text.alpha; }
336 |
337 | delete iData;
338 | }
339 |
340 | void Annotate::setInstanceData(
341 | RixContext& Ctx,
342 | const RtUString plugNodeName,
343 | const RixParameterList* pList,
344 | InstanceData* instanceData
345 | ) {
346 | // If we've already created instanceData, free it first so we can synchronize with the latest settings.
347 | if( instanceData->data && instanceData->freefunc ) instanceData->freefunc( instanceData->data );
348 |
349 | // Init instanceData.
350 | instanceData->datalen = 0;
351 | instanceData->data = NULL;
352 | instanceData->freefunc = NULL;
353 | instanceData->paramtable = NULL;
354 |
355 | // Create new local instance data.
356 | localInstanceData* iData = new localInstanceData;
357 | if( !iData ) return;
358 |
359 | // Get render state and integrator environment.
360 | RixRenderState* rixRS = static_cast< RixRenderState* >( Ctx.GetRixInterface( k_RixRenderState ));
361 |
362 | const RixIntegratorEnvironment* rixIE;
363 | {
364 | RixRenderState::FrameInfo rixFI;
365 | rixRS->GetFrameInfo( &rixFI );
366 |
367 | rixIE = static_cast< const RixIntegratorEnvironment* >( rixFI.integratorEnv );
368 | }
369 |
370 | // Get image dimensions in pixels.
371 | RixRenderState::FrameInfo frameInfo;
372 | rixRS->GetFrameInfo( &frameInfo );
373 |
374 | const int xres = frameInfo.displayState.resolution[0];
375 | const int yres = frameInfo.displayState.resolution[1];
376 |
377 | //
378 | // Get the display channel Id's.
379 | //
380 | RtUString Input( Rix::k_Ci );
381 | pList->EvalParam( ui_Input, 0, &Input );
382 |
383 | RtUString Output( Rix::k_Ci );
384 | pList->EvalParam( ui_Output, 0, &Output );
385 |
386 | RtInt Alpha = 1;
387 | pList->EvalParam( ui_Alpha, 0, &Alpha );
388 |
389 | // Init Id's.
390 | RixChannelId InputChannelId = k_InvalidChannelId;
391 | RixChannelId OutputChannelId = k_InvalidChannelId;
392 | RixChannelId AlphaChannelId = k_InvalidChannelId;
393 |
394 | // Find matching channels.
395 | for( int i=0; i < rixIE->numDisplays; ++i )
396 | {
397 | if( rixIE->displays[i].channel == Input ) InputChannelId = rixIE->displays[i].id;
398 | if( rixIE->displays[i].channel == Output ) OutputChannelId = rixIE->displays[i].id;
399 | if( Alpha == 1 && rixIE->displays[i].channel == Rix::k_a ) AlphaChannelId = rixIE->displays[i].id;
400 | }
401 |
402 | // Error check.
403 | if( InputChannelId == k_InvalidChannelId )
404 | {
405 | rixMsg->Warning( "The Input channel \"%s\" is invalid.", Input);
406 | delete iData;
407 | return;
408 | }
409 |
410 | if( OutputChannelId == k_InvalidChannelId )
411 | {
412 | rixMsg->Warning( "The Output channel \"%s\" is invalid.", Output);
413 | delete iData;
414 | return;
415 | }
416 |
417 | if( Alpha == 1 && AlphaChannelId == k_InvalidChannelId )
418 | {
419 | rixMsg->Warning( "The Alpha channel was not found." );
420 | delete iData;
421 | return;
422 | }
423 |
424 | // Set instanceData.
425 | iData->InputId = InputChannelId;
426 | iData->OutputId = OutputChannelId;
427 | iData->AlphaId = AlphaChannelId; // k_InvalidChannelId if not using alpha.
428 |
429 | //
430 | // Get Font data and initialize the type face.
431 | //
432 | iData->Color = RtColorRGB( 1.0f, 0.7f, 0.0f );
433 | pList->EvalParam( ui_Color, 0, &iData->Color );
434 |
435 | // Determine text size in pixels.
436 | RtFloat Height = 0.03f;
437 | pList->EvalParam( ui_Height, 0, &Height );
438 |
439 | const int size = std::max( 8.0f, std::round( Height * yres ));
440 |
441 | // Get the desired font file.
442 | RtUString Font( Rix::k_empty );
443 | pList->EvalParam( ui_Font, 0, &Font );
444 |
445 | // Init FreeType library.
446 | FT_Library library;
447 | FT_Init_FreeType( &library );
448 |
449 | // Get the type face (i.e. font) from the specified file.
450 | FT_Face face;
451 | FT_Error err = FT_New_Face( library, Font.CStr(), 0, &face );
452 |
453 | if( err )
454 | {
455 | rixMsg->Warning( "Error accessing Font file \"%s\" err = %d", Font, err );
456 | delete iData;
457 | }
458 | else
459 | {
460 | // Set the font's rendered glyph's em-square pixel height (and width).
461 | FT_Set_Pixel_Sizes( face, 0, size );
462 |
463 | // Generate the Text Image iData.
464 | Annotate::GenerateTextImage( pList, face, size, xres, yres, ui_Text, ui_Top, ui_Left, &( iData->Text ));
465 |
466 | // Done with FreeType face.
467 | FT_Done_Face( face );
468 |
469 | // Set instanceData to iData.
470 | instanceData->datalen = sizeof( *iData );
471 | instanceData->data = static_cast< void* >( iData );
472 | instanceData->freefunc = localInstanceData::Delete;
473 | }
474 |
475 | // Done with FreeType library.
476 | FT_Done_FreeType( library );
477 | }
478 |
479 |
480 | /*
481 | * Filter definition.
482 | */
483 | void Annotate::Filter(
484 | RixDisplayFilterContext& fCtx,
485 | RtPointer instanceData
486 | ) {
487 | // Retrieve the non-connectable parameter values.
488 | const localInstanceData* iData = static_cast< const localInstanceData* >( instanceData );
489 |
490 | // Nothing to do.
491 | if( !iData ) return;
492 |
493 | const bool useAlpha = iData->AlphaId != k_InvalidChannelId;
494 |
495 | // Loop over the current bucket of display pixels.
496 | for( int y = fCtx.ymin; y < fCtx.ymax; ++y )
497 | for( int x = fCtx.xmin; x < fCtx.xmax; ++x )
498 | {
499 | RtColorRGB Input;
500 | fCtx.Read( iData->InputId, x, y, Input );
501 |
502 | RtFloat Alpha;
503 | if( useAlpha ) fCtx.Read( iData->AlphaId, x, y, Alpha );
504 |
505 | Annotate::WriteTextPixel( &( iData->Text ), &( iData->Color ), x, y, useAlpha, &Input, &Alpha );
506 |
507 | fCtx.Write( iData->OutputId, x, y, Input );
508 | if( useAlpha ) fCtx.Write( iData->AlphaId, x, y, Alpha );
509 | }
510 | }
511 |
512 |
513 | /*
514 | * These are the entrypoints to the plugin from the renderer.
515 | */
516 | RIX_DISPLAYFILTERCREATE
517 | {
518 | return new Annotate();
519 | }
520 |
521 | RIX_DISPLAYFILTERDESTROY
522 | {
523 | delete static_cast< Annotate* >( filter );
524 | }
525 |
--------------------------------------------------------------------------------
/ris/displayfilter/Args/Annotate.args:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 | Annotate the rendered image with the supplied Text.
20 |
21 |
22 |
23 |
27 |
28 | Text to composite into the image.
29 |
30 |
31 |
32 |
36 |
37 | The Color of the Text.
38 |
39 |
40 |
41 |
46 |
47 | Determines where the Top of the Text will be located.
48 |
49 | In NDC coordinates: upper left (0,0) to lower right (1,1).
50 |
51 |
52 |
53 |
58 |
59 | Determines where the Left edge of the Text will be located.
60 |
61 | In NDC coordinates: upper left (0,0) to lower right (1,1).
62 |
63 |
64 |
65 |
70 |
71 | Character Height as a percentage of the image height (NDC space).
72 |
73 |
74 |
75 |
80 |
81 | The file containing the desired Font.
82 |
83 | On linux systems, these are typically in /usr/share/fonts
.
84 |
85 |
86 |
87 |
91 |
92 | The name of the display channel to be annotated.
93 |
94 |
95 |
96 |
100 |
101 | The name of the display channel to write the annotated image to.
102 | This may be the same as the Input.
103 |
104 |
105 |
106 |
111 |
112 | Include the Text's alpha in the alpha (a) channel.
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/scene/Teapot.katana:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/scene/Teapot.katana
--------------------------------------------------------------------------------
/scene/Teapot_Annotated.katana:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/scene/Teapot_Annotated.katana
--------------------------------------------------------------------------------
/wiki_images/Annotate.params.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/Annotate.params.png
--------------------------------------------------------------------------------
/wiki_images/Annotate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/Annotate.png
--------------------------------------------------------------------------------
/wiki_images/Material_v2_NMC.macro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/Material_v2_NMC.macro.png
--------------------------------------------------------------------------------
/wiki_images/Material_v2_NMC.params.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/Material_v2_NMC.params.png
--------------------------------------------------------------------------------
/wiki_images/Material_v2_Shaders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/Material_v2_Shaders.png
--------------------------------------------------------------------------------
/wiki_images/Teapot.katana.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/Teapot.katana.jpg
--------------------------------------------------------------------------------
/wiki_images/material_v2_PxrSurface.params.expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/material_v2_PxrSurface.params.expanded.png
--------------------------------------------------------------------------------
/wiki_images/material_v2_PxrSurface.params.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/material_v2_PxrSurface.params.png
--------------------------------------------------------------------------------
/wiki_images/material_v2_PxrSurface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaikaStudios/shading-library/b9032f49cf034746645fe3e4a97a6b5ea2f0268c/wiki_images/material_v2_PxrSurface.png
--------------------------------------------------------------------------------