Skip to content

Commit f47d090

Browse files
authored
Merge pull request #658 from Calinou/add-volumetric-fog-demo
Add a volumetric fog demo
2 parents 1923153 + 907b8a2 commit f47d090

File tree

8 files changed

+473
-0
lines changed

8 files changed

+473
-0
lines changed

3d/volumetric_fog/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Volumetric Fog
2+
3+
This is an example of Godot's volumetric fog capabilities with the Vulkan renderer.
4+
5+
Showcased features are:
6+
7+
- Positive/negative density volumes that affect albedo (incoming light) and emission.
8+
- Box/ellipsoid shapes, height falloff, and density modulation using a 3D texture.
9+
- Temporal reprojection for greater stability and avoiding flickering.
10+
- The difference is demonstrated with a moving fog volume.
11+
- Global density adjustment. With FogVolume nodes that have a positive density,
12+
it's possible to apply volumetric fog only in specific areas.
13+
14+
Language: GDScript
15+
16+
Renderer: Vulkan Clustered
17+
18+
## Screenshots
19+
20+
![Screenshot](screenshots/volumetric_fog.png)

3d/volumetric_fog/camera.gd

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
extends Camera3D
2+
3+
const MOUSE_SENSITIVITY = 0.002
4+
const MOVE_SPEED = 0.6
5+
6+
var rot = Vector3()
7+
var velocity = Vector3()
8+
9+
@onready var label = $Label
10+
11+
12+
func _ready():
13+
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
14+
update_label()
15+
16+
17+
func _process(delta):
18+
var motion = Vector3(
19+
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
20+
0,
21+
Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
22+
)
23+
24+
# Normalize motion to prevent diagonal movement from being
25+
# `sqrt(2)` times faster than straight movement.
26+
motion = motion.normalized()
27+
28+
velocity += MOVE_SPEED * delta * (transform.basis * motion)
29+
velocity *= 0.85
30+
position += velocity
31+
32+
33+
func _input(event):
34+
# Mouse look (only if the mouse is captured).
35+
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
36+
# Horizontal mouse look.
37+
rot.y -= event.relative.x * MOUSE_SENSITIVITY
38+
# Vertical mouse look.
39+
rot.x = clamp(rot.x - event.relative.y * MOUSE_SENSITIVITY, -1.57, 1.57)
40+
transform.basis = Basis.from_euler(rot)
41+
42+
if event.is_action_pressed("toggle_mouse_capture"):
43+
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
44+
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
45+
else:
46+
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
47+
48+
if event.is_action_pressed("toggle_temporal_reprojection"):
49+
get_world_3d().environment.volumetric_fog_temporal_reprojection_enabled = not get_world_3d().environment.volumetric_fog_temporal_reprojection_enabled
50+
update_label()
51+
elif event.is_action_pressed("increase_temporal_reprojection"):
52+
get_world_3d().environment.volumetric_fog_temporal_reprojection_amount = clamp(get_world_3d().environment.volumetric_fog_temporal_reprojection_amount + 0.01, 0.0, 0.99)
53+
update_label()
54+
elif event.is_action_pressed("decrease_temporal_reprojection"):
55+
get_world_3d().environment.volumetric_fog_temporal_reprojection_amount = clamp(get_world_3d().environment.volumetric_fog_temporal_reprojection_amount - 0.01, 0.0, 0.99)
56+
update_label()
57+
elif event.is_action_pressed("increase_fog_density"):
58+
get_world_3d().environment.volumetric_fog_density = clamp(get_world_3d().environment.volumetric_fog_density + 0.01, 0.0, 1.0)
59+
update_label()
60+
elif event.is_action_pressed("decrease_fog_density"):
61+
get_world_3d().environment.volumetric_fog_density = clamp(get_world_3d().environment.volumetric_fog_density - 0.01, 0.0, 1.0)
62+
update_label()
63+
64+
65+
func update_label():
66+
if get_world_3d().environment.volumetric_fog_temporal_reprojection_enabled:
67+
label.text = "Fog density: %.2f\nTemporal reprojection: Enabled\nTemporal reprojection strength: %.3f" % [get_world_3d().environment.volumetric_fog_density, get_world_3d().environment.volumetric_fog_temporal_reprojection_amount]
68+
else:
69+
label.text = "Fog density: %.2f\nTemporal reprojection: Disabled" % get_world_3d().environment.volumetric_fog_density

