Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/resources/3d/fog_material.cpp
9898 views
1
/**************************************************************************/
2
/* fog_material.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "fog_material.h"
32
33
#include "core/version.h"
34
35
Mutex FogMaterial::shader_mutex;
36
RID FogMaterial::shader;
37
38
void FogMaterial::set_density(float p_density) {
39
density = p_density;
40
RS::get_singleton()->material_set_param(_get_material(), "density", density);
41
}
42
43
float FogMaterial::get_density() const {
44
return density;
45
}
46
47
void FogMaterial::set_albedo(Color p_albedo) {
48
albedo = p_albedo;
49
RS::get_singleton()->material_set_param(_get_material(), "albedo", albedo);
50
}
51
52
Color FogMaterial::get_albedo() const {
53
return albedo;
54
}
55
56
void FogMaterial::set_emission(Color p_emission) {
57
emission = p_emission;
58
RS::get_singleton()->material_set_param(_get_material(), "emission", emission);
59
}
60
61
Color FogMaterial::get_emission() const {
62
return emission;
63
}
64
65
void FogMaterial::set_height_falloff(float p_falloff) {
66
height_falloff = MAX(p_falloff, 0.0f);
67
RS::get_singleton()->material_set_param(_get_material(), "height_falloff", height_falloff);
68
}
69
70
float FogMaterial::get_height_falloff() const {
71
return height_falloff;
72
}
73
74
void FogMaterial::set_edge_fade(float p_edge_fade) {
75
edge_fade = MAX(p_edge_fade, 0.0f);
76
RS::get_singleton()->material_set_param(_get_material(), "edge_fade", edge_fade);
77
}
78
79
float FogMaterial::get_edge_fade() const {
80
return edge_fade;
81
}
82
83
void FogMaterial::set_density_texture(const Ref<Texture3D> &p_texture) {
84
density_texture = p_texture;
85
Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant();
86
RS::get_singleton()->material_set_param(_get_material(), "density_texture", tex_rid);
87
}
88
89
Ref<Texture3D> FogMaterial::get_density_texture() const {
90
return density_texture;
91
}
92
93
Shader::Mode FogMaterial::get_shader_mode() const {
94
return Shader::MODE_FOG;
95
}
96
97
RID FogMaterial::get_shader_rid() const {
98
_update_shader();
99
return shader;
100
}
101
102
RID FogMaterial::get_rid() const {
103
_update_shader();
104
if (!shader_set) {
105
RS::get_singleton()->material_set_shader(_get_material(), shader);
106
shader_set = true;
107
}
108
return _get_material();
109
}
110
111
void FogMaterial::_bind_methods() {
112
ClassDB::bind_method(D_METHOD("set_density", "density"), &FogMaterial::set_density);
113
ClassDB::bind_method(D_METHOD("get_density"), &FogMaterial::get_density);
114
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &FogMaterial::set_albedo);
115
ClassDB::bind_method(D_METHOD("get_albedo"), &FogMaterial::get_albedo);
116
ClassDB::bind_method(D_METHOD("set_emission", "emission"), &FogMaterial::set_emission);
117
ClassDB::bind_method(D_METHOD("get_emission"), &FogMaterial::get_emission);
118
ClassDB::bind_method(D_METHOD("set_height_falloff", "height_falloff"), &FogMaterial::set_height_falloff);
119
ClassDB::bind_method(D_METHOD("get_height_falloff"), &FogMaterial::get_height_falloff);
120
ClassDB::bind_method(D_METHOD("set_edge_fade", "edge_fade"), &FogMaterial::set_edge_fade);
121
ClassDB::bind_method(D_METHOD("get_edge_fade"), &FogMaterial::get_edge_fade);
122
ClassDB::bind_method(D_METHOD("set_density_texture", "density_texture"), &FogMaterial::set_density_texture);
123
ClassDB::bind_method(D_METHOD("get_density_texture"), &FogMaterial::get_density_texture);
124
125
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "-8.0,8.0,0.0001,or_greater,or_less"), "set_density", "get_density");
126
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo", PROPERTY_HINT_COLOR_NO_ALPHA), "set_albedo", "get_albedo");
127
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission");
128
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_falloff", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_height_falloff", "get_height_falloff");
129
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_fade", PROPERTY_HINT_EXP_EASING), "set_edge_fade", "get_edge_fade");
130
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "density_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_density_texture", "get_density_texture");
131
}
132
133
void FogMaterial::cleanup_shader() {
134
if (shader.is_valid()) {
135
ERR_FAIL_NULL(RenderingServer::get_singleton());
136
RS::get_singleton()->free(shader);
137
}
138
}
139
140
void FogMaterial::_update_shader() {
141
MutexLock shader_lock(shader_mutex);
142
if (shader.is_null()) {
143
shader = RS::get_singleton()->shader_create();
144
145
// Add a comment to describe the shader origin (useful when converting to ShaderMaterial).
146
RS::get_singleton()->shader_set_code(shader, R"(
147
// NOTE: Shader automatically converted from )" GODOT_VERSION_NAME " " GODOT_VERSION_FULL_CONFIG R"('s FogMaterial.
148
149
shader_type fog;
150
151
uniform float density : hint_range(0, 1, 0.0001) = 1.0;
152
uniform vec4 albedo : source_color = vec4(1.0);
153
uniform vec4 emission : source_color = vec4(0, 0, 0, 1);
154
uniform float height_falloff = 0.0;
155
uniform float edge_fade = 0.1;
156
uniform sampler3D density_texture: hint_default_white;
157
158
159
void fog() {
160
DENSITY = density * clamp(exp2(-height_falloff * (WORLD_POSITION.y - OBJECT_POSITION.y)), 0.0, 1.0);
161
DENSITY *= texture(density_texture, UVW).r;
162
DENSITY *= pow(clamp(-2.0 * SDF / min(min(SIZE.x, SIZE.y), SIZE.z), 0.0, 1.0), edge_fade);
163
ALBEDO = albedo.rgb;
164
EMISSION = emission.rgb;
165
}
166
)");
167
}
168
}
169
170
FogMaterial::FogMaterial() {
171
_set_material(RS::get_singleton()->material_create());
172
173
set_density(1.0);
174
set_albedo(Color(1, 1, 1, 1));
175
set_emission(Color(0, 0, 0, 1));
176
177
set_height_falloff(0.0);
178
set_edge_fade(0.1);
179
}
180
181
FogMaterial::~FogMaterial() {
182
RS::get_singleton()->material_set_shader(_get_material(), RID());
183
}
184
185