Merge pull request #718 from Calinou/add-global-illumination-demo-2-4.0

Add a global illumination demo (4.0-dev)
This commit is contained in:
Aaron Franke
2022-04-25 00:04:18 -04:00
committed by GitHub
20 changed files with 244 additions and 2346 deletions

View File

@@ -1,39 +1,21 @@
# 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).
VoxelGI, SDFGI, ReflectionProbe and screen-space effects like SSAO and SSIL.
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]
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/1290
Renderer: Vulkan
## 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.
VoxelGI, SDFGI or environment lighting will be used to provide fallback reflections.
## Screenshots
@@ -45,7 +27,3 @@ GIProbe or environment lighting will be used to provide fallback reflections.
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.

View File

@@ -18,7 +18,7 @@ func _input(event):
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)
transform.basis = Basis.from_euler(rot)
if event.is_action_pressed("toggle_mouse_capture"):
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
@@ -29,9 +29,9 @@ func _input(event):
func _process(delta):
var motion = Vector3(
Input.get_axis(&"move_left", &"move_right"),
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
0,
Input.get_axis(&"move_forward", &"move_back")
Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
)
# Normalize motion to prevent diagonal movement from being

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="Sky" id=1]
[sub_resource type="ProceduralSky" id=1]
sky_energy = 0.2
ground_energy = 0.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -2,6 +2,7 @@
importer="texture"
type="StreamTexture2D"
uid="uid://q2k8m14vo3kr"
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
@@ -16,20 +17,18 @@ dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ste
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
compress/channel_pack=0
compress/streamed=false
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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
process/HDR_as_SRGB=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -6,60 +6,69 @@
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
config_version=5
[application]
config/name="Global Illumination"
run/main_scene="res://test.tscn"
config/icon="res://icon.png"
config/features=PackedStringArray("4.0")
[display]
window/dpi/allow_hidpi=true
window/stretch/mode="2d"
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"
[filesystem]
import/blender/enabled=false
[input]
cycle_gi_mode={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"unicode":0,"echo":false,"script":null)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"unicode":0,"echo":false,"script":null)
]
}
toggle_reflection_probe={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"unicode":0,"echo":false,"script":null)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"unicode":0,"echo":false,"script":null)
]
}
cycle_ssil_mode={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"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)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":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)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":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)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":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)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":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)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":16777217,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":16777253,"unicode":0,"echo":false,"script":null)
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

View File

