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

Add a global illumination demo
This commit is contained in:
Aaron Franke
2022-02-13 13:05:40 -06:00
committed by GitHub
24 changed files with 2678 additions and 0 deletions

View 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
![Screenshot](screenshots/global_illumination.png)
## 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.

View 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

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View 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

View 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"

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

View 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

View 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

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.