added clearcoat implementation
[blender.git] / intern / cycles / kernel / osl / osl_closures.h
1 /*
2  * Adapted from Open Shading Language with this license:
3  *
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011, Blender Foundation.
8  * 
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  * * Redistributions of source code must retain the above copyright
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in the
16  *   documentation and/or other materials provided with the distribution.
17  * * Neither the name of Sony Pictures Imageworks nor the names of its
18  *   contributors may be used to endorse or promote products derived from
19  *   this software without specific prior written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifndef __OSL_CLOSURES_H__
34 #define __OSL_CLOSURES_H__
35
36 #include "util_types.h"
37 #include "kernel_types.h"
38
39 #include <OSL/oslclosure.h>
40 #include <OSL/oslexec.h>
41 #include <OSL/genclosure.h>
42
43 CCL_NAMESPACE_BEGIN
44
45 OSL::ClosureParam *closure_emission_params();
46 OSL::ClosureParam *closure_background_params();
47 OSL::ClosureParam *closure_holdout_params();
48 OSL::ClosureParam *closure_ambient_occlusion_params();
49 OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
50 OSL::ClosureParam *closure_bsdf_phong_ramp_params();
51 OSL::ClosureParam *closure_bssrdf_cubic_params();
52 OSL::ClosureParam *closure_bssrdf_gaussian_params();
53 OSL::ClosureParam *closure_bssrdf_burley_params();
54 OSL::ClosureParam *closure_henyey_greenstein_volume_params();
55 OSL::ClosureParam *closure_bsdf_disney_diffuse_params();
56 OSL::ClosureParam *closure_bsdf_disney_specular_params();
57 OSL::ClosureParam *closure_bsdf_disney_clearcoat_params();
58
59 void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
60 void closure_background_prepare(OSL::RendererServices *, int id, void *data);
61 void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
62 void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
63 void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
64 void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
65 void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data);
66 void closure_bssrdf_gaussian_prepare(OSL::RendererServices *, int id, void *data);
67 void closure_bssrdf_burley_prepare(OSL::RendererServices *, int id, void *data);
68 void closure_henyey_greenstein_volume_prepare(OSL::RendererServices *, int id, void *data);
69 void closure_bsdf_disney_diffuse_prepare(OSL::RendererServices *, int id, void *data);
70 void closure_bsdf_disney_specular_prepare(OSL::RendererServices *, int id, void *data);
71 void closure_bsdf_disney_clearcoat_prepare(OSL::RendererServices *, int id, void *data);
72
73 #define CCLOSURE_PREPARE(name, classname)          \
74 void name(RendererServices *, int id, void *data) \
75 {                                                 \
76         memset(data, 0, sizeof(classname));           \
77         new (data) classname();                       \
78 }
79
80 #define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname)
81
82 #define CLOSURE_FLOAT3_PARAM(st, fld) \
83         { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
84
85 #define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
86 #define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
87 #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
88
89 /* Closure */
90
91 class CClosurePrimitive {
92 public:
93         enum Category {
94                 BSDF,             ///< Reflective and/or transmissive surface
95                 BSSRDF,           ///< Sub-surface light transfer
96                 Emissive,         ///< Light emission
97                 Background,       ///< Background emission
98                 Volume,           ///< Volume scattering
99                 Holdout,          ///< Holdout from alpha
100                 AmbientOcclusion, ///< Ambient occlusion
101         };
102
103         CClosurePrimitive (Category category_) : category (category_) {}
104         virtual ~CClosurePrimitive() {}
105         virtual void setup() {}
106
107         Category category;
108
109         OSL::ustring label;
110 };
111
112 /* BSDF */
113
114 class CBSDFClosure : public CClosurePrimitive {
115 public:
116         ShaderClosure sc;
117
118         CBSDFClosure(int scattering) : CClosurePrimitive(BSDF),
119           m_scattering_label(scattering), m_shaderdata_flag(0)
120         {}
121
122         int scattering() const { return m_scattering_label; }
123         int shaderdata_flag() const { return m_shaderdata_flag; }
124
125         virtual void blur(float roughness) = 0;
126         virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
127         virtual float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
128
129         virtual int sample(const float3 &Ng,
130                            const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
131                            float randu, float randv,
132                            float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
133                            float &pdf, float3 &eval) const = 0;
134
135 protected:
136         int m_scattering_label;
137         int m_shaderdata_flag;
138 };
139
140 #define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, svmlower, TYPE) \
141 \
142 class Upper##Closure : public CBSDFClosure { \
143 public: \
144         Upper##Closure() : CBSDFClosure(TYPE) \
145         { \
146         } \
147 \
148         void setup() \
149         { \
150                 sc.prim = NULL; \
151                 m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
152         } \
153 \
154         void blur(float roughness) \
155         { \
156         } \
157 \
158         float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const \
159         { \
160                 pdf = 0.0f; \
161                 return make_float3(0.0f, 0.0f, 0.0f); \
162         } \
163 \
164         float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const \
165         { \
166                 pdf = 0.0f; \
167                 return make_float3(0.0f, 0.0f, 0.0f); \
168         } \
169 \
170         int sample(const float3 &Ng, \
171                    const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, \
172                    float randu, float randv, \
173                    float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, \
174                    float &pdf, float3 &eval) const \
175         { \
176                 pdf = 0; \
177                 return LABEL_NONE; \
178         } \
179 }; \
180 \
181 static ClosureParam *bsdf_##lower##_params() \
182 { \
183         static ClosureParam params[] = {
184
185 /* parameters */
186
187 #define BSDF_CLOSURE_CLASS_END(Upper, lower) \
188                 CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \
189                 CLOSURE_FINISH_PARAM(Upper##Closure) \
190         }; \
191         return params; \
192 } \
193 \
194 CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
195
196
197 /* Volume */
198
199 class CVolumeClosure : public CClosurePrimitive {
200 public:
201         ShaderClosure sc;
202
203         CVolumeClosure(int scattering) : CClosurePrimitive(Volume),
204           m_scattering_label(scattering), m_shaderdata_flag(0)
205         {}
206         ~CVolumeClosure() { }
207
208         int scattering() const { return m_scattering_label; }
209         int shaderdata_flag() const { return m_shaderdata_flag; }
210
211 protected:
212         int m_scattering_label;
213         int m_shaderdata_flag;
214 };
215
216 #define VOLUME_CLOSURE_CLASS_BEGIN(Upper, lower, TYPE) \
217 \
218 class Upper##Closure : public CVolumeClosure { \
219 public: \
220         Upper##Closure() : CVolumeClosure(TYPE) {} \
221 \
222         void setup() \
223         { \
224                 sc.prim = NULL; \
225                 m_shaderdata_flag = volume_##lower##_setup(&sc); \
226         } \
227 }; \
228 \
229 static ClosureParam *volume_##lower##_params() \
230 { \
231         static ClosureParam params[] = {
232
233 /* parameters */
234
235 #define VOLUME_CLOSURE_CLASS_END(Upper, lower) \
236                 CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \
237                 CLOSURE_FINISH_PARAM(Upper##Closure) \
238         }; \
239         return params; \
240 } \
241 \
242 CCLOSURE_PREPARE_STATIC(volume_##lower##_prepare, Upper##Closure)
243
244 CCL_NAMESPACE_END
245
246 #endif /* __OSL_CLOSURES_H__ */
247