summaryrefslogtreecommitdiff
path: root/scene/resources/material.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/material.cpp')
-rw-r--r--scene/resources/material.cpp537
1 files changed, 306 insertions, 231 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index fd8cff7cd0..35c967ce27 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -30,7 +30,7 @@
#include "material.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
@@ -39,28 +39,27 @@
#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
-
for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) {
ERR_FAIL_COND_MSG(pass_child == this, "Can't set as next_pass one of its parents to prevent crashes due to recursive loop.");
}
- if (next_pass == p_pass)
+ if (next_pass == p_pass) {
return;
+ }
next_pass = p_pass;
RID next_pass_rid;
- if (next_pass.is_valid())
+ if (next_pass.is_valid()) {
next_pass_rid = next_pass->get_rid();
+ }
RS::get_singleton()->material_set_next_pass(material, next_pass_rid);
}
Ref<Material> Material::get_next_pass() const {
-
return next_pass;
}
void Material::set_render_priority(int p_priority) {
-
ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN);
ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX);
render_priority = p_priority;
@@ -68,23 +67,20 @@ void Material::set_render_priority(int p_priority) {
}
int Material::get_render_priority() const {
-
return render_priority;
}
RID Material::get_rid() const {
-
return material;
}
-void Material::_validate_property(PropertyInfo &property) const {
+void Material::_validate_property(PropertyInfo &property) const {
if (!_can_do_next_pass() && property.name == "next_pass") {
property.usage = 0;
}
}
void Material::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass);
ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass);
@@ -99,22 +95,18 @@ void Material::_bind_methods() {
}
Material::Material() {
-
material = RenderingServer::get_singleton()->material_create();
render_priority = 0;
}
Material::~Material() {
-
RenderingServer::get_singleton()->free(material);
}
///////////////////////////////////
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
-
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (!pr) {
String n = p_name;
@@ -135,9 +127,7 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
}
bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
-
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (!pr) {
String n = p_name;
@@ -159,16 +149,13 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
}
void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
-
if (!shader.is_null()) {
-
shader->get_param_list(p_list);
}
}
bool ShaderMaterial::property_can_revert(const String &p_name) {
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (pr) {
Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr);
@@ -192,7 +179,6 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) {
}
void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
-
// Only connect/disconnect the signal when running in the editor.
// This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`)
// does nothing in non-editor builds anyway. See GH-34741 for details.
@@ -217,17 +203,14 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
}
Ref<Shader> ShaderMaterial::get_shader() const {
-
return shader;
}
void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
-
RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
}
Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
-
return RS::get_singleton()->material_get_param(_get_material(), p_param);
}
@@ -236,7 +219,6 @@ void ShaderMaterial::_shader_changed() {
}
void ShaderMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader);
ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader);
ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param);
@@ -248,7 +230,6 @@ void ShaderMaterial::_bind_methods() {
}
void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
@@ -257,7 +238,6 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
String f = p_function.operator String();
if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
-
if (shader.is_valid()) {
List<PropertyInfo> pl;
shader->get_param_list(&pl);
@@ -270,15 +250,15 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
}
bool ShaderMaterial::_can_do_next_pass() const {
-
return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL;
}
Shader::Mode ShaderMaterial::get_shader_mode() const {
- if (shader.is_valid())
+ if (shader.is_valid()) {
return shader->get_mode();
- else
+ } else {
return Shader::MODE_SPATIAL;
+ }
}
ShaderMaterial::ShaderMaterial() {
@@ -295,7 +275,6 @@ Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::sha
BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = nullptr;
void BaseMaterial3D::init_shaders() {
-
dirty_materials = memnew(SelfList<BaseMaterial3D>::List);
shader_names = memnew(ShaderNames);
@@ -345,7 +324,6 @@ void BaseMaterial3D::init_shaders() {
shader_names->rim_texture_channel = "rim_texture_channel";
shader_names->heightmap_texture_channel = "heightmap_texture_channel";
shader_names->refraction_texture_channel = "refraction_texture_channel";
- shader_names->alpha_scissor_threshold = "alpha_scissor_threshold";
shader_names->transmittance_color = "transmittance_color";
shader_names->transmittance_curve = "transmittance_curve";
@@ -370,12 +348,17 @@ void BaseMaterial3D::init_shaders() {
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal";
shader_names->texture_names[TEXTURE_ORM] = "texture_orm";
+
+ shader_names->alpha_scissor_threshold = "alpha_scissor_threshold";
+ shader_names->alpha_hash_scale = "alpha_hash_scale";
+
+ shader_names->alpha_antialiasing_edge = "alpha_antialiasing_edge";
+ shader_names->albedo_texture_size = "albedo_texture_size";
}
Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D];
void BaseMaterial3D::finish_shaders() {
-
for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) {
materials_for_2d[i].unref();
}
@@ -387,12 +370,12 @@ void BaseMaterial3D::finish_shaders() {
}
void BaseMaterial3D::_update_shader() {
-
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk == current_key)
+ if (mk == current_key) {
return; //no update required in the end
+ }
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
@@ -406,7 +389,6 @@ void BaseMaterial3D::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
-
RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
shader_map[mk].users++;
return;
@@ -414,13 +396,26 @@ void BaseMaterial3D::_update_shader() {
String texfilter_str;
switch (texture_filter) {
- case TEXTURE_FILTER_NEAREST: texfilter_str = "filter_nearest"; break;
- case TEXTURE_FILTER_LINEAR: texfilter_str = "filter_linear"; break;
- case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: texfilter_str = "filter_nearest_mipmap"; break;
- case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texfilter_str = "filter_linear_mipmap"; break;
- case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_nearest_mipmap_aniso"; break;
- case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_linear_mipmap_aniso"; break;
- case TEXTURE_FILTER_MAX: break; // Internal value, skip.
+ case TEXTURE_FILTER_NEAREST:
+ texfilter_str = "filter_nearest";
+ break;
+ case TEXTURE_FILTER_LINEAR:
+ texfilter_str = "filter_linear";
+ break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
+ texfilter_str = "filter_nearest_mipmap";
+ break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
+ texfilter_str = "filter_linear_mipmap";
+ break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC:
+ texfilter_str = "filter_nearest_mipmap_aniso";
+ break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC:
+ texfilter_str = "filter_linear_mipmap_aniso";
+ break;
+ case TEXTURE_FILTER_MAX:
+ break; // Internal value, skip.
}
if (flags[FLAG_USE_TEXTURE_REPEAT]) {
@@ -433,10 +428,20 @@ void BaseMaterial3D::_update_shader() {
String code = "shader_type spatial;\nrender_mode ";
switch (blend_mode) {
- case BLEND_MODE_MIX: code += "blend_mix"; break;
- case BLEND_MODE_ADD: code += "blend_add"; break;
- case BLEND_MODE_SUB: code += "blend_sub"; break;
- case BLEND_MODE_MUL: code += "blend_mul"; break;
+ case BLEND_MODE_MIX:
+ code += "blend_mix";
+ break;
+ case BLEND_MODE_ADD:
+ code += "blend_add";
+ break;
+ case BLEND_MODE_SUB:
+ code += "blend_sub";
+ break;
+ case BLEND_MODE_MUL:
+ code += "blend_mul";
+ break;
+ case BLEND_MODE_MAX:
+ break; // Internal value, skip.
}
DepthDrawMode ddm = depth_draw_mode;
@@ -445,33 +450,69 @@ void BaseMaterial3D::_update_shader() {
}
switch (ddm) {
- case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break;
- case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break;
- case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break;
- }
-
- if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
- code += ",depth_prepass_alpha";
+ case DEPTH_DRAW_OPAQUE_ONLY:
+ code += ",depth_draw_opaque";
+ break;
+ case DEPTH_DRAW_ALWAYS:
+ code += ",depth_draw_always";
+ break;
+ case DEPTH_DRAW_DISABLED:
+ code += ",depth_draw_never";
+ break;
+ case DEPTH_DRAW_MAX:
+ break; // Internal value, skip.
}
switch (cull_mode) {
- case CULL_BACK: code += ",cull_back"; break;
- case CULL_FRONT: code += ",cull_front"; break;
- case CULL_DISABLED: code += ",cull_disabled"; break;
+ case CULL_BACK:
+ code += ",cull_back";
+ break;
+ case CULL_FRONT:
+ code += ",cull_front";
+ break;
+ case CULL_DISABLED:
+ code += ",cull_disabled";
+ break;
+ case CULL_MAX:
+ break; // Internal value, skip.
}
switch (diffuse_mode) {
- case DIFFUSE_BURLEY: code += ",diffuse_burley"; break;
- case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break;
- case DIFFUSE_LAMBERT_WRAP: code += ",diffuse_lambert_wrap"; break;
- case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break;
- case DIFFUSE_TOON: code += ",diffuse_toon"; break;
+ case DIFFUSE_BURLEY:
+ code += ",diffuse_burley";
+ break;
+ case DIFFUSE_LAMBERT:
+ code += ",diffuse_lambert";
+ break;
+ case DIFFUSE_LAMBERT_WRAP:
+ code += ",diffuse_lambert_wrap";
+ break;
+ case DIFFUSE_OREN_NAYAR:
+ code += ",diffuse_oren_nayar";
+ break;
+ case DIFFUSE_TOON:
+ code += ",diffuse_toon";
+ break;
+ case DIFFUSE_MAX:
+ break; // Internal value, skip.
}
switch (specular_mode) {
- case SPECULAR_SCHLICK_GGX: code += ",specular_schlick_ggx"; break;
- case SPECULAR_BLINN: code += ",specular_blinn"; break;
- case SPECULAR_PHONG: code += ",specular_phong"; break;
- case SPECULAR_TOON: code += ",specular_toon"; break;
- case SPECULAR_DISABLED: code += ",specular_disabled"; break;
+ case SPECULAR_SCHLICK_GGX:
+ code += ",specular_schlick_ggx";
+ break;
+ case SPECULAR_BLINN:
+ code += ",specular_blinn";
+ break;
+ case SPECULAR_PHONG:
+ code += ",specular_phong";
+ break;
+ case SPECULAR_TOON:
+ code += ",specular_toon";
+ break;
+ case SPECULAR_DISABLED:
+ code += ",specular_disabled";
+ break;
+ case SPECULAR_MAX:
+ break; // Internal value, skip.
}
if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) {
code += ",sss_mode_skin";
@@ -495,6 +536,23 @@ void BaseMaterial3D::_update_shader() {
if (flags[FLAG_USE_SHADOW_TO_OPACITY]) {
code += ",shadow_to_opacity";
}
+
+ if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
+ code += ",depth_prepass_alpha";
+ }
+
+ // Although its technically possible to do alpha antialiasing without using alpha hash or alpha scissor,
+ // it is restricted in the base material because it has no use, and abusing it with regular Alpha blending can
+ // saturate the MSAA mask
+ if (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR) {
+ // alpha antialiasing is only useful in ALPHA_HASH or ALPHA_SCISSOR
+ if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
+ code += ",alpha_to_coverage";
+ } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
+ code += ",alpha_to_coverage_and_one";
+ }
+ }
+
code += ";\n";
code += "uniform vec4 albedo : hint_color;\n";
@@ -511,8 +569,18 @@ void BaseMaterial3D::_update_shader() {
code += "uniform float distance_fade_max;\n";
}
+ // alpha scissor is only valid if there is not antialiasing edge
+ // alpha hash is valid whenever, but not with alpha scissor
if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
code += "uniform float alpha_scissor_threshold;\n";
+ } else if (transparency == TRANSPARENCY_ALPHA_HASH) {
+ code += "uniform float alpha_hash_scale;\n";
+ }
+ // if alpha antialiasing isn't off, add in the edge variable
+ if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF &&
+ (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH)) {
+ code += "uniform float alpha_antialiasing_edge;\n";
+ code += "uniform ivec2 albedo_texture_size;\n";
}
code += "uniform float point_size : hint_range(0,128);\n";
@@ -538,6 +606,8 @@ void BaseMaterial3D::_update_shader() {
case TEXTURE_CHANNEL_GRAYSCALE: {
code += "uniform sampler2D texture_roughness : hint_roughness_gray," + texfilter_str + ";\n";
} break;
+ case TEXTURE_CHANNEL_MAX:
+ break; // Internal value, skip.
}
code += "uniform float specular;\n";
@@ -553,7 +623,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_EMISSION]) {
-
code += "uniform sampler2D texture_emission : hint_black_albedo," + texfilter_str + ";\n";
code += "uniform vec4 emission : hint_color;\n";
code += "uniform float emission_energy;\n";
@@ -596,13 +665,11 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_SUBSURFACE_SCATTERING]) {
-
code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n";
code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
-
code += "uniform vec4 transmittance_color : hint_color;\n";
code += "uniform float transmittance_depth;\n";
code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
@@ -611,7 +678,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_BACKLIGHT]) {
-
code += "uniform vec4 backlight : hint_color;\n";
code += "uniform sampler2D texture_backlight : hint_black," + texfilter_str + ";\n";
}
@@ -649,18 +715,15 @@ void BaseMaterial3D::_update_shader() {
code += "void vertex() {\n";
if (flags[FLAG_SRGB_VERTEX_COLOR]) {
-
code += "\tif (!OUTPUT_IS_SRGB) {\n";
code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n";
code += "\t}\n";
}
if (flags[FLAG_USE_POINT_SIZE]) {
-
code += "\tPOINT_SIZE=point_size;\n";
}
if (shading_mode == SHADING_MODE_PER_VERTEX) {
-
code += "\tROUGHNESS=roughness;\n";
}
@@ -670,10 +733,8 @@ void BaseMaterial3D::_update_shader() {
switch (billboard_mode) {
case BILLBOARD_DISABLED: {
-
} break;
case BILLBOARD_ENABLED: {
-
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
@@ -681,7 +742,6 @@ void BaseMaterial3D::_update_shader() {
}
} break;
case BILLBOARD_FIXED_Y: {
-
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
@@ -691,7 +751,6 @@ void BaseMaterial3D::_update_shader() {
}
} break;
case BILLBOARD_PARTICLES: {
-
//make billboard
code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n";
//rotate by rotation
@@ -712,10 +771,11 @@ void BaseMaterial3D::_update_shader() {
code += "\tUV /= vec2(h_frames, v_frames);\n";
code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n";
} break;
+ case BILLBOARD_MAX:
+ break; // Internal value, skip.
}
if (flags[FLAG_FIXED_SIZE]) {
-
code += "\tif (PROJECTION_MATRIX[3][3] != 0.0) {\n";
//orthogonal matrix, try to do about the same
//with viewport size
@@ -750,7 +810,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
-
code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
@@ -758,7 +817,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
-
code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
@@ -887,6 +945,8 @@ void BaseMaterial3D::_update_shader() {
case TEXTURE_CHANNEL_GRAYSCALE: {
code += "\tvec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n";
} break;
+ case TEXTURE_CHANNEL_MAX:
+ break; // Internal value, skip.
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
@@ -939,7 +999,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_REFRACTION]) {
-
if (features[FEATURE_NORMAL_MAPPING]) {
code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) );\n";
} else {
@@ -955,10 +1014,17 @@ void BaseMaterial3D::_update_shader() {
code += "\tALBEDO *= 1.0 - ref_amount;\n";
code += "\tALPHA = 1.0;\n";
- } else if (transparency == TRANSPARENCY_ALPHA || transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
+ } else if (transparency != TRANSPARENCY_DISABLED || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
code += "\tALPHA = albedo.a * albedo_tex.a;\n";
+ }
+ if (transparency == TRANSPARENCY_ALPHA_HASH) {
+ code += "\tALPHA_HASH_SCALE = alpha_hash_scale;\n";
} else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
- code += "\tif (albedo.a * albedo_tex.a < alpha_scissor_threshold) discard;\n";
+ code += "\tALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold;\n";
+ }
+ if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR)) {
+ code += "\tALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n";
+ code += "\tALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n";
}
if (proximity_fade_enabled) {
@@ -970,7 +1036,6 @@ void BaseMaterial3D::_update_shader() {
if (distance_fade != DISTANCE_FADE_DISABLED) {
if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) {
-
if (!RenderingServer::get_singleton()->is_low_end()) {
code += "\t{\n";
if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) {
@@ -1044,7 +1109,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
-
if (!orm) {
if (flags[FLAG_AO_ON_UV2]) {
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
@@ -1067,7 +1131,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_SUBSURFACE_SCATTERING]) {
-
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
} else {
@@ -1077,7 +1140,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
-
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tvec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
@@ -1100,7 +1162,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_DETAIL]) {
-
bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2);
if (triplanar) {
@@ -1115,7 +1176,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
-
code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
@@ -1134,6 +1194,8 @@ void BaseMaterial3D::_update_shader() {
case BLEND_MODE_MUL: {
code += "\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n";
} break;
+ case BLEND_MODE_MAX:
+ break; // Internal value, skip.
}
code += "\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n";
@@ -1155,17 +1217,14 @@ void BaseMaterial3D::_update_shader() {
}
void BaseMaterial3D::flush_changes() {
-
MutexLock lock(material_mutex);
while (dirty_materials->first()) {
-
dirty_materials->first()->self()->_update_shader();
}
}
void BaseMaterial3D::_queue_shader_change() {
-
MutexLock lock(material_mutex);
if (!element.in_list()) {
@@ -1174,167 +1233,144 @@ void BaseMaterial3D::_queue_shader_change() {
}
bool BaseMaterial3D::_is_shader_dirty() const {
-
MutexLock lock(material_mutex);
return element.in_list();
}
-void BaseMaterial3D::set_albedo(const Color &p_albedo) {
+void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
}
Color BaseMaterial3D::get_albedo() const {
-
return albedo;
}
void BaseMaterial3D::set_specular(float p_specular) {
-
specular = p_specular;
RS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
}
float BaseMaterial3D::get_specular() const {
-
return specular;
}
void BaseMaterial3D::set_roughness(float p_roughness) {
-
roughness = p_roughness;
RS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
}
float BaseMaterial3D::get_roughness() const {
-
return roughness;
}
void BaseMaterial3D::set_metallic(float p_metallic) {
-
metallic = p_metallic;
RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
}
float BaseMaterial3D::get_metallic() const {
-
return metallic;
}
void BaseMaterial3D::set_emission(const Color &p_emission) {
-
emission = p_emission;
RS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
}
-Color BaseMaterial3D::get_emission() const {
+Color BaseMaterial3D::get_emission() const {
return emission;
}
void BaseMaterial3D::set_emission_energy(float p_emission_energy) {
-
emission_energy = p_emission_energy;
RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy);
}
-float BaseMaterial3D::get_emission_energy() const {
+float BaseMaterial3D::get_emission_energy() const {
return emission_energy;
}
void BaseMaterial3D::set_normal_scale(float p_normal_scale) {
-
normal_scale = p_normal_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale);
}
-float BaseMaterial3D::get_normal_scale() const {
+float BaseMaterial3D::get_normal_scale() const {
return normal_scale;
}
void BaseMaterial3D::set_rim(float p_rim) {
-
rim = p_rim;
RS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
}
-float BaseMaterial3D::get_rim() const {
+float BaseMaterial3D::get_rim() const {
return rim;
}
void BaseMaterial3D::set_rim_tint(float p_rim_tint) {
-
rim_tint = p_rim_tint;
RS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint);
}
-float BaseMaterial3D::get_rim_tint() const {
+float BaseMaterial3D::get_rim_tint() const {
return rim_tint;
}
void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) {
-
ao_light_affect = p_ao_light_affect;
RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect);
}
-float BaseMaterial3D::get_ao_light_affect() const {
+float BaseMaterial3D::get_ao_light_affect() const {
return ao_light_affect;
}
void BaseMaterial3D::set_clearcoat(float p_clearcoat) {
-
clearcoat = p_clearcoat;
RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
}
float BaseMaterial3D::get_clearcoat() const {
-
return clearcoat;
}
void BaseMaterial3D::set_clearcoat_gloss(float p_clearcoat_gloss) {
-
clearcoat_gloss = p_clearcoat_gloss;
RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss);
}
float BaseMaterial3D::get_clearcoat_gloss() const {
-
return clearcoat_gloss;
}
void BaseMaterial3D::set_anisotropy(float p_anisotropy) {
-
anisotropy = p_anisotropy;
RS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
}
-float BaseMaterial3D::get_anisotropy() const {
+float BaseMaterial3D::get_anisotropy() const {
return anisotropy;
}
void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) {
-
heightmap_scale = p_heightmap_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale);
}
float BaseMaterial3D::get_heightmap_scale() const {
-
return heightmap_scale;
}
void BaseMaterial3D::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
-
subsurface_scattering_strength = p_subsurface_scattering_strength;
RS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
}
float BaseMaterial3D::get_subsurface_scattering_strength() const {
-
return subsurface_scattering_strength;
}
@@ -1351,6 +1387,7 @@ void BaseMaterial3D::set_transmittance_depth(float p_depth) {
transmittance_depth = p_depth;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth);
}
+
float BaseMaterial3D::get_transmittance_depth() const {
return transmittance_depth;
}
@@ -1359,6 +1396,7 @@ void BaseMaterial3D::set_transmittance_curve(float p_curve) {
transmittance_curve = p_curve;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve);
}
+
float BaseMaterial3D::get_transmittance_curve() const {
return transmittance_curve;
}
@@ -1367,70 +1405,65 @@ void BaseMaterial3D::set_transmittance_boost(float p_boost) {
transmittance_boost = p_boost;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
}
+
float BaseMaterial3D::get_transmittance_boost() const {
return transmittance_boost;
}
void BaseMaterial3D::set_backlight(const Color &p_backlight) {
-
backlight = p_backlight;
RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight);
}
Color BaseMaterial3D::get_backlight() const {
-
return backlight;
}
void BaseMaterial3D::set_refraction(float p_refraction) {
-
refraction = p_refraction;
RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
}
float BaseMaterial3D::get_refraction() const {
-
return refraction;
}
void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) {
-
- if (detail_uv == p_detail_uv)
+ if (detail_uv == p_detail_uv) {
return;
+ }
detail_uv = p_detail_uv;
_queue_shader_change();
}
-BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
+BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
return detail_uv;
}
void BaseMaterial3D::set_blend_mode(BlendMode p_mode) {
-
- if (blend_mode == p_mode)
+ if (blend_mode == p_mode) {
return;
+ }
blend_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
return blend_mode;
}
void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) {
-
detail_blend_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
return detail_blend_mode;
}
void BaseMaterial3D::set_transparency(Transparency p_transparency) {
-
if (transparency == p_transparency) {
return;
}
@@ -1444,8 +1477,21 @@ BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const {
return transparency;
}
-void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
+void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) {
+ if (alpha_antialiasing_mode == p_alpha_aa) {
+ return;
+ }
+ alpha_antialiasing_mode = p_alpha_aa;
+ _queue_shader_change();
+ _change_notify();
+}
+
+BaseMaterial3D::AlphaAntiAliasing BaseMaterial3D::get_alpha_antialiasing() const {
+ return alpha_antialiasing_mode;
+}
+
+void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
if (shading_mode == p_shading_mode) {
return;
}
@@ -1460,63 +1506,63 @@ BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const {
}
void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) {
-
- if (depth_draw_mode == p_mode)
+ if (depth_draw_mode == p_mode) {
return;
+ }
depth_draw_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
+BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
return depth_draw_mode;
}
void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
-
- if (cull_mode == p_mode)
+ if (cull_mode == p_mode) {
return;
+ }
cull_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
+BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
return cull_mode;
}
void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) {
-
- if (diffuse_mode == p_mode)
+ if (diffuse_mode == p_mode) {
return;
+ }
diffuse_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
+BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
return diffuse_mode;
}
void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) {
-
- if (specular_mode == p_mode)
+ if (specular_mode == p_mode) {
return;
+ }
specular_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
+BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
return specular_mode;
}
void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- if (flags[p_flag] == p_enabled)
+ if (flags[p_flag] == p_enabled) {
return;
+ }
flags[p_flag] = p_enabled;
if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) {
@@ -1526,16 +1572,15 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
}
bool BaseMaterial3D::get_flag(Flags p_flag) const {
-
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags[p_flag];
}
void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
-
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
- if (features[p_feature] == p_enabled)
+ if (features[p_feature] == p_enabled) {
return;
+ }
features[p_feature] = p_enabled;
_change_notify();
@@ -1543,23 +1588,24 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
}
bool BaseMaterial3D::get_feature(Feature p_feature) const {
-
ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false);
return features[p_feature];
}
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+ if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) {
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
+ Vector2i(p_texture->get_width(), p_texture->get_height()));
+ }
_change_notify();
_queue_shader_change();
}
Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
-
ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture2D>());
return textures[p_param];
}
@@ -1567,8 +1613,9 @@ Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
Ref<Texture2D> BaseMaterial3D::get_texture_by_name(StringName p_name) const {
for (int i = 0; i < (int)BaseMaterial3D::TEXTURE_MAX; i++) {
TextureParam param = TextureParam(i);
- if (p_name == shader_names->texture_names[param])
+ if (p_name == shader_names->texture_names[param]) {
return textures[param];
+ }
}
return Ref<Texture2D>();
}
@@ -1629,10 +1676,34 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
+ // you can only enable anti-aliasing (in mataerials) on alpha scissor and alpha hash
+ const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH);
+ // alpha anti aliasiasing is only enabled when you can select aa
+ const bool alpha_aa_enabled = (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) && can_select_aa;
+
+ // alpha scissor slider isn't needed when alpha antialiasing is enabled
if (property.name == "alpha_scissor_threshold" && transparency != TRANSPARENCY_ALPHA_SCISSOR) {
property.usage = 0;
}
+ // alpha hash scale slider is only needed if transparency is alpha hash
+ if (property.name == "alpha_hash_scale" && transparency != TRANSPARENCY_ALPHA_HASH) {
+ property.usage = 0;
+ }
+
+ if (property.name == "alpha_antialiasing_mode" && !can_select_aa) {
+ property.usage = 0;
+ }
+
+ // we cant choose an antialiasing mode if alpha isnt possible
+ if (property.name == "alpha_antialiasing_edge" && !alpha_aa_enabled) {
+ property.usage = 0;
+ }
+
+ if (property.name == "blend_mode" && alpha_aa_enabled) {
+ property.usage = 0;
+ }
+
if ((property.name == "heightmap_min_layers" || property.name == "heightmap_max_layers") && !deep_parallax) {
property.usage = 0;
}
@@ -1642,7 +1713,6 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
}
if (orm) {
-
if (property.name == "shading_mode") {
property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness.
}
@@ -1657,9 +1727,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
}
if (shading_mode != SHADING_MODE_PER_PIXEL) {
-
if (shading_mode != SHADING_MODE_PER_VERTEX) {
-
//these may still work per vertex
if (property.name.begins_with("ao")) {
property.usage = 0;
@@ -1708,176 +1776,148 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
}
void BaseMaterial3D::set_point_size(float p_point_size) {
-
point_size = p_point_size;
RS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size);
}
float BaseMaterial3D::get_point_size() const {
-
return point_size;
}
void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) {
-
uv1_scale = p_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
}
Vector3 BaseMaterial3D::get_uv1_scale() const {
-
return uv1_scale;
}
void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) {
-
uv1_offset = p_offset;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
}
-Vector3 BaseMaterial3D::get_uv1_offset() const {
+Vector3 BaseMaterial3D::get_uv1_offset() const {
return uv1_offset;
}
void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
-
uv1_triplanar_sharpness = p_sharpness;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness);
}
float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const {
-
return uv1_triplanar_sharpness;
}
void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) {
-
uv2_scale = p_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
}
Vector3 BaseMaterial3D::get_uv2_scale() const {
-
return uv2_scale;
}
void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) {
-
uv2_offset = p_offset;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
}
Vector3 BaseMaterial3D::get_uv2_offset() const {
-
return uv2_offset;
}
void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
-
uv2_triplanar_sharpness = p_sharpness;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness);
}
float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
-
return uv2_triplanar_sharpness;
}
void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
-
billboard_mode = p_mode;
_queue_shader_change();
_change_notify();
}
BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const {
-
return billboard_mode;
}
void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) {
-
particles_anim_h_frames = p_frames;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
}
int BaseMaterial3D::get_particles_anim_h_frames() const {
-
return particles_anim_h_frames;
}
-void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
+void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
}
int BaseMaterial3D::get_particles_anim_v_frames() const {
-
return particles_anim_v_frames;
}
void BaseMaterial3D::set_particles_anim_loop(bool p_loop) {
-
particles_anim_loop = p_loop;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
}
bool BaseMaterial3D::get_particles_anim_loop() const {
-
return particles_anim_loop;
}
void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
-
deep_parallax = p_enable;
_queue_shader_change();
_change_notify();
}
bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const {
-
return deep_parallax;
}
void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) {
-
deep_parallax_min_layers = p_layer;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer);
}
-int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
return deep_parallax_min_layers;
}
void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) {
-
deep_parallax_max_layers = p_layer;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer);
}
-int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
return deep_parallax_max_layers;
}
void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) {
-
heightmap_parallax_flip_tangent = p_flip;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const {
-
return heightmap_parallax_flip_tangent;
}
void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) {
-
heightmap_parallax_flip_binormal = p_flip;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
-
return heightmap_parallax_flip_binormal;
}
@@ -1897,17 +1937,33 @@ void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) {
}
float BaseMaterial3D::get_alpha_scissor_threshold() const {
-
return alpha_scissor_threshold;
}
+void BaseMaterial3D::set_alpha_hash_scale(float p_scale) {
+ alpha_hash_scale = p_scale;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_hash_scale, p_scale);
+}
+
+float BaseMaterial3D::get_alpha_hash_scale() const {
+ return alpha_hash_scale;
+}
+
+void BaseMaterial3D::set_alpha_antialiasing_edge(float p_edge) {
+ alpha_antialiasing_edge = p_edge;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_antialiasing_edge, p_edge);
+}
+
+float BaseMaterial3D::get_alpha_antialiasing_edge() const {
+ return alpha_antialiasing_edge;
+}
+
void BaseMaterial3D::set_grow(float p_grow) {
grow = p_grow;
RS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow);
}
float BaseMaterial3D::get_grow() const {
-
return grow;
}
@@ -1934,7 +1990,6 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() co
}
void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) {
-
ERR_FAIL_INDEX(p_channel, 5);
roughness_texture_channel = p_channel;
_queue_shader_change();
@@ -1945,7 +2000,6 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() c
}
void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) {
-
ERR_FAIL_INDEX(p_channel, 5);
ao_texture_channel = p_channel;
RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
@@ -1956,7 +2010,6 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const {
}
void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) {
-
ERR_FAIL_INDEX(p_channel, 5);
refraction_texture_channel = p_channel;
RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
@@ -1967,22 +2020,28 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel()
}
RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
-
int version = 0;
- if (p_shaded)
+ if (p_shaded) {
version = 1;
- if (p_transparent)
+ }
+ if (p_transparent) {
version |= 2;
- if (p_cut_alpha)
+ }
+ if (p_cut_alpha) {
version |= 4;
- if (p_opaque_prepass)
+ }
+ if (p_opaque_prepass) {
version |= 8;
- if (p_double_sided)
+ }
+ if (p_double_sided) {
version |= 16;
- if (p_billboard)
+ }
+ if (p_billboard) {
version |= 32;
- if (p_billboard_y)
+ }
+ if (p_billboard_y) {
version |= 64;
+ }
if (materials_for_2d[version].is_valid()) {
return materials_for_2d[version]->get_rid();
@@ -2013,91 +2072,86 @@ void BaseMaterial3D::set_on_top_of_alpha() {
}
void BaseMaterial3D::set_proximity_fade(bool p_enable) {
-
proximity_fade_enabled = p_enable;
_queue_shader_change();
_change_notify();
}
bool BaseMaterial3D::is_proximity_fade_enabled() const {
-
return proximity_fade_enabled;
}
void BaseMaterial3D::set_proximity_fade_distance(float p_distance) {
-
proximity_fade_distance = p_distance;
RS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance);
}
-float BaseMaterial3D::get_proximity_fade_distance() const {
+float BaseMaterial3D::get_proximity_fade_distance() const {
return proximity_fade_distance;
}
void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
-
distance_fade = p_mode;
_queue_shader_change();
_change_notify();
}
-BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
+BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
return distance_fade;
}
void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) {
-
distance_fade_max_distance = p_distance;
RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
}
-float BaseMaterial3D::get_distance_fade_max_distance() const {
+float BaseMaterial3D::get_distance_fade_max_distance() const {
return distance_fade_max_distance;
}
void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) {
-
distance_fade_min_distance = p_distance;
RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
}
float BaseMaterial3D::get_distance_fade_min_distance() const {
-
return distance_fade_min_distance;
}
void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) {
-
- if (emission_op == p_op)
+ if (emission_op == p_op) {
return;
+ }
emission_op = p_op;
_queue_shader_change();
}
BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
-
return emission_op;
}
RID BaseMaterial3D::get_shader_rid() const {
-
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
Shader::Mode BaseMaterial3D::get_shader_mode() const {
-
return Shader::MODE_SPATIAL;
}
void BaseMaterial3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &BaseMaterial3D::set_albedo);
ClassDB::bind_method(D_METHOD("get_albedo"), &BaseMaterial3D::get_albedo);
ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &BaseMaterial3D::set_transparency);
ClassDB::bind_method(D_METHOD("get_transparency"), &BaseMaterial3D::get_transparency);
+ ClassDB::bind_method(D_METHOD("set_alpha_antialiasing", "alpha_aa"), &BaseMaterial3D::set_alpha_antialiasing);
+ ClassDB::bind_method(D_METHOD("get_alpha_antialiasing"), &BaseMaterial3D::get_alpha_antialiasing);
+
+ ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge", "edge"), &BaseMaterial3D::set_alpha_antialiasing_edge);
+ ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge"), &BaseMaterial3D::get_alpha_antialiasing_edge);
+
ClassDB::bind_method(D_METHOD("set_shading_mode", "shading_mode"), &BaseMaterial3D::set_shading_mode);
ClassDB::bind_method(D_METHOD("get_shading_mode"), &BaseMaterial3D::get_shading_mode);
@@ -2251,6 +2305,9 @@ void BaseMaterial3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &BaseMaterial3D::set_alpha_scissor_threshold);
ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &BaseMaterial3D::get_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &BaseMaterial3D::set_alpha_hash_scale);
+ ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &BaseMaterial3D::get_alpha_hash_scale);
+
ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &BaseMaterial3D::set_grow_enabled);
ClassDB::bind_method(D_METHOD("is_grow_enabled"), &BaseMaterial3D::is_grow_enabled);
@@ -2282,8 +2339,11 @@ void BaseMaterial3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance);
ADD_GROUP("Transparency", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,AlphaScissor,DepthPrePass"), "set_transparency", "get_transparency");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth PrePass"), "set_transparency", "get_transparency");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge");
ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode");
@@ -2479,6 +2539,7 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(TRANSPARENCY_DISABLED);
BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA);
BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_SCISSOR);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_HASH);
BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
BIND_ENUM_CONSTANT(TRANSPARENCY_MAX);
@@ -2506,6 +2567,10 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(BLEND_MODE_SUB);
BIND_ENUM_CONSTANT(BLEND_MODE_MUL);
+ BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_OFF);
+ BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE);
+ BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE);
+
BIND_ENUM_CONSTANT(DEPTH_DRAW_OPAQUE_ONLY);
BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS);
BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED);
@@ -2569,11 +2634,11 @@ void BaseMaterial3D::_bind_methods() {
BaseMaterial3D::BaseMaterial3D(bool p_orm) :
element(this) {
-
orm = p_orm;
// Initialize to the same values as the shader
- transparency = TRANSPARENCY_DISABLED;
shading_mode = SHADING_MODE_PER_PIXEL;
+ transparency = TRANSPARENCY_DISABLED;
+ alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
set_specular(0.5);
set_roughness(1.0);
@@ -2605,9 +2670,14 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_particles_anim_h_frames(1);
set_particles_anim_v_frames(1);
set_particles_anim_loop(false);
- set_alpha_scissor_threshold(0.98);
emission_op = EMISSION_OP_ADD;
+ set_transparency(TRANSPARENCY_DISABLED);
+ set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF);
+ set_alpha_scissor_threshold(0.05);
+ set_alpha_hash_scale(1.0);
+ set_alpha_antialiasing_edge(0.3);
+
proximity_fade_enabled = false;
distance_fade = DISTANCE_FADE_DISABLED;
set_proximity_fade_distance(1);
@@ -2637,7 +2707,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY;
cull_mode = CULL_BACK;
for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = 0;
+ flags[i] = false;
}
flags[FLAG_USE_TEXTURE_REPEAT] = true;
@@ -2648,15 +2718,12 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
features[i] = false;
}
- current_key.key0 = 0;
- current_key.key1 = 0;
- current_key.invalid_key = 1;
texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
+
_queue_shader_change();
}
BaseMaterial3D::~BaseMaterial3D() {
-
MutexLock lock(material_mutex);
if (shader_map.has(current_key)) {
@@ -2700,6 +2767,12 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value)
set_transparency(TRANSPARENCY_ALPHA_SCISSOR);
}
return true;
+ } else if (p_name == "params_use_alpha_hash") {
+ bool use_hash = p_value;
+ if (use_hash) {
+ set_transparency(TRANSPARENCY_ALPHA_HASH);
+ }
+ return true;
} else if (p_name == "params_depth_draw_mode") {
int mode = p_value;
if (mode == 3) {
@@ -2734,6 +2807,8 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value)
{ "params_grow", "grow" },
{ "params_grow_amount", "grow_amount" },
{ "params_alpha_scissor_threshold", "alpha_scissor_threshold" },
+ { "params_alpha_hash_scale", "alpha_hash_scale" },
+ { "params_alpha_antialiasing_edge", "alpha_antialiasing_edge" },
{ "depth_scale", "heightmap_scale" },
{ "depth_deep_parallax", "heightmap_deep_parallax" },