3d/volumetric_fog/icon_outlined.png

5.45 KB
Loading
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[remap]
2+
3+
importer="3d_texture"
4+
type="CompressedTexture3D"
5+
uid="uid://bpvy0e34otmhk"
6+
path="res://.godot/imported/icon_outlined.png-be09dc71a0cb04701900baffec3ab610.ctex3d"
7+
metadata={
8+
"vram_texture": false
9+
}
10+
11+
[deps]
12+
13+
source_file="res://icon_outlined.png"
14+
dest_files=["res://.godot/imported/icon_outlined.png-be09dc71a0cb04701900baffec3ab610.ctex3d"]
15+
16+
[params]
17+
18+
compress/mode=0
19+
compress/lossy_quality=0.7
20+
compress/hdr_compression=1
21+
compress/bptc_ldr=0
22+
compress/channel_pack=0
23+
mipmaps/generate=false
24+
mipmaps/limit=-1
25+
slices/horizontal=1
26+
slices/vertical=1

3d/volumetric_fog/project.godot

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
; Engine configuration file.
2+
; It's best edited using the editor UI and not directly,
3+
; since the parameters that go here are not all obvious.
4+
;
5+
; Format:
6+
; [section] ; section goes between []
7+
; param=value ; assign values to parameters
8+
9+
config_version=5
10+
11+
[application]
12+
13+
config/name="Volumetric Fog"
14+
run/main_scene="res://volumetric_fog.tscn"
15+
config/features=PackedStringArray("4.0")
16+
17+
[display]
18+
19+
window/stretch/mode="canvas_items"
20+
window/stretch/aspect="expand"
21+
22+
[input]
23+
24+
toggle_temporal_reprojection={
25+
"deadzone": 0.5,
26+
"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)
27+
]
28+
}
29+
increase_temporal_reprojection={
30+
"deadzone": 0.5,
31+
"events": [Object(InputEventMouseButton,"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,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"pressed":false,"double_click":false,"script":null)
32+
, 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)
33+
]
34+
}
35+
decrease_temporal_reprojection={
36+
"deadzone": 0.5,
37+
"events": [Object(InputEventMouseButton,"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,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"pressed":false,"double_click":false,"script":null)
38+
, 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)
39+
]
40+
}
41+
increase_fog_density={
42+
"deadzone": 0.5,
43+
"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":16777233,"unicode":0,"echo":false,"script":null)
44+
]
45+
}
46+
decrease_fog_density={
47+
"deadzone": 0.5,
48+
"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":16777231,"unicode":0,"echo":false,"script":null)
49+
]
50+
}
51+
move_forward={
52+
"deadzone": 0.5,
53+
"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)
54+
]
55+
}
56+
move_back={
57+
"deadzone": 0.5,
58+
"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)
59+
]
60+
}
61+
move_right={
62+
"deadzone": 0.5,
63+
"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)
64+
]
65+
}
66+
move_left={
67+
"deadzone": 0.5,
68+
"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)
69+
]
70+
}
71+
toggle_mouse_capture={
72+
"deadzone": 0.5,
73+
"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)
74+
]
75+
}
76+
77+
[rendering]
78+
79+
anti_aliasing/quality/screen_space_aa=1
80+
anti_aliasing/quality/use_debanding=true

3d/volumetric_fog/screenshots/.gdignore

Whitespace-only changes.
Loading

0 commit comments

Comments
 (0)