mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2025-12-31 09:49:06 +03:00
Merge pull request #679 from Calinou/add-global-illumination-demo-2
Add a global illumination demo
This commit is contained in:
49
3d/global_illumination/README.md
Normal file
49
3d/global_illumination/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Global Illumination
|
||||
|
||||
This demo showcases Godot's global illumination systems:
|
||||
[GIProbe](https://docs.godotengine.org/en/stable/tutorials/3d/gi_probes.html),
|
||||
[BakedLightmap](https://docs.godotengine.org/en/stable/tutorials/3d/baked_lightmaps.html)
|
||||
(indirect only and fully baked) and
|
||||
[ReflectionProbe](https://docs.godotengine.org/en/stable/tutorials/3d/reflection_probes.html).
|
||||
|
||||
Use the mouse to look around, <kbd>W</kbd>/<kbd>A</kbd>/<kbd>S</kbd>/<kbd>D</kbd>
|
||||
or arrow keys to move.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: GLES 3[^1]
|
||||
|
||||
## How does it work?
|
||||
|
||||
A glTF scene (which acts as the level mesh) is imported with its **Light Baking**
|
||||
option set to **Gen Lightmaps**.
|
||||
This is required for BakedLightmap to work (but is not required for GIProbe
|
||||
or BakedLightmap).
|
||||
|
||||
The level mesh is duplicated several times to allow displaying it with various bake settings:
|
||||
|
||||
- No baking (uses GIProbe or environment lighting).
|
||||
- Baked indirect lighting. Slower, but allows for real-time shadows to display
|
||||
on baked surfaces.
|
||||
- Baked direct *and* indirect lighting. Faster, but does not allow for real-time
|
||||
shadows to display on baked surfaces.
|
||||
|
||||
A sphere and box are parented to the camera to showcase dynamic object lighting.
|
||||
A ReflectionProbe is parented to the sphere to showcase real-time reflections.
|
||||
When the ReflectionProbe is hidden, it is disabled. In this case,
|
||||
GIProbe or environment lighting will be used to provide fallback reflections.
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||
## Licenses
|
||||
|
||||
`zdm2.glb` is derived from the [Cube 2: Sauerbraten](http://sauerbraten.org/)
|
||||
map "zdm2" and is
|
||||
[licensed under CC BY 4.0 Unported](https://github.com/Calinou/game-maps-obj/blob/master/sauerbraten/zdm2.txt).
|
||||
The OBJ file which it was converted from is available in the [game-maps-obj](https://github.com/Calinou/game-maps-obj) repository.
|
||||
|
||||
[^1]: This demo can be made to work with GLES2, but GIProbe will not work.
|
||||
Additionally, lightmaps have to be rebaked with the **Atlas > Generate** property
|
||||
disabled in BakedLightmap.
|
||||
43
3d/global_illumination/camera.gd
Normal file
43
3d/global_illumination/camera.gd
Normal file
@@ -0,0 +1,43 @@
|
||||
extends Camera
|
||||
|
||||
const MOUSE_SENSITIVITY = 0.002
|
||||
const MOVE_SPEED = 1.5
|
||||
|
||||
var rot = Vector3()
|
||||
var velocity = Vector3()
|
||||
|
||||
|
||||
func _ready():
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
|
||||
func _input(event):
|
||||
# Mouse look (only if the mouse is captured).
|
||||
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
||||
# Horizontal mouse look.
|
||||
rot.y -= event.relative.x * MOUSE_SENSITIVITY
|
||||
# Vertical mouse look.
|
||||
rot.x = clamp(rot.x - event.relative.y * MOUSE_SENSITIVITY, -1.57, 1.57)
|
||||
transform.basis = Basis(rot)
|
||||
|
||||
if event.is_action_pressed("toggle_mouse_capture"):
|
||||
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
else:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
var motion = Vector3(
|
||||
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
|
||||
0,
|
||||
Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
|
||||
)
|
||||
|
||||
# Normalize motion to prevent diagonal movement from being
|
||||
# `sqrt(2)` times faster than straight movement.
|
||||
motion = motion.normalized()
|
||||
|
||||
velocity += MOVE_SPEED * delta * transform.basis.xform(motion)
|
||||
velocity *= 0.85
|
||||
translation += velocity
|
||||
BIN
3d/global_illumination/cube.blend
Normal file
BIN
3d/global_illumination/cube.blend
Normal file
Binary file not shown.
BIN
3d/global_illumination/cube.glb
Normal file
BIN
3d/global_illumination/cube.glb
Normal file
Binary file not shown.
1065
3d/global_illumination/cube.glb.import
Normal file
1065
3d/global_illumination/cube.glb.import
Normal file
File diff suppressed because it is too large
Load Diff
BIN
3d/global_illumination/cube.glb.unwrap_cache
Normal file
BIN
3d/global_illumination/cube.glb.unwrap_cache
Normal file
Binary file not shown.
13
3d/global_illumination/default_env.tres
Normal file
13
3d/global_illumination/default_env.tres
Normal file
@@ -0,0 +1,13 @@
|
||||
[gd_resource type="Environment" load_steps=2 format=2]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=1]
|
||||
sky_energy = 0.2
|
||||
ground_energy = 0.0
|
||||
|
||||
[resource]
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
||||
fog_sun_amount = 1.0
|
||||
fog_depth_begin = 0.0
|
||||
tonemap_mode = 2
|
||||
tonemap_white = 6.0
|
||||
BIN
3d/global_illumination/icon.png
Normal file
BIN
3d/global_illumination/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
35
3d/global_illumination/icon.png.import
Normal file
35
3d/global_illumination/icon.png.import
Normal file
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
73
3d/global_illumination/project.godot
Normal file
73
3d/global_illumination/project.godot
Normal file
@@ -0,0 +1,73 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=4
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Global Illumination"
|
||||
run/main_scene="res://test.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[display]
|
||||
|
||||
window/dpi/allow_hidpi=true
|
||||
window/stretch/mode="2d"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[input]
|
||||
|
||||
cycle_gi_mode={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
toggle_reflection_probe={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_forward={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":87,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777232,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_back={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777234,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":65,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777231,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":68,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777233,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
toggle_mouse_capture={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777253,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777217,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
common/enable_pause_aware_picking=true
|
||||
|
||||
[rendering]
|
||||
|
||||
quality/shadows/filter_mode=2
|
||||
environment/default_environment="res://default_env.tres"
|
||||
0
3d/global_illumination/screenshots/.gdignore
Normal file
0
3d/global_illumination/screenshots/.gdignore
Normal file
BIN
3d/global_illumination/screenshots/global_illumination.png
Normal file
BIN
3d/global_illumination/screenshots/global_illumination.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 240 KiB |
BIN
3d/global_illumination/test.exr
Normal file
BIN
3d/global_illumination/test.exr
Normal file
Binary file not shown.
25
3d/global_illumination/test.exr.import
Normal file
25
3d/global_illumination/test.exr.import
Normal file
@@ -0,0 +1,25 @@
|
||||
[remap]
|
||||
|
||||
importer="texture_array"
|
||||
type="TextureArray"
|
||||
path="res://.import/test.exr-c2074adc031b4eb62ef608033f6d937a.texarr"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://test.exr"
|
||||
dest_files=[ "res://.import/test.exr-c2074adc031b4eb62ef608033f6d937a.texarr" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/no_bptc_if_rgb=false
|
||||
flags/repeat=false
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=false
|
||||
slices/horizontal=1
|
||||
slices/vertical=1
|
||||
114
3d/global_illumination/test.gd
Normal file
114
3d/global_illumination/test.gd
Normal file
@@ -0,0 +1,114 @@
|
||||
extends Spatial
|
||||
|
||||
enum GIMode {
|
||||
NONE,
|
||||
BAKED_LIGHTMAP_ALL,
|
||||
BAKED_LIGHTMAP_INDIRECT,
|
||||
GI_PROBE,
|
||||
MAX, # Maximum value of the enum, used internally.
|
||||
}
|
||||
|
||||
# Keep this in sync with the GIMode enum (except for MAX).
|
||||
const GI_MODE_TEXTS = [
|
||||
"Environment Lighting (Fastest)",
|
||||
"Baked Lightmap All (Fast)",
|
||||
"Baked Lightmap Indirect (Average)",
|
||||
"GIProbe (Slow)",
|
||||
]
|
||||
|
||||
var gi_mode = GIMode.NONE
|
||||
var use_reflection_probe = false
|
||||
|
||||
onready var gi_mode_label = $GIMode
|
||||
onready var reflection_probe_mode_label = $ReflectionProbeMode
|
||||
onready var reflection_probe = $Camera/ReflectiveSphere/ReflectionProbe
|
||||
|
||||
|
||||
func _ready():
|
||||
set_gi_mode(GIMode.NONE)
|
||||
set_use_reflection_probe(false)
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("cycle_gi_mode"):
|
||||
set_gi_mode(wrapi(gi_mode + 1, 0, GIMode.MAX))
|
||||
|
||||
if event.is_action_pressed("toggle_reflection_probe"):
|
||||
set_use_reflection_probe(not use_reflection_probe)
|
||||
|
||||
|
||||
func set_gi_mode(p_gi_mode):
|
||||
gi_mode = p_gi_mode
|
||||
gi_mode_label.text = "Current GI mode: %s " % GI_MODE_TEXTS[gi_mode]
|
||||
|
||||
match p_gi_mode:
|
||||
GIMode.NONE:
|
||||
$ZdmBakeIndirect.visible = false
|
||||
$ZdmBakeAll.visible = false
|
||||
$ZdmNoBake.visible = true
|
||||
$BakedLightmapIndirect.visible = false
|
||||
$BakedLightmapAll.visible = false
|
||||
$GIProbe.visible = false
|
||||
|
||||
# There is no difference between Indirect and Disabled when no GI is used.
|
||||
# Pick the default value (which is Indirect).
|
||||
$Sun.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$GrateOmniLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$GarageOmniLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$CornerSpotLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
|
||||
GIMode.BAKED_LIGHTMAP_ALL:
|
||||
$ZdmBakeIndirect.visible = false
|
||||
$ZdmBakeAll.visible = true
|
||||
$ZdmNoBake.visible = false
|
||||
$BakedLightmapIndirect.visible = false
|
||||
$BakedLightmapAll.visible = true
|
||||
$GIProbe.visible = false
|
||||
|
||||
# Make lights not affect baked surfaces by setting their bake mode to All.
|
||||
$Sun.light_bake_mode = Light.BAKE_ALL
|
||||
$GrateOmniLight.light_bake_mode = Light.BAKE_ALL
|
||||
$GarageOmniLight.light_bake_mode = Light.BAKE_ALL
|
||||
$CornerSpotLight.light_bake_mode = Light.BAKE_ALL
|
||||
|
||||
GIMode.BAKED_LIGHTMAP_INDIRECT:
|
||||
$ZdmBakeIndirect.visible = true
|
||||
$ZdmBakeAll.visible = false
|
||||
$ZdmNoBake.visible = false
|
||||
$BakedLightmapIndirect.visible = true
|
||||
$BakedLightmapAll.visible = false
|
||||
$GIProbe.visible = false
|
||||
|
||||
$Sun.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$GrateOmniLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$GarageOmniLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$CornerSpotLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
|
||||
GIMode.GI_PROBE:
|
||||
$ZdmBakeIndirect.visible = false
|
||||
$ZdmBakeAll.visible = false
|
||||
$ZdmNoBake.visible = true
|
||||
$BakedLightmapIndirect.visible = false
|
||||
$BakedLightmapAll.visible = false
|
||||
$GIProbe.visible = true
|
||||
|
||||
# Bake mode must be Indirect, not Disabled. Otherwise, GI will
|
||||
# not be visible for those lights.
|
||||
# Moving/blinking lights should generally have their bake mode set to Disabled
|
||||
# to avoid visible GI pop-ins. This is because GIProbe
|
||||
# can take a while to update.
|
||||
$Sun.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$GrateOmniLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$GarageOmniLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
$CornerSpotLight.light_bake_mode = Light.BAKE_INDIRECT
|
||||
|
||||
|
||||
func set_use_reflection_probe(p_visible):
|
||||
use_reflection_probe = p_visible
|
||||
|
||||
if p_visible:
|
||||
reflection_probe_mode_label.text = "Current reflection probe mode: Enabled - Using reflection probe (Average)"
|
||||
else:
|
||||
reflection_probe_mode_label.text = "Current reflection probe mode: Disabled - Using environment or GIProbe reflections (Fast)"
|
||||
|
||||
reflection_probe.visible = p_visible
|
||||
BIN
3d/global_illumination/test.lmbake
Normal file
BIN
3d/global_illumination/test.lmbake
Normal file
Binary file not shown.
171
3d/global_illumination/test.tscn
Normal file
171
3d/global_illumination/test.tscn
Normal file
File diff suppressed because one or more lines are too long
BIN
3d/global_illumination/test_all.exr
Normal file
BIN
3d/global_illumination/test_all.exr
Normal file
Binary file not shown.
25
3d/global_illumination/test_all.exr.import
Normal file
25
3d/global_illumination/test_all.exr.import
Normal file
@@ -0,0 +1,25 @@
|
||||
[remap]
|
||||
|
||||
importer="texture_array"
|
||||
type="TextureArray"
|
||||
path="res://.import/test_all.exr-20e3b4b8c4ad01c2073fdca1a38f60ed.texarr"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://test_all.exr"
|
||||
dest_files=[ "res://.import/test_all.exr-20e3b4b8c4ad01c2073fdca1a38f60ed.texarr" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/no_bptc_if_rgb=false
|
||||
flags/repeat=false
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=false
|
||||
slices/horizontal=1
|
||||
slices/vertical=1
|
||||
BIN
3d/global_illumination/test_all.lmbake
Normal file
BIN
3d/global_illumination/test_all.lmbake
Normal file
Binary file not shown.
BIN
3d/global_illumination/zdm2.blend
Normal file
BIN
3d/global_illumination/zdm2.blend
Normal file
Binary file not shown.
BIN
3d/global_illumination/zdm2.glb
Normal file
BIN
3d/global_illumination/zdm2.glb
Normal file
Binary file not shown.
1065
3d/global_illumination/zdm2.glb.import
Normal file
1065
3d/global_illumination/zdm2.glb.import
Normal file
File diff suppressed because it is too large
Load Diff
BIN
3d/global_illumination/zdm2.glb.unwrap_cache
Normal file
BIN
3d/global_illumination/zdm2.glb.unwrap_cache
Normal file
Binary file not shown.
Reference in New Issue
Block a user