Added proximity and distance fade to SpatialMaterial
This commit is contained in:
parent
d7468fea5b
commit
bf371dcb32
|
@ -2404,6 +2404,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
|
|||
|
||||
//store camera into ubo
|
||||
store_camera(p_cam_projection, state.ubo_data.projection_matrix);
|
||||
store_camera(p_cam_projection.inverse(), state.ubo_data.inv_projection_matrix);
|
||||
store_transform(p_cam_transform, state.ubo_data.camera_matrix);
|
||||
store_transform(p_cam_transform.affine_inverse(), state.ubo_data.camera_inverse_matrix);
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ public:
|
|||
struct SceneDataUBO {
|
||||
//this is a std140 compatible struct. Please read the OpenGL 3.3 Specificaiton spec before doing any changes
|
||||
float projection_matrix[16];
|
||||
float inv_projection_matrix[16];
|
||||
float camera_inverse_matrix[16];
|
||||
float camera_matrix[16];
|
||||
float ambient_light_color[4];
|
||||
|
|
|
@ -750,6 +750,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix";
|
||||
actions[VS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix";
|
||||
actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix";
|
||||
actions[VS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
|
||||
actions[VS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview";
|
||||
|
||||
actions[VS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz";
|
||||
|
|
|
@ -61,6 +61,7 @@ layout(location=12) in highp vec4 instance_custom_data;
|
|||
layout(std140) uniform SceneData { //ubo:0
|
||||
|
||||
highp mat4 projection_matrix;
|
||||
highp mat4 inv_projection_matrix;
|
||||
highp mat4 camera_inverse_matrix;
|
||||
highp mat4 camera_matrix;
|
||||
|
||||
|
@ -643,6 +644,7 @@ FRAGMENT_SHADER_GLOBALS
|
|||
layout(std140) uniform SceneData {
|
||||
|
||||
highp mat4 projection_matrix;
|
||||
highp mat4 inv_projection_matrix;
|
||||
highp mat4 camera_inverse_matrix;
|
||||
highp mat4 camera_matrix;
|
||||
|
||||
|
|
|
@ -268,6 +268,10 @@ void SpatialMaterial::init_shaders() {
|
|||
|
||||
shader_names->grow = "grow";
|
||||
|
||||
shader_names->proximity_fade_distance = "proximity_fade_distance";
|
||||
shader_names->distance_fade_min = "distance_fade_min";
|
||||
shader_names->distance_fade_max = "distance_fade_max";
|
||||
|
||||
shader_names->metallic_texture_channel = "metallic_texture_channel";
|
||||
shader_names->roughness_texture_channel = "roughness_texture_channel";
|
||||
shader_names->ao_texture_channel = "ao_texture_channel";
|
||||
|
@ -401,6 +405,14 @@ void SpatialMaterial::_update_shader() {
|
|||
code += "uniform float grow;\n";
|
||||
}
|
||||
|
||||
if (proximity_fade_enabled) {
|
||||
code += "uniform float proximity_fade_distance;\n";
|
||||
}
|
||||
if (distance_fade_enabled) {
|
||||
code += "uniform float distance_fade_min;\n";
|
||||
code += "uniform float distance_fade_max;\n";
|
||||
}
|
||||
|
||||
if (flags[FLAG_USE_ALPHA_SCISSOR]) {
|
||||
code += "uniform float alpha_scissor_threshold;\n";
|
||||
}
|
||||
|
@ -725,10 +737,21 @@ void SpatialMaterial::_update_shader() {
|
|||
code += "\tALBEDO *= 1.0 - ref_amount;\n";
|
||||
code += "\tALPHA = 1.0;\n";
|
||||
|
||||
} else if (features[FEATURE_TRANSPARENT] || features[FLAG_USE_ALPHA_SCISSOR]) {
|
||||
} else if (features[FEATURE_TRANSPARENT] || features[FLAG_USE_ALPHA_SCISSOR] || distance_fade_enabled || proximity_fade_enabled) {
|
||||
code += "\tALPHA = albedo.a * albedo_tex.a;\n";
|
||||
}
|
||||
|
||||
if (proximity_fade_enabled) {
|
||||
code += "\tfloat depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n";
|
||||
code += "\tvec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex*2.0-1.0,1.0);\n";
|
||||
code += "\tworld_pos.xyz/=world_pos.w;\n";
|
||||
code += "\tALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
|
||||
}
|
||||
|
||||
if (distance_fade_enabled) {
|
||||
code += "\tALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_RIM]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_triplanar_pos).xy;\n";
|
||||
|
@ -1231,6 +1254,14 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
|
|||
property.usage = 0;
|
||||
}
|
||||
|
||||
if (property.name == "proximity_fade_distacne" && !proximity_fade_enabled) {
|
||||
property.usage = 0;
|
||||
}
|
||||
|
||||
if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && !distance_fade_enabled) {
|
||||
property.usage = 0;
|
||||
}
|
||||
|
||||
if (property.name == "params_alpha_scissor_threshold" && !flags[FLAG_USE_ALPHA_SCISSOR]) {
|
||||
property.usage = 0;
|
||||
}
|
||||
|
@ -1526,6 +1557,60 @@ void SpatialMaterial::set_on_top_of_alpha() {
|
|||
set_flag(FLAG_DISABLE_DEPTH_TEST, true);
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_proximity_fade(bool p_enable) {
|
||||
|
||||
proximity_fade_enabled = p_enable;
|
||||
_queue_shader_change();
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
bool SpatialMaterial::is_proximity_fade_enabled() const {
|
||||
|
||||
return proximity_fade_enabled;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_proximity_fade_distance(float p_distance) {
|
||||
|
||||
proximity_fade_distance = p_distance;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance);
|
||||
}
|
||||
float SpatialMaterial::get_proximity_fade_distance() const {
|
||||
|
||||
return proximity_fade_distance;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_distance_fade(bool p_enable) {
|
||||
|
||||
distance_fade_enabled = p_enable;
|
||||
_queue_shader_change();
|
||||
_change_notify();
|
||||
}
|
||||
bool SpatialMaterial::is_distance_fade_enabled() const {
|
||||
|
||||
return distance_fade_enabled;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_distance_fade_max_distance(float p_distance) {
|
||||
|
||||
distance_fade_max_distance = p_distance;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
|
||||
}
|
||||
float SpatialMaterial::get_distance_fade_max_distance() const {
|
||||
|
||||
return distance_fade_max_distance;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_distance_fade_min_distance(float p_distance) {
|
||||
|
||||
distance_fade_min_distance = p_distance;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
|
||||
}
|
||||
|
||||
float SpatialMaterial::get_distance_fade_min_distance() const {
|
||||
|
||||
return distance_fade_min_distance;
|
||||
}
|
||||
|
||||
void SpatialMaterial::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
|
||||
|
@ -1672,6 +1757,21 @@ void SpatialMaterial::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &SpatialMaterial::set_refraction_texture_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &SpatialMaterial::get_refraction_texture_channel);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &SpatialMaterial::set_proximity_fade);
|
||||
ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &SpatialMaterial::is_proximity_fade_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &SpatialMaterial::set_proximity_fade_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &SpatialMaterial::get_proximity_fade_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_distance_fade", "enabled"), &SpatialMaterial::set_distance_fade);
|
||||
ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &SpatialMaterial::is_distance_fade_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &SpatialMaterial::set_distance_fade_max_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &SpatialMaterial::get_distance_fade_max_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &SpatialMaterial::set_distance_fade_min_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &SpatialMaterial::get_distance_fade_min_distance);
|
||||
|
||||
ADD_GROUP("Flags", "flags_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
|
||||
|
@ -1795,6 +1895,14 @@ void SpatialMaterial::_bind_methods() {
|
|||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_TRIPLANAR);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness");
|
||||
|
||||
ADD_GROUP("Proximity Fade", "proximity_fade_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enable"), "set_proximity_fade", "is_proximity_fade_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_proximity_fade_distance", "get_proximity_fade_distance");
|
||||
ADD_GROUP("Distance Fade", "distance_fade_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enable"), "set_distance_fade", "is_distance_fade_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_distance_fade_min_distance", "get_distance_fade_min_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_max_distance", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_distance_fade_max_distance", "get_distance_fade_max_distance");
|
||||
|
||||
BIND_ENUM_CONSTANT(TEXTURE_ALBEDO);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_METALLIC);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_ROUGHNESS);
|
||||
|
@ -1916,6 +2024,12 @@ SpatialMaterial::SpatialMaterial()
|
|||
set_particles_anim_loop(false);
|
||||
set_alpha_scissor_threshold(0.98);
|
||||
|
||||
proximity_fade_enabled = false;
|
||||
distance_fade_enabled = false;
|
||||
set_proximity_fade_distance(1);
|
||||
set_distance_fade_min_distance(0);
|
||||
set_distance_fade_max_distance(10);
|
||||
|
||||
set_metallic_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
set_roughness_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
set_ao_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
|
|
|
@ -232,6 +232,8 @@ private:
|
|||
uint64_t deep_parallax : 1;
|
||||
uint64_t billboard_mode : 2;
|
||||
uint64_t grow : 1;
|
||||
uint64_t proximity_fade : 1;
|
||||
uint64_t distance_fade : 1;
|
||||
};
|
||||
|
||||
uint64_t key;
|
||||
|
@ -274,6 +276,8 @@ private:
|
|||
mk.billboard_mode = billboard_mode;
|
||||
mk.deep_parallax = deep_parallax ? 1 : 0;
|
||||
mk.grow = grow_enabled;
|
||||
mk.proximity_fade = proximity_fade_enabled;
|
||||
mk.distance_fade = distance_fade_enabled;
|
||||
|
||||
return mk;
|
||||
}
|
||||
|
@ -308,6 +312,9 @@ private:
|
|||
StringName uv1_blend_sharpness;
|
||||
StringName uv2_blend_sharpness;
|
||||
StringName grow;
|
||||
StringName proximity_fade_distance;
|
||||
StringName distance_fade_min;
|
||||
StringName distance_fade_max;
|
||||
|
||||
StringName metallic_texture_channel;
|
||||
StringName roughness_texture_channel;
|
||||
|
@ -370,6 +377,13 @@ private:
|
|||
int deep_parallax_min_layers;
|
||||
int deep_parallax_max_layers;
|
||||
|
||||
bool proximity_fade_enabled;
|
||||
float proximity_fade_distance;
|
||||
|
||||
bool distance_fade_enabled;
|
||||
float distance_fade_max_distance;
|
||||
float distance_fade_min_distance;
|
||||
|
||||
BlendMode blend_mode;
|
||||
BlendMode detail_blend_mode;
|
||||
DepthDrawMode depth_draw_mode;
|
||||
|
@ -535,6 +549,21 @@ public:
|
|||
|
||||
void set_on_top_of_alpha();
|
||||
|
||||
void set_proximity_fade(bool p_enable);
|
||||
bool is_proximity_fade_enabled() const;
|
||||
|
||||
void set_proximity_fade_distance(float p_distance);
|
||||
float get_proximity_fade_distance() const;
|
||||
|
||||
void set_distance_fade(bool p_enable);
|
||||
bool is_distance_fade_enabled() const;
|
||||
|
||||
void set_distance_fade_max_distance(float p_distance);
|
||||
float get_distance_fade_max_distance() const;
|
||||
|
||||
void set_distance_fade_min_distance(float p_distance);
|
||||
float get_distance_fade_min_distance() const;
|
||||
|
||||
void set_metallic_texture_channel(TextureChannel p_channel);
|
||||
TextureChannel get_metallic_texture_channel() const;
|
||||
void set_roughness_texture_channel(TextureChannel p_channel);
|
||||
|
|
|
@ -75,6 +75,7 @@ ShaderTypes::ShaderTypes() {
|
|||
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
|
||||
|
||||
|
@ -115,6 +116,7 @@ ShaderTypes::ShaderTypes() {
|
|||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
|
||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].can_discard = true;
|
||||
|
|
Loading…
Reference in New Issue