Add new StandardMaterial properties to allow users to control FPS-style objects (hands, weapons, tools close to the camera)

Add new shader built in Z_CLIP_SCALE to easily adjust clipping distance to avoid clipping walls etc.

Add fov_override to StandardMaterial3D to easily have a custom FOV for FPS objects

Add IN_SHADOW_PASS built-in to shaders for tweaking materials without impacting shadow maps
This commit is contained in:
clayjohn 2024-06-13 15:16:18 -07:00
parent 25a3c27c41
commit 9a1def8da1
15 changed files with 254 additions and 90 deletions

View file

@ -666,6 +666,8 @@ void BaseMaterial3D::init_shaders() {
shader_names->alpha_antialiasing_edge = "alpha_antialiasing_edge";
shader_names->albedo_texture_size = "albedo_texture_size";
shader_names->z_clip_scale = "z_clip_scale";
shader_names->fov_override = "fov_override";
}
HashMap<uint64_t, Ref<StandardMaterial3D>> BaseMaterial3D::materials_for_2d;
@ -1135,6 +1137,14 @@ uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
)";
if (flags[FLAG_USE_Z_CLIP_SCALE]) {
code += "uniform float z_clip_scale : hint_range(0.01, 1.0, 0.01);\n";
}
if (flags[FLAG_USE_FOV_OVERRIDE]) {
code += "uniform float fov_override : hint_range(1.0, 179.0, 0.1);\n";
}
// Generate vertex shader.
code += R"(
void vertex() {)";
@ -1378,6 +1388,25 @@ void vertex() {)";
)";
}
if (flags[FLAG_USE_Z_CLIP_SCALE]) {
code += R"(
Z_CLIP_SCALE = z_clip_scale;
)";
}
if (flags[FLAG_USE_FOV_OVERRIDE]) {
code += R"(
if (!IN_SHADOW_PASS) {
float flip_y = sign(PROJECTION_MATRIX[1][1]);
float aspect = PROJECTION_MATRIX[1][1] / PROJECTION_MATRIX[0][0];
float f = flip_y / tan(fov_override * PI / 360.0);
PROJECTION_MATRIX[0][0] = f / aspect;
PROJECTION_MATRIX[1][1] = f;
}
)";
}
// End of the vertex shader function.
code += "}\n";
if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
@ -2375,7 +2404,9 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
p_flag == FLAG_SUBSURFACE_MODE_SKIN ||
p_flag == FLAG_USE_POINT_SIZE ||
p_flag == FLAG_UV1_USE_TRIPLANAR ||
p_flag == FLAG_UV2_USE_TRIPLANAR) {
p_flag == FLAG_UV2_USE_TRIPLANAR ||
p_flag == FLAG_USE_Z_CLIP_SCALE ||
p_flag == FLAG_USE_FOV_OVERRIDE) {
notify_property_list_changed();
}
@ -2510,6 +2541,14 @@ void BaseMaterial3D::_validate_property(PropertyInfo &p_property) const {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
if (p_property.name == "z_clip_scale" && !flags[FLAG_USE_Z_CLIP_SCALE]) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
if (p_property.name == "fov_override" && !flags[FLAG_USE_FOV_OVERRIDE]) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
// you can only enable anti-aliasing (in materials) 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
@ -2860,6 +2899,24 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel()
return refraction_texture_channel;
}
void BaseMaterial3D::set_z_clip_scale(float p_z_clip_scale) {
z_clip_scale = p_z_clip_scale;
_material_set_param(shader_names->z_clip_scale, p_z_clip_scale);
}
float BaseMaterial3D::get_z_clip_scale() const {
return z_clip_scale;
}
void BaseMaterial3D::set_fov_override(float p_fov_override) {
fov_override = p_fov_override;
_material_set_param(shader_names->fov_override, p_fov_override);
}
float BaseMaterial3D::get_fov_override() const {
return fov_override;
}
Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, AlphaAntiAliasing p_alpha_antialiasing_mode, RID *r_shader_rid) {
uint64_t key = 0;
key |= ((int8_t)p_shaded & 0x01) << 0;
@ -3212,6 +3269,12 @@ void BaseMaterial3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &BaseMaterial3D::set_distance_fade_min_distance);
ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance);
ClassDB::bind_method(D_METHOD("set_z_clip_scale", "scale"), &BaseMaterial3D::set_z_clip_scale);
ClassDB::bind_method(D_METHOD("get_z_clip_scale"), &BaseMaterial3D::get_z_clip_scale);
ClassDB::bind_method(D_METHOD("set_fov_override", "scale"), &BaseMaterial3D::set_fov_override);
ClassDB::bind_method(D_METHOD("get_fov_override"), &BaseMaterial3D::get_fov_override);
ADD_GROUP("Transparency", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass"), "set_transparency", "get_transparency");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
@ -3381,7 +3444,10 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1,suffix:px"), "set_point_size", "get_point_size");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_particle_trails"), "set_flag", "get_flag", FLAG_PARTICLE_TRAILS_MODE);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_z_clip_scale"), "set_flag", "get_flag", FLAG_USE_Z_CLIP_SCALE);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "z_clip_scale", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"), "set_z_clip_scale", "get_z_clip_scale");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_fov_override"), "set_flag", "get_flag", FLAG_USE_FOV_OVERRIDE);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov_override", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov_override", "get_fov_override");
ADD_GROUP("Proximity Fade", "proximity_fade_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enabled"), "set_proximity_fade_enabled", "is_proximity_fade_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0.01,4096,0.01,suffix:m"), "set_proximity_fade_distance", "get_proximity_fade_distance");
@ -3495,6 +3561,8 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_MSDF);
BIND_ENUM_CONSTANT(FLAG_DISABLE_FOG);
BIND_ENUM_CONSTANT(FLAG_DISABLE_SPECULAR_OCCLUSION);
BIND_ENUM_CONSTANT(FLAG_USE_Z_CLIP_SCALE);
BIND_ENUM_CONSTANT(FLAG_USE_FOV_OVERRIDE);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
@ -3589,6 +3657,9 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_heightmap_deep_parallax_max_layers(32);
set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal
set_z_clip_scale(1.0);
set_fov_override(75.0);
flags[FLAG_ALBEDO_TEXTURE_MSDF] = false;
flags[FLAG_USE_TEXTURE_REPEAT] = true;