diff options
Diffstat (limited to 'scene/resources/material.cpp')
-rw-r--r-- | scene/resources/material.cpp | 76 |
1 files changed, 62 insertions, 14 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 875b72159a..b6d1916b2c 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -34,6 +34,8 @@ void Material::set_next_pass(const Ref<Material> &p_pass) { + ERR_FAIL_COND(p_pass == this); + if (next_pass == p_pass) return; @@ -398,8 +400,10 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_USE_VERTEX_LIGHTING]) { code += ",vertex_lighting"; } + bool using_world = false; if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) { code += ",world_vertex_coords"; + using_world = true; } if (flags[FLAG_DONT_RECEIVE_SHADOWS]) { code += ",shadows_disabled"; @@ -423,7 +427,7 @@ void SpatialMaterial::_update_shader() { if (proximity_fade_enabled) { code += "uniform float proximity_fade_distance;\n"; } - if (distance_fade_enabled) { + if (distance_fade != DISTANCE_FADE_DISABLED) { code += "uniform float distance_fade_min;\n"; code += "uniform float distance_fade_max;\n"; } @@ -782,7 +786,7 @@ void SpatialMaterial::_update_shader() { code += "\tALBEDO *= 1.0 - ref_amount;\n"; code += "\tALPHA = 1.0;\n"; - } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || distance_fade_enabled || proximity_fade_enabled) { + } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } @@ -793,8 +797,47 @@ void SpatialMaterial::_update_shader() { 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 (distance_fade != DISTANCE_FADE_DISABLED) { + if (distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER) { + + code += "\t{\n"; + if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { + code += "\t\tfloat fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n"; + + } else { + code += "\t\tfloat fade_distance=-VERTEX.z;\n"; + } + + code += "\t\tfloat fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n"; + code += "\t\tint x = int(FRAGCOORD.x) % 4;\n"; + code += "\t\tint y = int(FRAGCOORD.y) % 4;\n"; + code += "\t\tint index = x + y * 4;\n"; + code += "\t\tfloat limit = 0.0;\n\n"; + code += "\t\tif (x < 8) {\n"; + code += "\t\t\tif (index == 0) limit = 0.0625;\n"; + code += "\t\t\tif (index == 1) limit = 0.5625;\n"; + code += "\t\t\tif (index == 2) limit = 0.1875;\n"; + code += "\t\t\tif (index == 3) limit = 0.6875;\n"; + code += "\t\t\tif (index == 4) limit = 0.8125;\n"; + code += "\t\t\tif (index == 5) limit = 0.3125;\n"; + code += "\t\t\tif (index == 6) limit = 0.9375;\n"; + code += "\t\t\tif (index == 7) limit = 0.4375;\n"; + code += "\t\t\tif (index == 8) limit = 0.25;\n"; + code += "\t\t\tif (index == 9) limit = 0.75;\n"; + code += "\t\t\tif (index == 10) limit = 0.125;\n"; + code += "\t\t\tif (index == 11) limit = 0.625;\n"; + code += "\t\t\tif (index == 12) limit = 1.0;\n"; + code += "\t\t\tif (index == 13) limit = 0.5;\n"; + code += "\t\t\tif (index == 14) limit = 0.875;\n"; + code += "\t\t\tif (index == 15) limit = 0.375;\n"; + code += "\t\t}\n\n"; + code += "\tif (fade < limit)\n"; + code += "\t\tdiscard;\n"; + code += "\t}\n\n"; + + } else { + code += "\tALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n"; + } } if (features[FEATURE_RIM]) { @@ -1324,7 +1367,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && !distance_fade_enabled) { + if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && distance_fade == DISTANCE_FADE_DISABLED) { property.usage = 0; } @@ -1645,15 +1688,15 @@ float SpatialMaterial::get_proximity_fade_distance() const { return proximity_fade_distance; } -void SpatialMaterial::set_distance_fade(bool p_enable) { +void SpatialMaterial::set_distance_fade(DistanceFadeMode p_mode) { - distance_fade_enabled = p_enable; + distance_fade = p_mode; _queue_shader_change(); _change_notify(); } -bool SpatialMaterial::is_distance_fade_enabled() const { +SpatialMaterial::DistanceFadeMode SpatialMaterial::get_distance_fade() const { - return distance_fade_enabled; + return distance_fade; } void SpatialMaterial::set_distance_fade_max_distance(float p_distance) { @@ -1859,8 +1902,8 @@ void SpatialMaterial::_bind_methods() { 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", "mode"), &SpatialMaterial::set_distance_fade); + ClassDB::bind_method(D_METHOD("get_distance_fade"), &SpatialMaterial::get_distance_fade); 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); @@ -1892,7 +1935,7 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "params_depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never,Opaque Pre-Pass"), "set_depth_draw_mode", "get_depth_draw_mode"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_line_width", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_line_width", "get_line_width"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard1"), "set_billboard_mode", "get_billboard_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params_grow"), "set_grow_enabled", "is_grow_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_grow_amount", PROPERTY_HINT_RANGE, "-16,10,0.01"), "set_grow", "get_grow"); @@ -2003,7 +2046,7 @@ void SpatialMaterial::_bind_methods() { 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::INT, "distance_fade_mode", PROPERTY_HINT_ENUM, "Disabled,PixelAlpha,PixelDither,ObjectDither"), "set_distance_fade", "get_distance_fade"); 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"); @@ -2101,6 +2144,11 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_OP_ADD); BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY); + + BIND_ENUM_CONSTANT(DISTANCE_FADE_DISABLED); + BIND_ENUM_CONSTANT(DISTANCE_FADE_PIXEL_ALPHA); + BIND_ENUM_CONSTANT(DISTANCE_FADE_PIXEL_DITHER); + BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER); } SpatialMaterial::SpatialMaterial() : @@ -2139,7 +2187,7 @@ SpatialMaterial::SpatialMaterial() : emission_op = EMISSION_OP_ADD; proximity_fade_enabled = false; - distance_fade_enabled = false; + distance_fade = DISTANCE_FADE_DISABLED; set_proximity_fade_distance(1); set_distance_fade_min_distance(0); set_distance_fade_max_distance(10); |