1 /* 2 * Copyright 2011-2013 Blender Foundation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __SHADER_H__ 18 #define __SHADER_H__ 19 20 #ifdef WITH_OSL 21 /* So no context pollution happens from indirectly included windows.h */ 22 # include "util/util_windows.h" 23 # include <OSL/oslexec.h> 24 #endif 25 26 #include "kernel/kernel_types.h" 27 #include "render/attribute.h" 28 29 #include "graph/node.h" 30 31 #include "util/util_map.h" 32 #include "util/util_param.h" 33 #include "util/util_string.h" 34 #include "util/util_thread.h" 35 #include "util/util_types.h" 36 37 CCL_NAMESPACE_BEGIN 38 39 class Device; 40 class DeviceScene; 41 class DeviceRequestedFeatures; 42 class Mesh; 43 class Progress; 44 class Scene; 45 class ShaderGraph; 46 struct float3; 47 48 enum ShadingSystem { SHADINGSYSTEM_OSL, SHADINGSYSTEM_SVM }; 49 50 /* Keep those in sync with the python-defined enum. */ 51 enum VolumeSampling { 52 VOLUME_SAMPLING_DISTANCE = 0, 53 VOLUME_SAMPLING_EQUIANGULAR = 1, 54 VOLUME_SAMPLING_MULTIPLE_IMPORTANCE = 2, 55 56 VOLUME_NUM_SAMPLING, 57 }; 58 59 enum VolumeInterpolation { 60 VOLUME_INTERPOLATION_LINEAR = 0, 61 VOLUME_INTERPOLATION_CUBIC = 1, 62 63 VOLUME_NUM_INTERPOLATION, 64 }; 65 66 enum DisplacementMethod { 67 DISPLACE_BUMP = 0, 68 DISPLACE_TRUE = 1, 69 DISPLACE_BOTH = 2, 70 71 DISPLACE_NUM_METHODS, 72 }; 73 74 /* Shader describing the appearance of a Mesh, Light or Background. 75 * 76 * While there is only a single shader graph, it has three outputs: surface, 77 * volume and displacement, that the shader manager will compile and execute 78 * separately. */ 79 80 class Shader : public Node { 81 public: 82 NODE_DECLARE 83 84 int pass_id; 85 86 /* shader graph */ 87 ShaderGraph *graph; 88 89 /* sampling */ 90 bool use_mis; 91 bool use_transparent_shadow; 92 bool heterogeneous_volume; 93 VolumeSampling volume_sampling_method; 94 int volume_interpolation_method; 95 float volume_step_rate; 96 float prev_volume_step_rate; 97 98 /* synchronization */ 99 bool need_update; 100 bool need_update_geometry; 101 102 /* If the shader has only volume components, the surface is assumed to 103 * be transparent. 104 * However, graph optimization might remove the volume subgraph, but 105 * since the user connected something to the volume output the surface 106 * should still be transparent. 107 * Therefore, has_volume_connected stores whether some volume sub-tree 108 * was connected before optimization. */ 109 bool has_volume_connected; 110 111 /* information about shader after compiling */ 112 bool has_surface; 113 bool has_surface_emission; 114 bool has_surface_transparent; 115 bool has_volume; 116 bool has_displacement; 117 bool has_surface_bssrdf; 118 bool has_bump; 119 bool has_bssrdf_bump; 120 bool has_surface_spatial_varying; 121 bool has_volume_spatial_varying; 122 bool has_volume_attribute_dependency; 123 bool has_integrator_dependency; 124 125 /* displacement */ 126 DisplacementMethod displacement_method; 127 128 /* requested mesh attributes */ 129 AttributeRequestSet attributes; 130 131 /* determined before compiling */ 132 uint id; 133 bool used; 134 135 #ifdef WITH_OSL 136 /* osl shading state references */ 137 OSL::ShaderGroupRef osl_surface_ref; 138 OSL::ShaderGroupRef osl_surface_bump_ref; 139 OSL::ShaderGroupRef osl_volume_ref; 140 OSL::ShaderGroupRef osl_displacement_ref; 141 #endif 142 143 Shader(); 144 ~Shader(); 145 146 /* Checks whether the shader consists of just a emission node with fixed inputs that's connected 147 * directly to the output. 148 * If yes, it sets the content of emission to the constant value (color * strength), which is 149 * then used for speeding up light evaluation. */ 150 bool is_constant_emission(float3 *emission); 151 152 void set_graph(ShaderGraph *graph); 153 void tag_update(Scene *scene); 154 void tag_used(Scene *scene); 155 }; 156 157 /* Shader Manager virtual base class 158 * 159 * From this the SVM and OSL shader managers are derived, that do the actual 160 * shader compiling and device updating. */ 161 162 class ShaderManager { 163 public: 164 bool need_update; 165 166 static ShaderManager *create(int shadingsystem); 167 virtual ~ShaderManager(); 168 169 virtual void reset(Scene *scene) = 0; 170 use_osl()171 virtual bool use_osl() 172 { 173 return false; 174 } 175 176 /* device update */ 177 virtual void device_update(Device *device, 178 DeviceScene *dscene, 179 Scene *scene, 180 Progress &progress) = 0; 181 virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene) = 0; 182 183 void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); 184 void device_free_common(Device *device, DeviceScene *dscene, Scene *scene); 185 186 /* get globally unique id for a type of attribute */ 187 uint get_attribute_id(ustring name); 188 uint get_attribute_id(AttributeStandard std); 189 190 /* get shader id for mesh faces */ 191 int get_shader_id(Shader *shader, bool smooth = false); 192 193 /* add default shaders to scene, to use as default for things that don't 194 * have any shader assigned explicitly */ 195 static void add_default(Scene *scene); 196 197 /* Selective nodes compilation. */ 198 void update_shaders_used(Scene *scene); 199 void get_requested_features(Scene *scene, DeviceRequestedFeatures *requested_features); 200 201 static void free_memory(); 202 203 float linear_rgb_to_gray(float3 c); 204 205 string get_cryptomatte_materials(Scene *scene); 206 207 protected: 208 ShaderManager(); 209 210 typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap; 211 AttributeIDMap unique_attribute_id; 212 213 static thread_mutex lookup_table_mutex; 214 static vector<float> beckmann_table; 215 static bool beckmann_table_ready; 216 217 size_t beckmann_table_offset; 218 219 void get_requested_graph_features(ShaderGraph *graph, 220 DeviceRequestedFeatures *requested_features); 221 222 thread_spin_lock attribute_lock_; 223 224 float3 xyz_to_r; 225 float3 xyz_to_g; 226 float3 xyz_to_b; 227 float3 rgb_to_y; 228 }; 229 230 CCL_NAMESPACE_END 231 232 #endif /* __SHADER_H__ */ 233