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