1 /** 2 Real-time global illumination (GI) probe. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.giprobe; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.visualinstance; 25 import godot.node; 26 import godot.giprobedata; 27 /** 28 Real-time global illumination (GI) probe. 29 30 $(D GIProbe)s are used to provide high-quality real-time indirect light to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. $(D GIProbe)s need to be baked before using, however, once baked, dynamic objects will receive light from them. Further, lights can be fully dynamic or baked. 31 Having $(D GIProbe)s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the $(D ProjectSettings) using $(D ProjectSettings.rendering/quality/voxelConeTracing/highQuality). 32 $(B Note:) Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh. 33 $(B Note:) Due to a renderer limitation, emissive $(D ShaderMaterial)s cannot emit light when used in a $(D GIProbe). Only emissive $(D SpatialMaterial)s can emit light in a $(D GIProbe). 34 */ 35 @GodotBaseClass struct GIProbe 36 { 37 package(godot) enum string _GODOT_internal_name = "GIProbe"; 38 public: 39 @nogc nothrow: 40 union { /** */ godot_object _godot_object; /** */ VisualInstance _GODOT_base; } 41 alias _GODOT_base this; 42 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 43 package(godot) __gshared bool _classBindingInitialized = false; 44 package(godot) static struct GDNativeClassBinding 45 { 46 __gshared: 47 @GodotName("bake") GodotMethod!(void, Node, bool) bake; 48 @GodotName("debug_bake") GodotMethod!(void) debugBake; 49 @GodotName("get_bias") GodotMethod!(double) getBias; 50 @GodotName("get_dynamic_range") GodotMethod!(long) getDynamicRange; 51 @GodotName("get_energy") GodotMethod!(double) getEnergy; 52 @GodotName("get_extents") GodotMethod!(Vector3) getExtents; 53 @GodotName("get_normal_bias") GodotMethod!(double) getNormalBias; 54 @GodotName("get_probe_data") GodotMethod!(GIProbeData) getProbeData; 55 @GodotName("get_propagation") GodotMethod!(double) getPropagation; 56 @GodotName("get_subdiv") GodotMethod!(GIProbe.Subdiv) getSubdiv; 57 @GodotName("is_compressed") GodotMethod!(bool) isCompressed; 58 @GodotName("is_interior") GodotMethod!(bool) isInterior; 59 @GodotName("set_bias") GodotMethod!(void, double) setBias; 60 @GodotName("set_compress") GodotMethod!(void, bool) setCompress; 61 @GodotName("set_dynamic_range") GodotMethod!(void, long) setDynamicRange; 62 @GodotName("set_energy") GodotMethod!(void, double) setEnergy; 63 @GodotName("set_extents") GodotMethod!(void, Vector3) setExtents; 64 @GodotName("set_interior") GodotMethod!(void, bool) setInterior; 65 @GodotName("set_normal_bias") GodotMethod!(void, double) setNormalBias; 66 @GodotName("set_probe_data") GodotMethod!(void, GIProbeData) setProbeData; 67 @GodotName("set_propagation") GodotMethod!(void, double) setPropagation; 68 @GodotName("set_subdiv") GodotMethod!(void, long) setSubdiv; 69 } 70 /// 71 pragma(inline, true) bool opEquals(in GIProbe other) const 72 { return _godot_object.ptr is other._godot_object.ptr; } 73 /// 74 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 75 { _godot_object.ptr = n; return null; } 76 /// 77 pragma(inline, true) bool opEquals(typeof(null) n) const 78 { return _godot_object.ptr is n; } 79 /// 80 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 81 mixin baseCasts; 82 /// Construct a new instance of GIProbe. 83 /// Note: use `memnew!GIProbe` instead. 84 static GIProbe _new() 85 { 86 static godot_class_constructor constructor; 87 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("GIProbe"); 88 if(constructor is null) return typeof(this).init; 89 return cast(GIProbe)(constructor()); 90 } 91 @disable new(size_t s); 92 /// 93 enum Subdiv : int 94 { 95 /** 96 Use 64 subdivisions. This is the lowest quality setting, but the fastest. Use it if you can, but especially use it on lower-end hardware. 97 */ 98 subdiv64 = 0, 99 /** 100 Use 128 subdivisions. This is the default quality setting. 101 */ 102 subdiv128 = 1, 103 /** 104 Use 256 subdivisions. 105 */ 106 subdiv256 = 2, 107 /** 108 Use 512 subdivisions. This is the highest quality setting, but the slowest. On lower-end hardware this could cause the GPU to stall. 109 */ 110 subdiv512 = 3, 111 /** 112 Represents the size of the $(D subdiv) enum. 113 */ 114 subdivMax = 4, 115 } 116 /// 117 enum Constants : int 118 { 119 subdiv64 = 0, 120 subdiv128 = 1, 121 subdiv256 = 2, 122 subdiv512 = 3, 123 subdivMax = 4, 124 } 125 /** 126 Bakes the effect from all $(D GeometryInstance)s marked with $(D GeometryInstance.useInBakedLight) and $(D Light)s marked with either $(D constant Light.BAKE_INDIRECT) or $(D constant Light.BAKE_ALL). If `create_visual_debug` is `true`, after baking the light, this will generate a $(D MultiMesh) that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the $(D GIProbe)'s data and debug any issues that may be occurring. 127 */ 128 void bake(Node from_node = Node.init, in bool create_visual_debug = false) 129 { 130 checkClassBinding!(typeof(this))(); 131 ptrcall!(void)(GDNativeClassBinding.bake, _godot_object, from_node, create_visual_debug); 132 } 133 /** 134 Calls $(D bake) with `create_visual_debug` enabled. 135 */ 136 void debugBake() 137 { 138 checkClassBinding!(typeof(this))(); 139 ptrcall!(void)(GDNativeClassBinding.debugBake, _godot_object); 140 } 141 /** 142 143 */ 144 double getBias() const 145 { 146 checkClassBinding!(typeof(this))(); 147 return ptrcall!(double)(GDNativeClassBinding.getBias, _godot_object); 148 } 149 /** 150 151 */ 152 long getDynamicRange() const 153 { 154 checkClassBinding!(typeof(this))(); 155 return ptrcall!(long)(GDNativeClassBinding.getDynamicRange, _godot_object); 156 } 157 /** 158 159 */ 160 double getEnergy() const 161 { 162 checkClassBinding!(typeof(this))(); 163 return ptrcall!(double)(GDNativeClassBinding.getEnergy, _godot_object); 164 } 165 /** 166 167 */ 168 Vector3 getExtents() const 169 { 170 checkClassBinding!(typeof(this))(); 171 return ptrcall!(Vector3)(GDNativeClassBinding.getExtents, _godot_object); 172 } 173 /** 174 175 */ 176 double getNormalBias() const 177 { 178 checkClassBinding!(typeof(this))(); 179 return ptrcall!(double)(GDNativeClassBinding.getNormalBias, _godot_object); 180 } 181 /** 182 183 */ 184 Ref!GIProbeData getProbeData() const 185 { 186 checkClassBinding!(typeof(this))(); 187 return ptrcall!(GIProbeData)(GDNativeClassBinding.getProbeData, _godot_object); 188 } 189 /** 190 191 */ 192 double getPropagation() const 193 { 194 checkClassBinding!(typeof(this))(); 195 return ptrcall!(double)(GDNativeClassBinding.getPropagation, _godot_object); 196 } 197 /** 198 199 */ 200 GIProbe.Subdiv getSubdiv() const 201 { 202 checkClassBinding!(typeof(this))(); 203 return ptrcall!(GIProbe.Subdiv)(GDNativeClassBinding.getSubdiv, _godot_object); 204 } 205 /** 206 207 */ 208 bool isCompressed() const 209 { 210 checkClassBinding!(typeof(this))(); 211 return ptrcall!(bool)(GDNativeClassBinding.isCompressed, _godot_object); 212 } 213 /** 214 215 */ 216 bool isInterior() const 217 { 218 checkClassBinding!(typeof(this))(); 219 return ptrcall!(bool)(GDNativeClassBinding.isInterior, _godot_object); 220 } 221 /** 222 223 */ 224 void setBias(in double max) 225 { 226 checkClassBinding!(typeof(this))(); 227 ptrcall!(void)(GDNativeClassBinding.setBias, _godot_object, max); 228 } 229 /** 230 231 */ 232 void setCompress(in bool enable) 233 { 234 checkClassBinding!(typeof(this))(); 235 ptrcall!(void)(GDNativeClassBinding.setCompress, _godot_object, enable); 236 } 237 /** 238 239 */ 240 void setDynamicRange(in long max) 241 { 242 checkClassBinding!(typeof(this))(); 243 ptrcall!(void)(GDNativeClassBinding.setDynamicRange, _godot_object, max); 244 } 245 /** 246 247 */ 248 void setEnergy(in double max) 249 { 250 checkClassBinding!(typeof(this))(); 251 ptrcall!(void)(GDNativeClassBinding.setEnergy, _godot_object, max); 252 } 253 /** 254 255 */ 256 void setExtents(in Vector3 extents) 257 { 258 checkClassBinding!(typeof(this))(); 259 ptrcall!(void)(GDNativeClassBinding.setExtents, _godot_object, extents); 260 } 261 /** 262 263 */ 264 void setInterior(in bool enable) 265 { 266 checkClassBinding!(typeof(this))(); 267 ptrcall!(void)(GDNativeClassBinding.setInterior, _godot_object, enable); 268 } 269 /** 270 271 */ 272 void setNormalBias(in double max) 273 { 274 checkClassBinding!(typeof(this))(); 275 ptrcall!(void)(GDNativeClassBinding.setNormalBias, _godot_object, max); 276 } 277 /** 278 279 */ 280 void setProbeData(GIProbeData data) 281 { 282 checkClassBinding!(typeof(this))(); 283 ptrcall!(void)(GDNativeClassBinding.setProbeData, _godot_object, data); 284 } 285 /** 286 287 */ 288 void setPropagation(in double max) 289 { 290 checkClassBinding!(typeof(this))(); 291 ptrcall!(void)(GDNativeClassBinding.setPropagation, _godot_object, max); 292 } 293 /** 294 295 */ 296 void setSubdiv(in long subdiv) 297 { 298 checkClassBinding!(typeof(this))(); 299 ptrcall!(void)(GDNativeClassBinding.setSubdiv, _godot_object, subdiv); 300 } 301 /** 302 Offsets the lookup of the light contribution from the $(D GIProbe). This can be used to avoid self-shadowing, but may introduce light leaking at higher values. This and $(D normalBias) should be played around with to minimize self-shadowing and light leaking. 303 $(B Note:) `bias` should usually be above 1.0 as that is the size of the voxels. 304 */ 305 @property double bias() 306 { 307 return getBias(); 308 } 309 /// ditto 310 @property void bias(double v) 311 { 312 setBias(v); 313 } 314 /** 315 If `true`, the data for this $(D GIProbe) will be compressed. Compression saves space, but results in far worse visual quality. 316 */ 317 @property bool compress() 318 { 319 return isCompressed(); 320 } 321 /// ditto 322 @property void compress(bool v) 323 { 324 setCompress(v); 325 } 326 /** 327 The $(D GIProbeData) resource that holds the data for this $(D GIProbe). 328 */ 329 @property GIProbeData data() 330 { 331 return getProbeData(); 332 } 333 /// ditto 334 @property void data(GIProbeData v) 335 { 336 setProbeData(v); 337 } 338 /** 339 The maximum brightness that the $(D GIProbe) will recognize. Brightness will be scaled within this range. 340 */ 341 @property long dynamicRange() 342 { 343 return getDynamicRange(); 344 } 345 /// ditto 346 @property void dynamicRange(long v) 347 { 348 setDynamicRange(v); 349 } 350 /** 351 Energy multiplier. Makes the lighting contribution from the $(D GIProbe) brighter. 352 */ 353 @property double energy() 354 { 355 return getEnergy(); 356 } 357 /// ditto 358 @property void energy(double v) 359 { 360 setEnergy(v); 361 } 362 /** 363 The size of the area covered by the $(D GIProbe). If you make the extents larger without increasing the subdivisions with $(D subdiv), the size of each cell will increase and result in lower detailed lighting. 364 */ 365 @property Vector3 extents() 366 { 367 return getExtents(); 368 } 369 /// ditto 370 @property void extents(Vector3 v) 371 { 372 setExtents(v); 373 } 374 /** 375 If `true`, ignores the sky contribution when calculating lighting. 376 */ 377 @property bool interior() 378 { 379 return isInterior(); 380 } 381 /// ditto 382 @property void interior(bool v) 383 { 384 setInterior(v); 385 } 386 /** 387 Offsets the lookup into the $(D GIProbe) based on the object's normal direction. Can be used to reduce some self-shadowing artifacts. 388 */ 389 @property double normalBias() 390 { 391 return getNormalBias(); 392 } 393 /// ditto 394 @property void normalBias(double v) 395 { 396 setNormalBias(v); 397 } 398 /** 399 How much light propagates through the probe internally. A higher value allows light to spread further. 400 */ 401 @property double propagation() 402 { 403 return getPropagation(); 404 } 405 /// ditto 406 @property void propagation(double v) 407 { 408 setPropagation(v); 409 } 410 /** 411 Number of times to subdivide the grid that the $(D GIProbe) operates on. A higher number results in finer detail and thus higher visual quality, while lower numbers result in better performance. 412 */ 413 @property GIProbe.Subdiv subdiv() 414 { 415 return getSubdiv(); 416 } 417 /// ditto 418 @property void subdiv(long v) 419 { 420 setSubdiv(v); 421 } 422 }