1
2//
3// This source file is part of appleseed.
4// Visit https://appleseedhq.net/ for additional information and resources.
5//
6// This software is released under the MIT license.
7//
8// Copyright (c) 2017 Luis Barrancos, The appleseedhq Organization
9//
10// Permission is hereby granted, free of charge, to any person obtaining a copy
11// of this software and associated documentation files (the "Software"), to deal
12// in the Software without restriction, including without limitation the rights
13// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14// copies of the Software, and to permit persons to whom the Software is
15// furnished to do so, subject to the following conditions:
16//
17// The above copyright notice and this permission notice shall be included in
18// all copies or substantial portions of the Software.
19//
20// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26// THE SOFTWARE.
27//
28
29// Ref: $MAYA_LOCATION/docs/Nodes/crater.html
30
31#include "appleseed/math/as_math_helpers.h"
32#include "appleseed/maya/as_maya_helpers.h"
33#include "appleseed/maya/as_maya_recurrence_helpers.h"
34#include "appleseed/maya/as_maya_transform_helpers.h"
35
36shader as_maya_crater
37[[
38    string as_node_name = "crater"
39]]
40(
41    float in_shaker = 1.5
42    [[
43        string as_maya_attribute_name = "shaker",
44        string as_maya_attribute_short_name = "sh",
45        float min = 0.0,
46        float softmax = 20.0,
47        string label = "Shaker",
48        string page = "Crater Attributes"
49    ]],
50    color in_channel1 = color(1, 0, 0)
51    [[
52        string as_maya_attribute_name = "channel1",
53        string as_maya_attribute_short_name = "c1",
54        string label = "Channel 1",
55        string page = "Crater Attributes"
56    ]],
57    color in_channel2 = color(0, 1, 0)
58    [[
59        string as_maya_attribute_name = "channel2",
60        string as_maya_attribute_short_name = "c2",
61        string label = "Channel 2",
62        string page = "Crater Attributes"
63    ]],
64    color in_channel3 = color(0, 0, 1)
65    [[
66        string as_maya_attribute_name = "channel3",
67        string as_maya_attribute_short_name = "c3",
68        string label = "Channel 3",
69        string page = "Crater Attributes"
70    ]],
71    float in_melt = 0.0
72    [[
73        string as_maya_attribute_name = "melt",
74        string as_maya_attribute_short_name = "m",
75        float min = 0.0,
76        float softmax = 1.0,
77        string label = "Melt",
78        string page = "Crater Attributes"
79    ]],
80    float in_balance = 0.0
81    [[
82        string as_maya_attribute_name = "balance",
83        string as_maya_attribute_short_name = "ba",
84        float min = 0.0,
85        float softmax = 1.0,
86        string label = "Balance",
87        string page = "Crater Attributes"
88    ]],
89    float in_frequency = 2.0
90    [[
91        string as_maya_attribute_name = "frequency",
92        string as_maya_attribute_short_name = "fr",
93        float min = 0.0,
94        float softmax = 10.0,
95        string label = "Frequency",
96        string page = "Crater Attributes"
97    ]],
98    float in_normDepth = 5.0
99    [[
100        string as_maya_attribute_name = "normDepth",
101        string as_maya_attribute_short_name = "nd",
102        float softmin = 0.0,
103        float softmax = 10.0,
104        string label = "Normal Depth",
105        string page = "Normal Options"
106    ]],
107    float in_normMelt = 0.0
108    [[
109        string as_maya_attribute_name = "normMelt",
110        string as_maya_attribute_short_name = "nm",
111        float min = 0.0,
112        float softmax = 1.0,
113        string label = "Normal Melt",
114        string page = "Normal Options"
115    ]],
116    float in_normBalance = 1.0
117    [[
118        string as_maya_attribute_name = "normBalance",
119        string as_maya_attribute_short_name = "nb",
120        float min = 0.0,
121        float softmax = 1.0,
122        string label = "Normal Balance",
123        string page = "Normal Options"
124    ]],
125    float in_normFrequency = 1.0
126    [[
127        string as_maya_attribute_name = "normFrequency",
128        string as_maya_attribute_short_name = "nf",
129        float min = 0.0,
130        float softmax = 10.0,
131        string label = "Normal Frequency",
132        string page = "Normal Options"
133    ]],
134    normal in_normalCamera = N
135    [[
136        string as_maya_attribute_name = "normalCamera",
137        string as_maya_attribute_short_name = "n",
138        string label = "Normal",
139        string widget = "null"
140    ]],
141    point in_refPointCamera = P
142    [[
143        string as_maya_attribute_name = "refPointCamera",
144        string as_maya_attribute_short_name = "rpc",
145        string label = "Surface Point",
146        string widget = "null"
147    ]],
148    matrix in_placementMatrix = matrix(1)
149    [[
150        string as_maya_attribute_name = "placementMatrix",
151        string label = "Placement Matrix",
152        string widget = "null"
153    ]],
154
155    MAYA_COLORBALANCE_PARAMETERS,
156    MAYA_EFFECTS_PARAMETERS,
157    MAYA_EFFECTS_3DTEX_PARAMETERS,
158
159    output color out_outColor = color(0)
160    [[
161        string as_maya_attribute_name = "outColor",
162        string as_maya_attribute_short_name = "oc",
163        string label = "Output Color",
164        string widget = "null"
165    ]],
166    output float out_outAlpha = 1.0
167    [[
168        string as_maya_attribute_name = "outAlpha",
169        string as_maya_attribute_short_name = "oa",
170        string label = "Output Alpha",
171        string widget = "null"
172    ]],
173    output normal out_outNormal = N
174    [[
175        string as_maya_attribute_name = "outNormal",
176        string as_maya_attribute_short_name = "o",
177        string label = "Output Normal",
178        string widget = "null"
179    ]]
180)
181{
182    matrix placement = (in_local)
183        ? matrix("common", "object") * in_placementMatrix
184        : in_placementMatrix;
185
186    point Pp = transform(placement, in_refPointCamera);
187
188    float box_blending = 0.0;
189
190    int outside_box = outside_place3d_volume(
191        Pp,
192        in_wrap,
193        in_blend,
194        box_blending);
195
196    if (outside_box)
197    {
198        out_outColor = in_defaultColor;
199        out_outAlpha = maya_luminance(out_outColor);
200        out_outNormal = in_normalCamera;
201
202        return;
203    }
204    else
205    {
206        // Output color.
207
208        float filter_width = 0.0;
209
210        if (in_filter > 0.0)
211        {
212            filter_width = in_filter * max(EPS, sqrt(area(Pp)));
213            filter_width += in_filterOffset;
214        }
215
216        float value = recurrenceN(
217            filter_width,
218            in_refPointCamera,
219            in_shaker,
220            in_melt);
221
222        float coeff = 1.0 / (in_balance + 1.0);
223
224        float m1 = sqr(sin(value * in_frequency));
225        float m2 = sqr(sqr(m1 - 1.0));
226
227        m1 = sqr(sqr(m1)) * in_balance * coeff;
228        m2 = (-m2 + 1.0) * coeff;
229
230        float p1 = m1 + m2;
231        float p2 = sqr(p1);
232
233        for (int i = 0; i < 3; ++i)
234        {
235            out_outColor[i] =
236                in_channel1[i] * (p2 - 2.0 * p1 + 1.0) +
237                in_channel2[i] * (2.0 * (p1 - p2)) +
238                in_channel3[i] * p2;
239
240            if (out_outColor[i] < 0.0)
241            {
242                out_outColor[i] = -out_outColor[i];
243
244                if (out_outColor[i] > 1.0)
245                    out_outColor[i] = 1.0;
246            }
247            else if (out_outColor[i] > 1.0)
248            {
249                out_outColor[i] = 2.0 - out_outColor[i];
250
251                if (out_outColor[i] < 0.0)
252                    out_outColor[i] = 0.0;
253            }
254        }
255        out_outAlpha = value;
256
257        // Output normal.
258
259        vector tmp_normal = recurrence3(
260            filter_width,
261            in_refPointCamera,
262            in_normDepth,
263            in_normMelt);
264
265        coeff = 1.0 / (in_normBalance + 1.0);
266
267        m1 = sqr(sin(value * in_normFrequency));
268        m2 = sqr(sqr(m1 - 1.0));
269
270        m1 = sqr(sqr(m1)) * in_normBalance * coeff;
271        m2 = (-m2 + 1.0) * coeff;
272
273        p1 = m1 + m2;
274        out_outNormal = (normal) tmp_normal * p1;
275
276        if (!in_wrap && in_blend)
277        {
278            out_outColor = mix(in_defaultColor, out_outColor, box_blending);
279            out_outAlpha *= box_blending;
280            out_outNormal *= box_blending;
281        }
282        out_outNormal = normalize(out_outNormal + in_normalCamera);
283
284        maya_colorBalance(
285            in_colorGain,
286            in_colorOffset,
287            in_defaultColor,
288            in_alphaGain,
289            in_alphaOffset,
290            in_invert,
291            in_alphaIsLuminance,
292            out_outColor,
293            out_outAlpha
294            );
295    }
296}
297