Skip to content

Commit 0fbb22d

Browse files
Add partial and optional support for OCIO to MaterialX (AcademySoftwareFoundation#1917)
The default color management system in MaterialX has support for a very limited set of color spaces. Some commonly used spaces such as linear Rec.2020 or sRGB-encoded AP1 are not available. MaterialX is often used in applications that already use OCIO for color management and so artists are sometimes confused as to why the color spaces in a menu that is available for textures in another part of the application are not available for textures in MaterialX. In some cases, a color space may even be mathematically the same as one in the MaterialX set, but it is simply named differently. This may lead to the artist picking the wrong color space and wasting time. In situations like this, the application is able to offer a better user experience by offloading the interpretation of color space names to OCIO. This allows artists to use the same color spaces with all textures rather than having a different set for MaterialX. However, not all OCIO color spaces are appropriate for use in a MaterialX document and this PR does not offer support for full OCIO. Supported color spaces include any of those that are mathematically compatible with one of the default MaterialX spaces. This PR does not change where the implicit color conversions happen in a MaterialX shader, and it does not provide any additional functionality to creators of MaterialX documents, other than expanding the set of allowed color space names. The MaterialX API already allows a client to override the default mx::ColorManagementSystem, this PR illustrates how that may be done in order to take advantage of a subset of OCIO. It should be noted that only minimal changes would be needed to adapt this PR for use with either OCIO or the nanoColor library currently under development. This integrates the OCIO shadergen into the MaterialX shadergen to provide on-the-fly color management for OpenGL, Vulkan, Metal, and OSL.
1 parent 9a8f0a0 commit 0fbb22d

20 files changed

Lines changed: 1201 additions & 13 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ option(MATERIALX_BUILD_GEN_MSL "Build the MSL shader generator back-end." ON)
4545
option(MATERIALX_BUILD_RENDER "Build the MaterialX Render modules." ON)
4646
option(MATERIALX_BUILD_RENDER_PLATFORMS "Build platform-specific render modules for each shader generator." ON)
4747
option(MATERIALX_BUILD_OIIO "Build OpenImageIO support for MaterialXRender." OFF)
48+
option(MATERIALX_BUILD_OCIO "Build OpenColorIO support for shader generators." OFF)
4849
option(MATERIALX_BUILD_TESTS "Build unit tests." OFF)
4950
option(MATERIALX_BUILD_BENCHMARK_TESTS "Build benchmark tests." OFF)
5051

@@ -169,6 +170,7 @@ mark_as_advanced(MATERIALX_BUILD_GEN_MSL)
169170
mark_as_advanced(MATERIALX_BUILD_RENDER)
170171
mark_as_advanced(MATERIALX_BUILD_RENDER_PLATFORMS)
171172
mark_as_advanced(MATERIALX_BUILD_OIIO)
173+
mark_as_advanced(MATERIALX_BUILD_OCIO)
172174
mark_as_advanced(MATERIALX_BUILD_BENCHMARK_TESTS)
173175
mark_as_advanced(MATERIALX_BUILD_SHARED_LIBS)
174176
mark_as_advanced(MATERIALX_BUILD_DATA_LIBRARY)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Adds some syntactic sugar allowing mixing vector4 and color4 as
2+
// arguments of some binary operators used by OCIO transform code.
3+
4+
vector4 __operator__mul__(matrix m, vector4 v)
5+
{
6+
return transform(m, v);
7+
}
8+
9+
vector4 __operator__mul__(color4 c, vector4 v)
10+
{
11+
return vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a) * v;
12+
}
13+
14+
vector4 __operator__mul__(vector4 v, color4 c)
15+
{
16+
return c * v;
17+
}
18+
19+
vector4 __operator__sub__(color4 c, vector4 v)
20+
{
21+
return vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a) - v;
22+
}
23+
24+
vector4 __operator__add__(vector4 v, color4 c)
25+
{
26+
return v + vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a);
27+
}
28+
29+
vector4 __operator__add__(color4 c, vector4 v)
30+
{
31+
return v + c;
32+
}
33+
34+
vector4 pow(color4 c, vector4 v)
35+
{
36+
return pow(vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a), v);
37+
}
38+
39+
vector4 max(vector4 v, color4 c)
40+
{
41+
return max(v, vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a));
42+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?xml version="1.0"?>
2+
<materialx version="1.39">
3+
<standard_surface name="standard_surface1" type="surfaceshader" nodedef="ND_standard_surface_surfaceshader">
4+
<input name="base_color" type="color3" nodename="switch1" />
5+
</standard_surface>
6+
<surfacematerial name="Standard_Surface1" type="material" nodedef="ND_surfacematerial">
7+
<input name="surfaceshader" type="surfaceshader" nodename="standard_surface1" />
8+
</surfacematerial>
9+
<switch name="switch1" type="color3" nodedef="ND_switch_color3">
10+
<input name="in1" type="color3" nodename="switch2" />
11+
<input name="in2" type="color3" nodename="switch3" />
12+
<input name="in3" type="color3" nodename="switch4" />
13+
<input name="in4" type="color3" nodename="switch5" />
14+
<input name="in5" type="color3" nodename="switch6" />
15+
<input name="in6" type="color3" nodename="switch7" />
16+
<input name="in7" type="color3" nodename="switch8" />
17+
<input name="in8" type="color3" nodename="switch9" />
18+
<input name="in9" type="color3" nodename="switch10" />
19+
<input name="in10" type="color3" nodename="switch11" />
20+
<input name="which" type="float" nodename="multiply1" />
21+
</switch>
22+
<texcoord name="texcoord1" type="vector2" nodedef="ND_texcoord_vector2" />
23+
<separate2 name="separate2_1" type="multioutput" nodedef="ND_separate2_vector2">
24+
<input name="in" type="vector2" nodename="texcoord1" />
25+
</separate2>
26+
<multiply name="multiply1" type="float" nodedef="ND_multiply_float">
27+
<input name="in2" type="float" value="5" />
28+
<input name="in1" type="float" nodename="add1" />
29+
</multiply>
30+
<position name="position1" type="vector3" nodedef="ND_position_vector3" />
31+
<separate3 name="separate3_1" type="multioutput" nodedef="ND_separate3_vector3">
32+
<input name="in" type="vector3" nodename="position1" />
33+
</separate3>
34+
<add name="add1" type="float" nodedef="ND_add_float">
35+
<input name="in1" type="float" nodename="separate3_1" output="outy" />
36+
<input name="in2" type="float" value="1" />
37+
</add>
38+
<switch name="switch2" type="color3" nodedef="ND_switch_color3">
39+
<input name="which" type="float" nodename="multiply3" />
40+
<input name="in1" type="color3" value="0.6425, 0.5324, 0.4798" colorspace="g18_rec709" />
41+
<input name="in2" type="color3" value="0.8591, 0.7447, 0.6878" colorspace="g18_rec709" />
42+
<input name="in3" type="color3" value="0.5879, 0.6639, 0.7638" colorspace="g18_rec709" />
43+
<input name="in4" type="color3" value="0.5502, 0.6205, 0.4759" colorspace="g18_rec709" />
44+
<input name="in5" type="color3" value="0.6965, 0.6819, 0.8164" colorspace="g18_rec709" />
45+
<input name="in6" type="color3" value="0.6043, 0.8467, 0.7983" colorspace="g18_rec709" />
46+
<input name="in7" type="color3" value="0.9072, 0.6759, 0.3768" colorspace="g18_rec709" />
47+
<input name="in8" type="color3" value="0.5252, 0.5641, 0.7878" colorspace="g18_rec709" />
48+
<input name="in9" type="color3" value="0.8566, 0.5607, 0.5912" colorspace="g18_rec709" />
49+
<input name="in10" type="color3" value="0.5744, 0.4476, 0.6205" colorspace="g18_rec709" />
50+
</switch>
51+
<texcoord name="texcoord2" type="vector2" nodedef="ND_texcoord_vector2" />
52+
<extract name="extract1" type="float" nodedef="ND_extract_vector2">
53+
<input name="in" type="vector2" nodename="texcoord2" />
54+
</extract>
55+
<multiply name="multiply2" type="float" nodedef="ND_multiply_float">
56+
<input name="in2" type="float" value="2" />
57+
<input name="in1" type="float" nodename="extract1" />
58+
</multiply>
59+
<trianglewave name="trianglewave1" type="float" nodedef="ND_trianglewave_float">
60+
<input name="in" type="float" nodename="multiply2" />
61+
</trianglewave>
62+
<multiply name="multiply3" type="float" nodedef="ND_multiply_float">
63+
<input name="in2" type="float" value="20" />
64+
<input name="in1" type="float" nodename="trianglewave1" />
65+
</multiply>
66+
<switch name="switch3" type="color3" nodedef="ND_switch_color3">
67+
<input name="in1" type="color3" value="0.6963, 0.5971, 0.5484" colorspace="g22_rec709" />
68+
<input name="in2" type="color3" value="0.8831, 0.7857, 0.7362" colorspace="g22_rec709" />
69+
<input name="in3" type="color3" value="0.6475, 0.7153, 0.8021" colorspace="g22_rec709" />
70+
<input name="in4" type="color3" value="0.6134, 0.6767, 0.5447" colorspace="g22_rec709" />
71+
<input name="in5" type="color3" value="0.7439, 0.7310, 0.8471" colorspace="g22_rec709" />
72+
<input name="in6" type="color3" value="0.6623, 0.8727, 0.8317" colorspace="g22_rec709" />
73+
<input name="in7" type="color3" value="0.9234, 0.7258, 0.4499" colorspace="g22_rec709" />
74+
<input name="in8" type="color3" value="0.5904, 0.6260, 0.8227" colorspace="g22_rec709" />
75+
<input name="in9" type="color3" value="0.8811, 0.6229, 0.6505" colorspace="g22_rec709" />
76+
<input name="in10" type="color3" value="0.6353, 0.5180, 0.6767" colorspace="g22_rec709" />
77+
<input name="which" type="float" nodename="multiply3" />
78+
</switch>
79+
<switch name="switch4" type="color3" nodedef="ND_switch_color3">
80+
<input name="in1" type="color3" value="0.7176, 0.6233, 0.5765" colorspace="rec709_display" />
81+
<input name="in2" type="color3" value="0.8923, 0.8016, 0.7552" colorspace="rec709_display" />
82+
<input name="in3" type="color3" value="0.6714, 0.7355, 0.8170" colorspace="rec709_display" />
83+
<input name="in4" type="color3" value="0.6389, 0.6991, 0.5730" colorspace="rec709_display" />
84+
<input name="in5" type="color3" value="0.7624, 0.7504, 0.8589" colorspace="rec709_display" />
85+
<input name="in6" type="color3" value="0.6854, 0.8827, 0.8446" colorspace="rec709_display" />
86+
<input name="in7" type="color3" value="0.9296, 0.7455, 0.4809" colorspace="rec709_display" />
87+
<input name="in8" type="color3" value="0.6169, 0.6509, 0.8362" colorspace="rec709_display" />
88+
<input name="in9" type="color3" value="0.8904, 0.6480, 0.6742" colorspace="rec709_display" />
89+
<input name="in10" type="color3" value="0.6598, 0.5472, 0.6991" colorspace="rec709_display" />
90+
<input name="which" type="float" nodename="multiply3" />
91+
</switch>
92+
<switch name="switch5" type="color3" nodedef="ND_switch_color3">
93+
<input name="in1" type="color3" value="0.3983, 0.3299, 0.2765" colorspace="acescg" />
94+
<input name="in2" type="color3" value="0.6903, 0.5993, 0.5236" colorspace="acescg" />
95+
<input name="in3" type="color3" value="0.4272, 0.4737, 0.5959" colorspace="acescg" />
96+
<input name="in4" type="color3" value="0.3654, 0.4156, 0.2820" colorspace="acescg" />
97+
<input name="in5" type="color3" value="0.5231, 0.5059, 0.6695" colorspace="acescg" />
98+
<input name="in6" type="color3" value="0.5309, 0.7165, 0.6694" colorspace="acescg" />
99+
<input name="in7" type="color3" value="0.6905, 0.5140, 0.2215" colorspace="acescg" />
100+
<input name="in8" type="color3" value="0.3444, 0.3578, 0.6118" colorspace="acescg" />
101+
<input name="in9" type="color3" value="0.6023, 0.3818, 0.3920" colorspace="acescg" />
102+
<input name="in10" type="color3" value="0.3260, 0.2472, 0.4018" colorspace="acescg" />
103+
<input name="which" type="float" nodename="multiply3" />
104+
</switch>
105+
<switch name="switch6" type="color3" nodedef="ND_switch_color3">
106+
<input name="in1" type="color3" value="0.6581, 0.6041, 0.5575" colorspace="g22_ap1" />
107+
<input name="in2" type="color3" value="0.8450, 0.7924, 0.7452" colorspace="g22_ap1" />
108+
<input name="in3" type="color3" value="0.6794, 0.7120, 0.7903" colorspace="g22_ap1" />
109+
<input name="in4" type="color3" value="0.6328, 0.6709, 0.5625" colorspace="g22_ap1" />
110+
<input name="in5" type="color3" value="0.7449, 0.7337, 0.8333" colorspace="g22_ap1" />
111+
<input name="in6" type="color3" value="0.7499, 0.8594, 0.8332" colorspace="g22_ap1" />
112+
<input name="in7" type="color3" value="0.8450, 0.7390, 0.5040" colorspace="g22_ap1" />
113+
<input name="in8" type="color3" value="0.6160, 0.6268, 0.7998" colorspace="g22_ap1" />
114+
<input name="in9" type="color3" value="0.7941, 0.6455, 0.6533" colorspace="g22_ap1" />
115+
<input name="in10" type="color3" value="0.6008, 0.5298, 0.6607" colorspace="g22_ap1" />
116+
<input name="which" type="float" nodename="multiply3" />
117+
</switch>
118+
<switch name="switch7" type="color3" nodedef="ND_switch_color3">
119+
<input name="in1" type="color3" value="0.7021, 0.6026, 0.5532" colorspace="srgb_texture" />
120+
<input name="in2" type="color3" value="0.8864, 0.7907, 0.7418" colorspace="srgb_texture" />
121+
<input name="in3" type="color3" value="0.6533, 0.7210, 0.8070" colorspace="srgb_texture" />
122+
<input name="in4" type="color3" value="0.6190, 0.6825, 0.5495" colorspace="srgb_texture" />
123+
<input name="in5" type="color3" value="0.7494, 0.7366, 0.8511" colorspace="srgb_texture" />
124+
<input name="in6" type="color3" value="0.6681, 0.8762, 0.8360" colorspace="srgb_texture" />
125+
<input name="in7" type="color3" value="0.9257, 0.7315, 0.4523" colorspace="srgb_texture" />
126+
<input name="in8" type="color3" value="0.5959, 0.6317, 0.8272" colorspace="srgb_texture" />
127+
<input name="in9" type="color3" value="0.8844, 0.6286, 0.6563" colorspace="srgb_texture" />
128+
<input name="in10" type="color3" value="0.6411, 0.5223, 0.6825" colorspace="srgb_texture" />
129+
<input name="which" type="float" nodename="multiply3" />
130+
</switch>
131+
<switch name="switch8" type="color3" nodedef="ND_switch_color3">
132+
<input name="in1" type="color3" value="0.4141, 0.3216, 0.2689" colorspace="lin_adobergb" />
133+
<input name="in2" type="color3" value="0.7116, 0.5882, 0.5130" colorspace="lin_adobergb" />
134+
<input name="in3" type="color3" value="0.4111, 0.4784, 0.6100" colorspace="lin_adobergb" />
135+
<input name="in4" type="color3" value="0.3646, 0.4235, 0.2694" colorspace="lin_adobergb" />
136+
<input name="in5" type="color3" value="0.5160, 0.5020, 0.6862" colorspace="lin_adobergb" />
137+
<input name="in6" type="color3" value="0.5000, 0.7412, 0.6697" colorspace="lin_adobergb" />
138+
<input name="in7" type="color3" value="0.7409, 0.4941, 0.1858" colorspace="lin_adobergb" />
139+
<input name="in8" type="color3" value="0.3260, 0.3569, 0.6389" colorspace="lin_adobergb" />
140+
<input name="in9" type="color3" value="0.6418, 0.3529, 0.3868" colorspace="lin_adobergb" />
141+
<input name="in10" type="color3" value="0.3306, 0.2353, 0.4158" colorspace="lin_adobergb" />
142+
<input name="which" type="float" nodename="multiply3" />
143+
</switch>
144+
<switch name="switch9" type="color3" nodedef="ND_switch_color3">
145+
<input name="in1" type="color3" value="0.6697, 0.5970, 0.5504" colorspace="adobergb" />
146+
<input name="in2" type="color3" value="0.8567, 0.7856, 0.7382" colorspace="adobergb" />
147+
<input name="in3" type="color3" value="0.6675, 0.7152, 0.7987" colorspace="adobergb" />
148+
<input name="in4" type="color3" value="0.6321, 0.6766, 0.5508" colorspace="adobergb" />
149+
<input name="in5" type="color3" value="0.7402, 0.7310, 0.8426" colorspace="adobergb" />
150+
<input name="in6" type="color3" value="0.7297, 0.8727, 0.8334" colorspace="adobergb" />
151+
<input name="in7" type="color3" value="0.8725, 0.7257, 0.4652" colorspace="adobergb" />
152+
<input name="in8" type="color3" value="0.6007, 0.6259, 0.8157" colorspace="adobergb" />
153+
<input name="in9" type="color3" value="0.8174, 0.6228, 0.6493" colorspace="adobergb" />
154+
<input name="in10" type="color3" value="0.6046, 0.5179, 0.6710" colorspace="adobergb" />
155+
<input name="which" type="float" nodename="multiply3" />
156+
</switch>
157+
<switch name="switch10" type="color3" nodedef="ND_switch_color3">
158+
<input name="in1" type="color3" value="0.6858, 0.6062, 0.5600" colorspace="srgb_displayp3" />
159+
<input name="in2" type="color3" value="0.8704, 0.7942, 0.7482" colorspace="srgb_displayp3" />
160+
<input name="in3" type="color3" value="0.6660, 0.7188, 0.7988" colorspace="srgb_displayp3" />
161+
<input name="in4" type="color3" value="0.6309, 0.6806, 0.5618" colorspace="srgb_displayp3" />
162+
<input name="in5" type="color3" value="0.7471, 0.7371, 0.8419" colorspace="srgb_displayp3" />
163+
<input name="in6" type="color3" value="0.7110, 0.8703, 0.8365" colorspace="srgb_displayp3" />
164+
<input name="in7" type="color3" value="0.8952, 0.7390, 0.4926" colorspace="srgb_displayp3" />
165+
<input name="in8" type="color3" value="0.6024, 0.6306, 0.8117" colorspace="srgb_displayp3" />
166+
<input name="in9" type="color3" value="0.8462, 0.6393, 0.6591" colorspace="srgb_displayp3" />
167+
<input name="in10" type="color3" value="0.6221, 0.5268, 0.6719" colorspace="srgb_displayp3" />
168+
<input name="which" type="float" nodename="multiply3" />
169+
</switch>
170+
<switch name="switch11" type="color3" nodedef="ND_switch_color3">
171+
<input name="in1" type="color3" value="0.4280, 0.3259, 0.2738" colorspace="lin_displayp3" />
172+
<input name="in2" type="color3" value="0.7302, 0.5940, 0.5198" colorspace="lin_displayp3" />
173+
<input name="in3" type="color3" value="0.4010, 0.4753, 0.6018" colorspace="lin_displayp3" />
174+
<input name="in4" type="color3" value="0.3558, 0.4208, 0.2757" colorspace="lin_displayp3" />
175+
<input name="in5" type="color3" value="0.5181, 0.5026, 0.6773" colorspace="lin_displayp3" />
176+
<input name="in6" type="color3" value="0.4638, 0.7300, 0.6676" colorspace="lin_displayp3" />
177+
<input name="in7" type="color3" value="0.7779, 0.5056, 0.2072" colorspace="lin_displayp3" />
178+
<input name="in8" type="color3" value="0.3214, 0.3554, 0.6239" colorspace="lin_displayp3" />
179+
<input name="in9" type="color3" value="0.6852, 0.3663, 0.3920" colorspace="lin_displayp3" />
180+
<input name="in10" type="color3" value="0.3450, 0.2397, 0.4090" colorspace="lin_displayp3" />
181+
<input name="which" type="float" nodename="multiply3" />
182+
</switch>
183+
</materialx>

0 commit comments

Comments
 (0)