@@ -1,25 +0,0 @@
[remap]
importer="texture_array"
type="Texture2DArray"
path="res://.godot/imported/test.exr-c2074adc031b4eb62ef608033f6d937a.texarr"
metadata={
"vram_texture": false
}
[deps]
source_file="res://test.exr"
dest_files=["res://.godot/imported/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

View File

@@ -2,31 +2,53 @@ extends Node3D
enum GIMode {
NONE,
BAKED_LIGHTMAP_ALL,
BAKED_LIGHTMAP_INDIRECT,
GI_PROBE,
# BAKED_LIGHTMAP_ALL,
# BAKED_LIGHTMAP_INDIRECT,
VOXEL_GI,
SDFGI,
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)",
# "Baked Lightmap All (Fast)",
# "Baked Lightmap Indirect (Average)",
"VoxelGI (Slow)",
"SDFGI (Slow)",
]
enum SSILMode {
NONE,
SSAO,
SSIL,
SSAO_AND_SSIL,
MAX, # Maximum value of the enum, used internally.
}
# Keep this in sync with the SSILMode enum (except for MAX).
const SSIL_MODE_TEXTS = [
"Disabled (Fastest)",
"Screen-space ambient occlusion (Fast)",
"Screen-space indirect lighting (Average)",
"SSAO + SSIL (Slow)",
]
var gi_mode = GIMode.NONE
var use_reflection_probe = false
var ssil_mode = SSILMode.NONE
@onready var environment = $WorldEnvironment.environment
@onready var gi_mode_label = $GIMode
@onready var reflection_probe_mode_label = $ReflectionProbeMode
@onready var reflection_probe = $Camera3D/ReflectiveSphere/ReflectionProbe
@onready var reflection_probe = $Camera/ReflectiveSphere/ReflectionProbe
@onready var ssil_mode_label = $SSILMode
func _ready():
set_gi_mode(GIMode.NONE)
set_use_reflection_probe(false)
set_gi_mode(gi_mode)
set_use_reflection_probe(use_reflection_probe)
set_ssil_mode(ssil_mode)
func _input(event):
@@ -36,79 +58,109 @@ func _input(event):
if event.is_action_pressed("toggle_reflection_probe"):
set_use_reflection_probe(not use_reflection_probe)
if event.is_action_pressed("cycle_ssil_mode"):
set_ssil_mode(wrapi(ssil_mode + 1, 0, SSILMode.MAX))
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]
gi_mode_label.text = "Global illumination: %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
# $BakedLightmapIndirect.visible = false
# $BakedLightmapAll.visible = false
$VoxelGI.visible = false
environment.sdfgi_enabled = 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 = Light3D.BAKE_INDIRECT
$GrateOmniLight.light_bake_mode = Light3D.BAKE_INDIRECT
$GarageOmniLight.light_bake_mode = Light3D.BAKE_INDIRECT
$CornerSpotLight.light_bake_mode = Light3D.BAKE_INDIRECT
$Sun.light_bake_mode = Light3D.BAKE_DYNAMIC
$GrateOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
$GarageOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
$CornerSpotLight.light_bake_mode = Light3D.BAKE_DYNAMIC
GIMode.BAKED_LIGHTMAP_ALL:
$ZdmBakeIndirect.visible = false
$ZdmBakeAll.visible = true
$ZdmNoBake.visible = false
$BakedLightmapIndirect.visible = false
$BakedLightmapAll.visible = true
$VoxelGI.visible = false
# GIMode.BAKED_LIGHTMAP_ALL:
# $BakedLightmapIndirect.visible = false
# $BakedLightmapAll.visible = true
# $VoxelGI.visible = false
# environment.sdfgi_enabled = false
#
# # Make lights not affect baked surfaces by setting their bake mode to All.
# $Sun.light_bake_mode = Light3D.BAKE_STATIC
# $GrateOmniLight.light_bake_mode = Light3D.BAKE_STATIC
# $GarageOmniLight.light_bake_mode = Light3D.BAKE_STATIC
# $CornerSpotLight.light_bake_mode = Light3D.BAKE_STATIC
# Make lights not affect baked surfaces by setting their bake mode to All.
$Sun.light_bake_mode = Light3D.BAKE_ALL
$GrateOmniLight.light_bake_mode = Light3D.BAKE_ALL
$GarageOmniLight.light_bake_mode = Light3D.BAKE_ALL
$CornerSpotLight.light_bake_mode = Light3D.BAKE_ALL
# GIMode.BAKED_LIGHTMAP_INDIRECT:
# $BakedLightmapIndirect.visible = true
# $BakedLightmapAll.visible = false
# $VoxelGI.visible = false
# environment.sdfgi_enabled = false
#
# $Sun.light_bake_mode = Light3D.BAKE_DYNAMIC
# $GrateOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
# $GarageOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
# $CornerSpotLight.light_bake_mode = Light3D.BAKE_DYNAMIC
GIMode.BAKED_LIGHTMAP_INDIRECT:
$ZdmBakeIndirect.visible = true
$ZdmBakeAll.visible = false
$ZdmNoBake.visible = false
$BakedLightmapIndirect.visible = true
$BakedLightmapAll.visible = false
$VoxelGI.visible = false
$Sun.light_bake_mode = Light3D.BAKE_INDIRECT
$GrateOmniLight.light_bake_mode = Light3D.BAKE_INDIRECT
$GarageOmniLight.light_bake_mode = Light3D.BAKE_INDIRECT
$CornerSpotLight.light_bake_mode = Light3D.BAKE_INDIRECT
GIMode.GI_PROBE:
$ZdmBakeIndirect.visible = false
$ZdmBakeAll.visible = false
$ZdmNoBake.visible = true
$BakedLightmapIndirect.visible = false
$BakedLightmapAll.visible = false
GIMode.VOXEL_GI:
# $BakedLightmapIndirect.visible = false
# $BakedLightmapAll.visible = false
$VoxelGI.visible = true
environment.sdfgi_enabled = false
# 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 VoxelGI
# can take a while to update.
$Sun.light_bake_mode = Light3D.BAKE_INDIRECT
$GrateOmniLight.light_bake_mode = Light3D.BAKE_INDIRECT
$GarageOmniLight.light_bake_mode = Light3D.BAKE_INDIRECT
$CornerSpotLight.light_bake_mode = Light3D.BAKE_INDIRECT
$Sun.light_bake_mode = Light3D.BAKE_DYNAMIC
$GrateOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
$GarageOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
$CornerSpotLight.light_bake_mode = Light3D.BAKE_DYNAMIC
GIMode.SDFGI:
# $BakedLightmapIndirect.visible = false
# $BakedLightmapAll.visible = false
$VoxelGI.visible = false
environment.sdfgi_enabled = 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 SDFGI
# can take a while to update.
$Sun.light_bake_mode = Light3D.BAKE_DYNAMIC
$GrateOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
$GarageOmniLight.light_bake_mode = Light3D.BAKE_DYNAMIC
$CornerSpotLight.light_bake_mode = Light3D.BAKE_DYNAMIC
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)"
reflection_probe_mode_label.text = "Reflection probe: Enabled - Using reflection probe (Average)"
else:
reflection_probe_mode_label.text = "Current reflection probe mode: Disabled - Using environment or VoxelGI reflections (Fast)"
reflection_probe_mode_label.text = "Reflection probe: Disabled - Using environment, VoxelGI or SDFGI reflections (Fast)"
reflection_probe.visible = p_visible
func set_ssil_mode(p_ssil_mode):
ssil_mode = p_ssil_mode
ssil_mode_label.text = "Screen-space lighting effects: %s " % SSIL_MODE_TEXTS[ssil_mode]
match p_ssil_mode:
SSILMode.NONE:
environment.ssao_enabled = false
environment.ssil_enabled = false
SSILMode.SSAO:
environment.ssao_enabled = true
environment.ssil_enabled = false
SSILMode.SSIL:
environment.ssao_enabled = false
environment.ssil_enabled = true
SSILMode.SSAO_AND_SSIL:
environment.ssao_enabled = true
environment.ssil_enabled = true

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@@ -1,25 +0,0 @@
[remap]
importer="texture_array"
type="Texture2DArray"
path="res://.godot/imported/test_all.exr-20e3b4b8c4ad01c2073fdca1a38f60ed.texarr"
metadata={
"vram_texture": false
}
[deps]
source_file="res://test_all.exr"
dest_files=["res://.godot/imported/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

File diff suppressed because it is too large Load Diff