1/**************************************************************************/
2/* lightmapper.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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
31#ifndef LIGHTMAPPER_H
32#define LIGHTMAPPER_H
33
34#include "core/object/ref_counted.h"
35
36class Image;
37
38#if !defined(__aligned)
39
40#if defined(_WIN32) && defined(_MSC_VER)
41#define __aligned(...) __declspec(align(__VA_ARGS__))
42#else
43#define __aligned(...) __attribute__((aligned(__VA_ARGS__)))
44#endif
45
46#endif
47
48class LightmapDenoiser : public RefCounted {
49 GDCLASS(LightmapDenoiser, RefCounted)
50protected:
51 static LightmapDenoiser *(*create_function)();
52
53public:
54 virtual Ref<Image> denoise_image(const Ref<Image> &p_image) = 0;
55 static Ref<LightmapDenoiser> create();
56};
57
58class LightmapRaycaster : public RefCounted {
59 GDCLASS(LightmapRaycaster, RefCounted)
60protected:
61 static LightmapRaycaster *(*create_function)();
62
63public:
64 // compatible with embree3 rays
65 struct __aligned(16) Ray {
66 const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h
67
68 /*! Default construction does nothing. */
69 _FORCE_INLINE_ Ray() :
70 geomID(INVALID_GEOMETRY_ID) {}
71
72 /*! Constructs a ray from origin, direction, and ray segment. Near
73 * has to be smaller than far. */
74 _FORCE_INLINE_ Ray(const Vector3 &p_org,
75 const Vector3 &p_dir,
76 float p_tnear = 0.0f,
77 float p_tfar = INFINITY) :
78 org(p_org),
79 tnear(p_tnear),
80 dir(p_dir),
81 time(0.0f),
82 tfar(p_tfar),
83 mask(-1),
84 u(0.0),
85 v(0.0),
86 primID(INVALID_GEOMETRY_ID),
87 geomID(INVALID_GEOMETRY_ID),
88 instID(INVALID_GEOMETRY_ID) {}
89
90 /*! Tests if we hit something. */
91 _FORCE_INLINE_ explicit operator bool() const {
92 return geomID != INVALID_GEOMETRY_ID;
93 }
94
95 public:
96 Vector3 org; //!< Ray origin + tnear
97 float tnear; //!< Start of ray segment
98 Vector3 dir; //!< Ray direction + tfar
99 float time; //!< Time of this ray for motion blur.
100 float tfar; //!< End of ray segment
101 unsigned int mask; //!< used to mask out objects during traversal
102 unsigned int id; //!< ray ID
103 unsigned int flags; //!< ray flags
104
105 Vector3 normal; //!< Not normalized geometry normal
106 float u; //!< Barycentric u coordinate of hit
107 float v; //!< Barycentric v coordinate of hit
108 unsigned int primID; //!< primitive ID
109 unsigned int geomID; //!< geometry ID
110 unsigned int instID; //!< instance ID
111 };
112
113 virtual bool intersect(Ray &p_ray) = 0;
114
115 virtual void intersect(Vector<Ray> &r_rays) = 0;
116
117 virtual void add_mesh(const Vector<Vector3> &p_vertices, const Vector<Vector3> &p_normals, const Vector<Vector2> &p_uv2s, unsigned int p_id) = 0;
118 virtual void set_mesh_alpha_texture(Ref<Image> p_alpha_texture, unsigned int p_id) = 0;
119 virtual void commit() = 0;
120
121 virtual void set_mesh_filter(const HashSet<int> &p_mesh_ids) = 0;
122 virtual void clear_mesh_filter() = 0;
123
124 static Ref<LightmapRaycaster> create();
125};
126
127class Lightmapper : public RefCounted {
128 GDCLASS(Lightmapper, RefCounted)
129public:
130 enum GenerateProbes {
131 GENERATE_PROBES_DISABLED,
132 GENERATE_PROBES_SUBDIV_4,
133 GENERATE_PROBES_SUBDIV_8,
134 GENERATE_PROBES_SUBDIV_16,
135 GENERATE_PROBES_SUBDIV_32,
136
137 };
138
139 enum LightType {
140 LIGHT_TYPE_DIRECTIONAL,
141 LIGHT_TYPE_OMNI,
142 LIGHT_TYPE_SPOT
143 };
144
145 enum BakeError {
146 BAKE_ERROR_LIGHTMAP_TOO_SMALL,
147 BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES,
148 BAKE_OK
149 };
150
151 enum BakeQuality {
152 BAKE_QUALITY_LOW,
153 BAKE_QUALITY_MEDIUM,
154 BAKE_QUALITY_HIGH,
155 BAKE_QUALITY_ULTRA,
156 };
157
158 typedef Lightmapper *(*CreateFunc)();
159
160 static CreateFunc create_custom;
161 static CreateFunc create_gpu;
162 static CreateFunc create_cpu;
163
164protected:
165public:
166 typedef bool (*BakeStepFunc)(float, const String &, void *, bool); //step index, step total, step description, userdata
167
168 struct MeshData {
169 //triangle data
170 Vector<Vector3> points;
171 Vector<Vector2> uv2;
172 Vector<Vector3> normal;
173 Ref<Image> albedo_on_uv2;
174 Ref<Image> emission_on_uv2;
175 Variant userdata;
176 };
177
178 virtual void add_mesh(const MeshData &p_mesh) = 0;
179 virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance, float p_shadow_blur) = 0;
180 virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) = 0;
181 virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) = 0;
182 virtual void add_probe(const Vector3 &p_position) = 0;
183 virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0;
184
185 virtual int get_bake_texture_count() const = 0;
186 virtual Ref<Image> get_bake_texture(int p_index) const = 0;
187 virtual int get_bake_mesh_count() const = 0;
188 virtual Variant get_bake_mesh_userdata(int p_index) const = 0;
189 virtual Rect2 get_bake_mesh_uv_scale(int p_index) const = 0;
190 virtual int get_bake_mesh_texture_slice(int p_index) const = 0;
191 virtual int get_bake_probe_count() const = 0;
192 virtual Vector3 get_bake_probe_point(int p_probe) const = 0;
193 virtual Vector<Color> get_bake_probe_sh(int p_probe) const = 0;
194
195 static Ref<Lightmapper> create();
196
197 Lightmapper();
198};
199
200#endif // LIGHTMAPPER_H
201