diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-07-08 12:34:05 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-07-08 12:36:15 -0300 |
commit | f4c8c552f956094e1bb8787de79476f57dd6a7b6 (patch) | |
tree | 4ed1eb9e7d0a9401db6eaaadf257d8e73e03b499 /scene/resources | |
parent | 0067982f5ece3145c00e2f4c0bc092d1ec28c8b3 (diff) |
Added triplanar mapping, toon mode, and more specular modes for materials. Added multipass support for materials.
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/material.cpp | 108 | ||||
-rw-r--r-- | scene/resources/material.h | 34 |
2 files changed, 136 insertions, 6 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index d9bd9eca6d..22c7744c84 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -30,11 +30,36 @@ #include "material.h" #include "scene/scene_string_names.h" +void Material::set_next_pass(const Ref<Material> &p_pass) { + + if (next_pass == p_pass) + return; + + next_pass = p_pass; + RID next_pass_rid; + if (next_pass.is_valid()) + next_pass_rid = next_pass->get_rid(); + VS::get_singleton()->material_set_next_pass(material, next_pass_rid); +} + +Ref<Material> Material::get_next_pass() const { + + return next_pass; +} + RID Material::get_rid() const { return material; } +void Material::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass:Material"), &Material::set_next_pass); + ClassDB::bind_method(D_METHOD("get_next_pass:Material"), &Material::get_next_pass); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass"); +} + Material::Material() { material = VisualServer::get_singleton()->material_create(); @@ -207,6 +232,8 @@ void SpatialMaterial::init_shaders() { shader_names->depth_min_layers = "depth_min_layers"; shader_names->depth_max_layers = "depth_max_layers"; + shader_names->grow = "grow"; + shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo"; shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic"; shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness"; @@ -291,6 +318,13 @@ void SpatialMaterial::_update_shader() { case DIFFUSE_HALF_LAMBERT: code += ",diffuse_half_lambert"; break; case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break; case DIFFUSE_BURLEY: code += ",diffuse_burley"; break; + case DIFFUSE_TOON: code += ",diffuse_toon"; break; + } + 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; } if (flags[FLAG_UNSHADED]) { @@ -309,6 +343,9 @@ void SpatialMaterial::_update_shader() { code += "uniform sampler2D texture_albedo : hint_albedo;\n"; code += "uniform float specular;\n"; code += "uniform float metallic;\n"; + if (grow_enabled) { + code += "uniform float grow;\n"; + } code += "uniform float roughness : hint_range(0,1);\n"; code += "uniform float point_size : hint_range(0,128);\n"; @@ -492,6 +529,10 @@ void SpatialMaterial::_update_shader() { code += "\tuv2_world_pos *= vec3(1.0,-1.0, 1.0);\n"; } + if (grow_enabled) { + code += "\tVERTEX+=NORMAL*grow;\n"; + } + code += "}\n"; code += "\n\n"; if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) { @@ -642,7 +683,7 @@ void SpatialMaterial::_update_shader() { } else { code += "\tvec3 anisotropy_tex = texture(texture_flowmap,base_uv).rga;\n"; } - code += "\tANISOTROPY = anisotropy_ratio*anisotropy_tex.a;\n"; + code += "\tANISOTROPY = anisotropy_ratio*anisotropy_tex.b;\n"; code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n"; } @@ -1003,6 +1044,19 @@ SpatialMaterial::DiffuseMode SpatialMaterial::get_diffuse_mode() const { return diffuse_mode; } +void SpatialMaterial::set_specular_mode(SpecularMode p_mode) { + + if (specular_mode == p_mode) + return; + + specular_mode = p_mode; + _queue_shader_change(); +} +SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const { + + return specular_mode; +} + void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -1075,6 +1129,10 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) { property.usage = 0; } + + if (property.name == "params_grow_amount" && !grow_enabled) { + property.usage = 0; + } } void SpatialMaterial::set_line_width(float p_line_width) { @@ -1240,6 +1298,26 @@ int SpatialMaterial::get_depth_deep_parallax_max_layers() const { return deep_parallax_max_layers; } +void SpatialMaterial::set_grow_enabled(bool p_enable) { + grow_enabled = p_enable; + _queue_shader_change(); + _change_notify(); +} + +bool SpatialMaterial::is_grow_enabled() const { + return grow_enabled; +} + +void SpatialMaterial::set_grow(float p_grow) { + grow = p_grow; + VS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow); +} + +float SpatialMaterial::get_grow() const { + + return grow; +} + void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo); @@ -1308,6 +1386,9 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &SpatialMaterial::set_diffuse_mode); ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &SpatialMaterial::get_diffuse_mode); + ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &SpatialMaterial::set_specular_mode); + ClassDB::bind_method(D_METHOD("get_specular_mode"), &SpatialMaterial::get_specular_mode); + ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &SpatialMaterial::set_flag); ClassDB::bind_method(D_METHOD("get_flag"), &SpatialMaterial::get_flag); @@ -1359,6 +1440,12 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers); ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers); + ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow); + ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow); + + ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &SpatialMaterial::set_grow_enabled); + ClassDB::bind_method(D_METHOD("is_grow_enabled"), &SpatialMaterial::is_grow_enabled); + 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); @@ -1370,13 +1457,16 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR); ADD_GROUP("Parameters", "params_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_diffuse_mode", PROPERTY_HINT_ENUM, "Lambert,Lambert Wrap,Oren Nayar,Burley"), "set_diffuse_mode", "get_diffuse_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "params_diffuse_mode", PROPERTY_HINT_ENUM, "Lambert,Lambert Wrap,Oren Nayar,Burley,Toon"), "set_diffuse_mode", "get_diffuse_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "params_specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon"), "set_specular_mode", "get_specular_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "params_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "params_cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode"); 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 Billboard"), "set_billboard_mode", "get_billboard_mode"); + 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"); ADD_GROUP("Particles Anim", "particles_anim_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); @@ -1458,13 +1548,13 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_scale"), "set_uv1_scale", "get_uv1_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_offset"), "set_uv1_offset", "get_uv1_offset"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_TRIPLANAR); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv1_triplanar_sharpness"), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv1_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness"); ADD_GROUP("UV2", "uv2_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_scale"), "set_uv2_scale", "get_uv2_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_offset"), "set_uv2_offset", "get_uv2_offset"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_TRIPLANAR); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness"), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness"); BIND_CONSTANT(TEXTURE_ALBEDO); BIND_CONSTANT(TEXTURE_METALLIC); @@ -1525,6 +1615,12 @@ void SpatialMaterial::_bind_methods() { BIND_CONSTANT(DIFFUSE_HALF_LAMBERT); BIND_CONSTANT(DIFFUSE_OREN_NAYAR); BIND_CONSTANT(DIFFUSE_BURLEY); + BIND_CONSTANT(DIFFUSE_TOON); + + BIND_CONSTANT(SPECULAR_SCHLICK_GGX); + BIND_CONSTANT(SPECULAR_BLINN); + BIND_CONSTANT(SPECULAR_PHONG); + BIND_CONSTANT(SPECULAR_TOON); BIND_CONSTANT(BILLBOARD_DISABLED); BIND_CONSTANT(BILLBOARD_ENABLED); @@ -1564,6 +1660,9 @@ SpatialMaterial::SpatialMaterial() set_particles_anim_v_frames(1); set_particles_anim_loop(false); + grow_enabled = false; + set_grow(0.0); + deep_parallax = false; set_depth_deep_parallax_min_layers(8); set_depth_deep_parallax_max_layers(32); @@ -1577,6 +1676,7 @@ SpatialMaterial::SpatialMaterial() flags[i] = 0; } diffuse_mode = DIFFUSE_LAMBERT; + specular_mode = SPECULAR_SCHLICK_GGX; for (int i = 0; i < FEATURE_MAX; i++) { features[i] = false; diff --git a/scene/resources/material.h b/scene/resources/material.h index 80732be8de..1a9822a1c8 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -47,11 +47,16 @@ class Material : public Resource { OBJ_SAVE_TYPE(Material) RID material; + Ref<Material> next_pass; protected: _FORCE_INLINE_ RID _get_material() const { return material; } + static void _bind_methods(); public: + void set_next_pass(const Ref<Material> &p_pass); + Ref<Material> get_next_pass() const; + virtual RID get_rid() const; Material(); virtual ~Material(); @@ -166,6 +171,14 @@ public: DIFFUSE_HALF_LAMBERT, DIFFUSE_OREN_NAYAR, DIFFUSE_BURLEY, + DIFFUSE_TOON, + }; + + enum SpecularMode { + SPECULAR_SCHLICK_GGX, + SPECULAR_BLINN, + SPECULAR_PHONG, + SPECULAR_TOON, }; enum BillboardMode { @@ -186,10 +199,12 @@ private: uint64_t cull_mode : 2; uint64_t flags : 9; uint64_t detail_blend_mode : 2; - uint64_t diffuse_mode : 2; + uint64_t diffuse_mode : 3; + uint64_t specular_mode : 2; uint64_t invalid_key : 1; uint64_t deep_parallax : 1; uint64_t billboard_mode : 2; + uint64_t grow : 1; }; uint64_t key; @@ -228,9 +243,10 @@ private: } mk.detail_blend_mode = detail_blend_mode; mk.diffuse_mode = diffuse_mode; + mk.specular_mode = specular_mode; mk.billboard_mode = billboard_mode; mk.deep_parallax = deep_parallax ? 1 : 0; - ; + mk.grow = grow_enabled; return mk; } @@ -263,6 +279,7 @@ private: StringName depth_max_layers; StringName uv1_blend_sharpness; StringName uv2_blend_sharpness; + StringName grow; StringName texture_names[TEXTURE_MAX]; }; @@ -294,6 +311,8 @@ private: float refraction; float line_width; float point_size; + bool grow_enabled; + float grow; int particles_anim_h_frames; int particles_anim_v_frames; bool particles_anim_loop; @@ -317,6 +336,7 @@ private: DepthDrawMode depth_draw_mode; CullMode cull_mode; bool flags[FLAG_MAX]; + SpecularMode specular_mode; DiffuseMode diffuse_mode; BillboardMode billboard_mode; @@ -409,6 +429,9 @@ public: void set_diffuse_mode(DiffuseMode p_mode); DiffuseMode get_diffuse_mode() const; + void set_specular_mode(SpecularMode p_mode); + SpecularMode get_specular_mode() const; + void set_flag(Flags p_flag, bool p_enabled); bool get_flag(Flags p_flag) const; @@ -447,6 +470,12 @@ public: void set_particles_anim_loop(int p_frames); int get_particles_anim_loop() const; + void set_grow_enabled(bool p_enable); + bool is_grow_enabled() const; + + void set_grow(float p_grow); + float get_grow() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); @@ -463,6 +492,7 @@ VARIANT_ENUM_CAST(SpatialMaterial::DepthDrawMode) VARIANT_ENUM_CAST(SpatialMaterial::CullMode) VARIANT_ENUM_CAST(SpatialMaterial::Flags) VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode) +VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode) VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode) ////////////////////// |