1 /*************************************************************************/ 2 /* baked_light_baker.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 #ifndef BAKED_LIGHT_BAKER_H 31 #define BAKED_LIGHT_BAKER_H 32 33 #include "os/thread.h" 34 #include "scene/3d/baked_light_instance.h" 35 #include "scene/3d/light.h" 36 #include "scene/3d/mesh_instance.h" 37 38 class BakedLightBaker { 39 public: 40 enum { 41 42 ATTENUATION_CURVE_LEN = 256, 43 OCTANT_POOL_CHUNK = 1000000 44 }; 45 46 //struct OctantLight { 47 48 // double accum[8][3]; 49 //}; 50 51 struct Octant { 52 bool leaf; 53 AABB aabb; 54 uint16_t texture_x; 55 uint16_t texture_y; 56 int sampler_ofs; 57 float normal_accum[8][3]; 58 double full_accum[3]; 59 int parent; 60 union { 61 struct { 62 int next_leaf; 63 float offset[3]; 64 int bake_neighbour; 65 bool first_neighbour; 66 double light_accum[8][3]; 67 }; 68 int children[8]; 69 }; 70 }; 71 72 struct OctantHash { 73 74 int next; 75 uint32_t hash; 76 uint64_t value; 77 }; 78 79 struct MeshTexture { 80 81 Vector<uint8_t> tex; 82 int tex_w, tex_h; 83 get_colorMeshTexture84 _FORCE_INLINE_ void get_color(const Vector2 &p_uv, Color &ret) { 85 86 if (tex_w && tex_h) { 87 88 int x = Math::fast_ftoi(Math::fposmod(p_uv.x, 1.0) * tex_w); 89 int y = Math::fast_ftoi(Math::fposmod(p_uv.y, 1.0) * tex_w); 90 x = CLAMP(x, 0, tex_w - 1); 91 y = CLAMP(y, 0, tex_h - 1); 92 const uint8_t *ptr = &tex[(y * tex_w + x) * 4]; 93 ret.r *= ptr[0] / 255.0; 94 ret.g *= ptr[1] / 255.0; 95 ret.b *= ptr[2] / 255.0; 96 ret.a *= ptr[3] / 255.0; 97 } 98 } 99 }; 100 101 struct Param { 102 103 Color color; 104 MeshTexture *tex; get_colorParam105 _FORCE_INLINE_ Color get_color(const Vector2 &p_uv) { 106 107 Color ret = color; 108 if (tex) 109 tex->get_color(p_uv, ret); 110 return ret; 111 } 112 }; 113 114 struct MeshMaterial { 115 116 Param diffuse; 117 Param specular; 118 Param emission; 119 }; 120 121 struct Triangle { 122 123 AABB aabb; 124 Vector3 vertices[3]; 125 Vector2 uvs[3]; 126 Vector2 bake_uvs[3]; 127 Vector3 normals[3]; 128 MeshMaterial *material; 129 int baked_texture; 130 get_uvTriangle131 _FORCE_INLINE_ Vector2 get_uv(const Vector3 &p_pos) { 132 133 Vector3 v0 = vertices[1] - vertices[0]; 134 Vector3 v1 = vertices[2] - vertices[0]; 135 Vector3 v2 = p_pos - vertices[0]; 136 137 float d00 = v0.dot(v0); 138 float d01 = v0.dot(v1); 139 float d11 = v1.dot(v1); 140 float d20 = v2.dot(v0); 141 float d21 = v2.dot(v1); 142 float denom = (d00 * d11 - d01 * d01); 143 if (denom == 0) 144 return uvs[0]; 145 float v = (d11 * d20 - d01 * d21) / denom; 146 float w = (d00 * d21 - d01 * d20) / denom; 147 float u = 1.0f - v - w; 148 149 return uvs[0] * u + uvs[1] * v + uvs[2] * w; 150 } 151 get_uv_and_normalTriangle152 _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, Vector2 &r_uv, Vector3 &r_normal) { 153 154 Vector3 v0 = vertices[1] - vertices[0]; 155 Vector3 v1 = vertices[2] - vertices[0]; 156 Vector3 v2 = p_pos - vertices[0]; 157 158 float d00 = v0.dot(v0); 159 float d01 = v0.dot(v1); 160 float d11 = v1.dot(v1); 161 float d20 = v2.dot(v0); 162 float d21 = v2.dot(v1); 163 float denom = (d00 * d11 - d01 * d01); 164 if (denom == 0) { 165 r_normal = normals[0]; 166 r_uv = uvs[0]; 167 return; 168 } 169 float v = (d11 * d20 - d01 * d21) / denom; 170 float w = (d00 * d21 - d01 * d20) / denom; 171 float u = 1.0f - v - w; 172 173 r_uv = uvs[0] * u + uvs[1] * v + uvs[2] * w; 174 r_normal = (normals[0] * u + normals[1] * v + normals[2] * w).normalized(); 175 } 176 }; 177 178 struct BVH { 179 180 AABB aabb; 181 Vector3 center; 182 Triangle *leaf; 183 BVH *children[2]; 184 }; 185 186 struct BVHCmpX { 187 operatorBVHCmpX188 bool operator()(const BVH *p_left, const BVH *p_right) const { 189 190 return p_left->center.x < p_right->center.x; 191 } 192 }; 193 194 struct BVHCmpY { 195 operatorBVHCmpY196 bool operator()(const BVH *p_left, const BVH *p_right) const { 197 198 return p_left->center.y < p_right->center.y; 199 } 200 }; 201 struct BVHCmpZ { 202 operatorBVHCmpZ203 bool operator()(const BVH *p_left, const BVH *p_right) const { 204 205 return p_left->center.z < p_right->center.z; 206 } 207 }; 208 209 struct BakeTexture { 210 211 Vector<uint8_t> data; 212 int width, height; 213 }; 214 215 struct LightData { 216 217 VS::LightType type; 218 219 Vector3 pos; 220 Vector3 up; 221 Vector3 left; 222 Vector3 dir; 223 Color diffuse; 224 Color specular; 225 float energy; 226 float length; 227 int rays_thrown; 228 bool bake_shadow; 229 230 float radius; 231 float attenuation; 232 float spot_angle; 233 float darkening; 234 float spot_attenuation; 235 float area; 236 237 float constant; 238 239 bool bake_direct; 240 241 Vector<float> attenuation_table; 242 }; 243 244 Vector<LightData> lights; 245 246 List<MeshMaterial> materials; 247 List<MeshTexture> textures; 248 249 AABB octree_aabb; 250 Vector<Octant> octant_pool; 251 int octant_pool_size; 252 BVH *bvh; 253 Vector<Triangle> triangles; 254 Vector<BakeTexture> baked_textures; 255 Transform base_inv; 256 int leaf_list; 257 int octree_depth; 258 int bvh_depth; 259 int cell_count; 260 uint32_t *ray_stack; 261 BVH **bvh_stack; 262 uint32_t *octant_stack; 263 uint32_t *octantptr_stack; 264 265 struct ThreadStack { 266 uint32_t *octant_stack; 267 uint32_t *octantptr_stack; 268 uint32_t *ray_stack; 269 BVH **bvh_stack; 270 }; 271 272 Map<Vector3, Vector3> endpoint_normal; 273 Map<Vector3, uint64_t> endpoint_normal_bits; 274 275 float cell_size; 276 float plot_size; //multiplied by cell size 277 float octree_extra_margin; 278 279 int max_bounces; 280 int64_t total_rays; 281 bool use_diffuse; 282 bool use_specular; 283 bool use_translucency; 284 bool linear_color; 285 286 int baked_octree_texture_w; 287 int baked_octree_texture_h; 288 int baked_light_texture_w; 289 int baked_light_texture_h; 290 int lattice_size; 291 float edge_damp; 292 float normal_damp; 293 float tint; 294 float ao_radius; 295 float ao_strength; 296 297 bool paused; 298 bool baking; 299 bool first_bake_to_map; 300 301 Map<Ref<Material>, MeshMaterial *> mat_map; 302 Map<Ref<Texture>, MeshTexture *> tex_map; 303 304 MeshTexture *_get_mat_tex(const Ref<Texture> &p_tex); 305 void _add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_mat_override, const Transform &p_xform, int p_baked_texture = -1); 306 void _parse_geometry(Node *p_node); 307 BVH *_parse_bvh(BVH **p_children, int p_size, int p_depth, int &max_depth); 308 void _make_bvh(); 309 void _make_octree(); 310 void _make_octree_texture(); 311 void _octree_insert(int p_octant, Triangle *p_triangle, int p_depth); 312 _FORCE_INLINE_ void _plot_pixel_to_lightmap(int x, int y, int width, int height, uint8_t *image, const Vector3 &p_pos, const Vector3 &p_normal, double *p_norm_ptr, float mult, float gamma); 313 314 void _free_bvh(BVH *p_bvh); 315 316 void _fix_lights(); 317 318 Ref<BakedLight> baked_light; 319 320 //void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,int p_octant=0); 321 void _plot_light(ThreadStack &thread_stack, const Vector3 &p_plot_pos, const AABB &p_plot_aabb, const Color &p_light, const Color &p_tint_light, bool p_only_full, const Plane &p_plane); 322 //void _plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light); 323 324 float _throw_ray(ThreadStack &thread_stack, bool p_bake_direct, const Vector3 &p_begin, const Vector3 &p_end, float p_rest, const Color &p_light, float *p_att_curve, float p_att_pos, int p_att_curve_len, int p_bounces, bool p_first_bounce = false, bool p_only_dist = false); 325 326 float total_light_area; 327 328 Vector<Thread *> threads; 329 330 bool bake_thread_exit; 331 static void _bake_thread_func(void *arg); 332 333 void _start_thread(); 334 void _stop_thread(); 335 336 public: 337 void throw_rays(ThreadStack &thread_stack, int p_amount); 338 double get_normalization(int p_light_idx) const; 339 double get_modifier(int p_light_idx) const; 340 341 void bake(const Ref<BakedLight> &p_light, Node *p_base); 342 bool is_baking(); 343 void set_pause(bool p_pause); 344 bool is_paused(); get_rays_thrown()345 uint64_t get_rays_thrown() { return total_rays; } 346 347 Error transfer_to_lightmaps(); 348 349 void update_octree_sampler(DVector<int> &p_sampler); 350 void update_octree_images(DVector<uint8_t> &p_octree, DVector<uint8_t> &p_light); 351 get_baked_light()352 Ref<BakedLight> get_baked_light() { return baked_light; } 353 354 void clear(); 355 356 BakedLightBaker(); 357 ~BakedLightBaker(); 358 }; 359 360 #endif // BAKED_LIGHT_BAKER_H 361