Skip to content

Commit

Permalink
Added proximity and distance fade to SpatialMaterial
Browse files Browse the repository at this point in the history
  • Loading branch information
reduz committed Sep 21, 2017
1 parent d7468fe commit bf371dc
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class RasterizerSceneGLES3 : public RasterizerScene {
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];
Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/shader_compiler_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
2 changes: 2 additions & 0 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
116 changes: 115 additions & 1 deletion scene/resources/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
}
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions scene/resources/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ class SpatialMaterial : public Material {
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;
Expand Down Expand Up @@ -274,6 +276,8 @@ class SpatialMaterial : public Material {
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;
}
Expand Down Expand Up @@ -308,6 +312,9 @@ class SpatialMaterial : public Material {
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;
Expand Down Expand Up @@ -370,6 +377,13 @@ class SpatialMaterial : public Material {
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;
Expand Down Expand Up @@ -535,6 +549,21 @@ class SpatialMaterial : public Material {

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);
Expand Down
2 changes: 2 additions & 0 deletions servers/visual/shader_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit bf371dc

Please sign in to comment.