diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-10-27 11:50:26 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-10-27 11:50:26 -0300 |
commit | 53d8f2b1ec1d86b189800b7fe156c464fdf9e380 (patch) | |
tree | a86ac6591239fd58193701419750bdfac3d89417 /scene | |
parent | cb34b70df13ad9f7942b0c363edc71cfd417bb21 (diff) |
PBR more or less working, still working on bringing gizmos back
Diffstat (limited to 'scene')
-rw-r--r-- | scene/3d/light.cpp | 156 | ||||
-rw-r--r-- | scene/3d/light.h | 41 | ||||
-rw-r--r-- | scene/3d/particles.cpp | 10 | ||||
-rw-r--r-- | scene/main/scene_main_loop.cpp | 52 | ||||
-rw-r--r-- | scene/main/scene_main_loop.h | 12 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 2 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 11 | ||||
-rw-r--r-- | scene/resources/environment.cpp | 27 | ||||
-rw-r--r-- | scene/resources/environment.h | 6 | ||||
-rw-r--r-- | scene/resources/material.cpp | 754 | ||||
-rw-r--r-- | scene/resources/material.h | 291 |
11 files changed, 1303 insertions, 59 deletions
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index d98f100020..88ba7b3731 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -39,24 +39,88 @@ bool Light::_can_gizmo_scale() const { } +void Light::set_param(Param p_param, float p_value) { + + ERR_FAIL_INDEX(p_param,PARAM_MAX); + param[p_param]=p_value; + + VS::get_singleton()->light_set_param(light,VS::LightParam(p_param),p_value); + + if (p_param==PARAM_SPOT_ANGLE || p_param==PARAM_RANGE) { + update_gizmo();; + } + + +} + +float Light::get_param(Param p_param) const{ + + ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0); + return param[p_param]; + +} + +void Light::set_shadow(bool p_enable){ + + shadow=p_enable; + VS::get_singleton()->light_set_shadow(light,p_enable); + +} +bool Light::has_shadow() const{ + + return shadow; +} + +void Light::set_negative(bool p_enable){ + + negative=p_enable; + VS::get_singleton()->light_set_negative(light,p_enable); +} +bool Light::is_negative() const{ + + return negative; +} + +void Light::set_cull_mask(uint32_t p_cull_mask){ + + cull_mask=p_cull_mask; + VS::get_singleton()->light_set_cull_mask(light,p_cull_mask); + +} +uint32_t Light::get_cull_mask() const{ + + return cull_mask; +} + +void Light::set_color(const Color& p_color){ + + color=p_color; + VS::get_singleton()->light_set_color(light,p_color); +} +Color Light::get_color() const{ + + return color; +} + + AABB Light::get_aabb() const { -#if 0 + if (type==VisualServer::LIGHT_DIRECTIONAL) { return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) ); } else if (type==VisualServer::LIGHT_OMNI) { - return AABB( Vector3(-1,-1,-1) * vars[PARAM_RADIUS], Vector3(2, 2, 2 ) * vars[PARAM_RADIUS]); + return AABB( Vector3(-1,-1,-1) * param[PARAM_RANGE], Vector3(2, 2, 2 ) * param[PARAM_RANGE]); } else if (type==VisualServer::LIGHT_SPOT) { - float len=vars[PARAM_RADIUS]; - float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len; + float len=param[PARAM_RANGE]; + float size=Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE]))*len; return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) ); } -#endif + return AABB(); } @@ -118,10 +182,51 @@ void Light::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_editor_only"), &Light::is_editor_only ); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only")); - - - + ObjectTypeDB::bind_method(_MD("set_param","param","value"), &Light::set_param ); + ObjectTypeDB::bind_method(_MD("get_param","param"), &Light::get_param ); + + ObjectTypeDB::bind_method(_MD("set_shadow","enabled"), &Light::set_shadow ); + ObjectTypeDB::bind_method(_MD("has_shadow"), &Light::has_shadow ); + + ObjectTypeDB::bind_method(_MD("set_negative","enabled"), &Light::set_negative ); + ObjectTypeDB::bind_method(_MD("is_negative"), &Light::is_negative ); + + ObjectTypeDB::bind_method(_MD("set_cull_mask","cull_mask"), &Light::set_cull_mask ); + ObjectTypeDB::bind_method(_MD("get_cull_mask"), &Light::get_cull_mask ); + + ObjectTypeDB::bind_method(_MD("set_color","color"), &Light::set_color ); + ObjectTypeDB::bind_method(_MD("get_color"), &Light::get_color ); + + ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color"), _SCS("set_color"), _SCS("get_color")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "light/negative"), _SCS("set_negative"), _SCS("is_negative")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR); + ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask"), _SCS("set_cull_mask"), _SCS("get_cull_mask")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkness"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_DARKNESS); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/normal_bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias_split_scale"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE); + + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only")); + + BIND_CONSTANT( PARAM_ENERGY ); + BIND_CONSTANT( PARAM_SPECULAR ); + BIND_CONSTANT( PARAM_RANGE ); + BIND_CONSTANT( PARAM_ATTENUATION ); + BIND_CONSTANT( PARAM_SPOT_ANGLE ); + BIND_CONSTANT( PARAM_SPOT_ATTENUATION ); + BIND_CONSTANT( PARAM_SHADOW_MAX_DISTANCE ); + BIND_CONSTANT( PARAM_SHADOW_DARKNESS ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_1_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_2_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_3_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_4_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_NORMAL_BIAS ); + BIND_CONSTANT( PARAM_SHADOW_BIAS ); + BIND_CONSTANT( PARAM_SHADOW_BIAS_SPLIT_SCALE ); + BIND_CONSTANT( PARAM_MAX ); } @@ -131,9 +236,29 @@ Light::Light(VisualServer::LightType p_type) { type=p_type; light=VisualServer::get_singleton()->light_create(p_type); - + VS::get_singleton()->instance_set_base(get_instance(),light); editor_only=false; + set_color(Color(1,1,1,1)); + set_shadow(false); + set_negative(false); + set_cull_mask(0xFFFFFFFF); + + set_param(PARAM_ENERGY,1); + set_param(PARAM_SPECULAR,1); + set_param(PARAM_RANGE,5); + set_param(PARAM_ATTENUATION,1); + set_param(PARAM_SPOT_ANGLE,45); + set_param(PARAM_SPOT_ATTENUATION,1); + set_param(PARAM_SHADOW_MAX_DISTANCE,0); + set_param(PARAM_SHADOW_DARKNESS,0); + set_param(PARAM_SHADOW_SPLIT_1_OFFSET,0.1); + set_param(PARAM_SHADOW_SPLIT_2_OFFSET,0.2); + set_param(PARAM_SHADOW_SPLIT_3_OFFSET,0.5); + set_param(PARAM_SHADOW_SPLIT_4_OFFSET,1.0); + set_param(PARAM_SHADOW_NORMAL_BIAS,0.1); + set_param(PARAM_SHADOW_BIAS,0.1); + set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE,0.1); } @@ -147,6 +272,8 @@ Light::Light() { Light::~Light() { + VS::get_singleton()->instance_set_base(get_instance(),RID()); + if (light.is_valid()) VisualServer::get_singleton()->free(light); } @@ -156,6 +283,10 @@ Light::~Light() { void DirectionalLight::_bind_methods() { + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_2"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_3"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_4"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_4_OFFSET); } @@ -169,11 +300,16 @@ DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL ) void OmniLight::_bind_methods() { + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/range"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION); } void SpotLight::_bind_methods() { + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/spot_angle"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/spot_attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION); + } diff --git a/scene/3d/light.h b/scene/3d/light.h index 3c31d90d4c..7da2d8e7ca 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -44,10 +44,32 @@ class Light : public VisualInstance { public: - + enum Param { + PARAM_ENERGY, + PARAM_SPECULAR, + PARAM_RANGE, + PARAM_ATTENUATION, + PARAM_SPOT_ANGLE, + PARAM_SPOT_ATTENUATION, + PARAM_SHADOW_MAX_DISTANCE, + PARAM_SHADOW_DARKNESS, + PARAM_SHADOW_SPLIT_1_OFFSET, + PARAM_SHADOW_SPLIT_2_OFFSET, + PARAM_SHADOW_SPLIT_3_OFFSET, + PARAM_SHADOW_SPLIT_4_OFFSET, + PARAM_SHADOW_NORMAL_BIAS, + PARAM_SHADOW_BIAS, + PARAM_SHADOW_BIAS_SPLIT_SCALE, + PARAM_MAX + }; private: + Color color; + float param[PARAM_MAX]; + bool shadow; + bool negative; + uint32_t cull_mask; VS::LightType type; bool editor_only; void _update_visibility(); @@ -71,6 +93,22 @@ public: void set_editor_only(bool p_editor_only); bool is_editor_only() const; + void set_param(Param p_param, float p_value); + float get_param(Param p_param) const; + + void set_shadow(bool p_enable); + bool has_shadow() const; + + void set_negative(bool p_enable); + bool is_negative() const; + + void set_cull_mask(uint32_t p_cull_mask); + uint32_t get_cull_mask() const; + + void set_color(const Color& p_color); + Color get_color() const; + + virtual AABB get_aabb() const; virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const; @@ -79,6 +117,7 @@ public: }; +VARIANT_ENUM_CAST(Light::Param); class DirectionalLight : public Light { diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 994e329853..1e18ba2c79 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -319,10 +319,10 @@ RES Particles::_get_gizmo_geometry() const { Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - Ref<FixedMaterial> mat( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> mat( memnew( FixedSpatialMaterial )); - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) ); - mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); + mat->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) ); + mat->set_parameter( FixedSpatialMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); mat->set_blend_mode( Material::BLEND_MODE_ADD ); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); // mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); @@ -382,9 +382,9 @@ RES Particles::_get_gizmo_geometry() const { Ref<Mesh> mesh = surface_tool->commit(); - Ref<FixedMaterial> mat_aabb( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> mat_aabb( memnew( FixedSpatialMaterial )); - mat_aabb->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) ); + mat_aabb->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) ); mat_aabb->set_line_width(3); mat_aabb->set_flag( Material::FLAG_UNSHADED, true ); diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index c1552a4167..cfc6753378 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -490,6 +490,8 @@ void SceneTree::input_event( const InputEvent& p_event ) { } + _call_idle_callbacks(); + } void SceneTree::init() { @@ -528,6 +530,7 @@ bool SceneTree::iteration(float p_time) { root_lock--; _flush_delete_queue(); + _call_idle_callbacks(); return _quit; } @@ -590,6 +593,8 @@ bool SceneTree::idle(float p_time){ E=N; } + _call_idle_callbacks(); + return _quit; } @@ -745,12 +750,12 @@ Ref<Material> SceneTree::get_debug_navigation_material() { if (navigation_material.is_valid()) return navigation_material; - Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); /* line_material->set_flag(Material::FLAG_UNSHADED, true); line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/ + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/ navigation_material=line_material; @@ -763,12 +768,12 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material(){ if (navigation_disabled_material.is_valid()) return navigation_disabled_material; - Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); /* line_material->set_flag(Material::FLAG_UNSHADED, true); line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/ + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/ navigation_disabled_material=line_material; @@ -781,12 +786,12 @@ Ref<Material> SceneTree::get_debug_collision_material() { return collision_material; - Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); /*line_material->set_flag(Material::FLAG_UNSHADED, true); line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/ + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/ collision_material=line_material; @@ -800,11 +805,11 @@ Ref<Mesh> SceneTree::get_debug_contact_mesh() { debug_contact_mesh = Ref<Mesh>( memnew( Mesh ) ); - Ref<FixedMaterial> mat = memnew( FixedMaterial ); + Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); /*mat->set_flag(Material::FLAG_UNSHADED,true); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); - mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/ + mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/ Vector3 diamond[6]={ Vector3(-1, 0, 0), @@ -2259,6 +2264,23 @@ void SceneTree::_bind_methods() { SceneTree *SceneTree::singleton=NULL; + +SceneTree::IdleCallback SceneTree::idle_callbacks[SceneTree::MAX_IDLE_CALLBACKS]; +int SceneTree::idle_callback_count=0; + +void SceneTree::_call_idle_callbacks() { + + for(int i=0;i<idle_callback_count;i++) { + idle_callbacks[i](); + } +} + +void SceneTree::add_idle_callback(IdleCallback p_callback) { + ERR_FAIL_COND(idle_callback_count>=MAX_IDLE_CALLBACKS); + idle_callbacks[idle_callback_count++]=p_callback; +} + + SceneTree::SceneTree() { singleton=this; diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 1c0f88862c..4860f4a9bf 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -74,6 +74,8 @@ class SceneTree : public MainLoop { public: + typedef void (*IdleCallback)(); + enum StretchMode { STRETCH_MODE_DISABLED, @@ -303,6 +305,15 @@ friend class Viewport; static void _live_edit_reparent_node_funcs(void* self,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos) { reinterpret_cast<SceneTree*>(self)->_live_edit_reparent_node_func(p_at,p_new_place,p_new_name,p_at_pos); } #endif + + enum { + MAX_IDLE_CALLBACKS=256 + }; + + static IdleCallback idle_callbacks[MAX_IDLE_CALLBACKS]; + static int idle_callback_count; + void _call_idle_callbacks(); + protected: @@ -430,6 +441,7 @@ public: void set_refuse_new_network_connections(bool p_refuse); bool is_refusing_new_network_connections() const; + static void add_idle_callback(IdleCallback p_callback); SceneTree(); ~SceneTree(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index e93a16371d..35f72c5ce7 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2513,7 +2513,7 @@ Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const { Vector2 Viewport::get_camera_rect_size() const { - return last_vp_rect.size; + return size; } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index ad845555a4..e2f5b56796 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -544,14 +544,16 @@ void register_scene_types() { #ifndef _3D_DISABLED ObjectTypeDB::register_type<Mesh>(); ObjectTypeDB::register_virtual_type<Material>(); - ObjectTypeDB::register_type<FixedMaterial>(); + ObjectTypeDB::register_type<FixedSpatialMaterial>(); + SceneTree::add_idle_callback(FixedSpatialMaterial::flush_changes); + FixedSpatialMaterial::init_shaders(); // ObjectTypeDB::register_type<ShaderMaterial>(); ObjectTypeDB::register_type<RoomBounds>(); // ObjectTypeDB::register_type<MaterialShaderGraph>(); ObjectTypeDB::register_type<SpatialShader>(); ObjectTypeDB::add_compatibility_type("Shader","MaterialShader"); - ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedMaterial"); - ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedMaterial"); + ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedSpatialMaterial"); + ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedSpatialMaterial"); ObjectTypeDB::register_type<MultiMesh>(); ObjectTypeDB::register_type<MeshLibrary>(); @@ -655,6 +657,7 @@ void unregister_scene_types() { memdelete( resource_loader_wav ); memdelete( resource_loader_dynamic_font ); + #ifdef TOOLS_ENABLED @@ -669,5 +672,7 @@ void unregister_scene_types() { if (resource_loader_text) { memdelete(resource_loader_text); } + + FixedSpatialMaterial::finish_shaders(); SceneStringNames::free(); } diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 85d16da915..3897c86d5b 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -53,7 +53,7 @@ void Environment::set_skybox(const Ref<CubeMap>& p_skybox){ sb_rid=bg_skybox->get_rid(); print_line("skybox valid: "+itos(sb_rid.is_valid())); - VS::get_singleton()->environment_set_skybox(environment,sb_rid,Globals::get_singleton()->get("rendering/skybox/radiance_cube_resolution"),Globals::get_singleton()->get("rendering/skybox/iradiance_cube_resolution")); + VS::get_singleton()->environment_set_skybox(environment,sb_rid,Globals::get_singleton()->get("rendering/skybox/radiance_cube_resolution")); } void Environment::set_skybox_scale(float p_scale) { @@ -80,17 +80,17 @@ void Environment::set_canvas_max_layer(int p_max_layer){ void Environment::set_ambient_light_color(const Color& p_color){ ambient_color=p_color; - VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy); + VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution); } void Environment::set_ambient_light_energy(float p_energy){ ambient_energy=p_energy; - VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy); + VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution); } -void Environment::set_ambient_light_skybox_energy(float p_energy){ +void Environment::set_ambient_light_skybox_contribution(float p_energy){ - ambient_skybox_energy=p_energy; - VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy); + ambient_skybox_contribution=p_energy; + VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution); } Environment::BGMode Environment::get_background() const{ @@ -127,16 +127,16 @@ float Environment::get_ambient_light_energy() const{ return ambient_energy; } -float Environment::get_ambient_light_skybox_energy() const{ +float Environment::get_ambient_light_skybox_contribution() const{ - return ambient_skybox_energy; + return ambient_skybox_contribution; } void Environment::_validate_property(PropertyInfo& property) const { - if (property.name=="background/skybox" || property.name=="ambient_light/skybox_energy") { + if (property.name=="background/skybox" || property.name=="background/skybox_scale" || property.name=="ambient_light/skybox_contribution") { if (bg_mode!=BG_SKYBOX) { property.usage=PROPERTY_USAGE_NOEDITOR; } @@ -166,7 +166,7 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_canvas_max_layer","layer"),&Environment::set_canvas_max_layer); ObjectTypeDB::bind_method(_MD("set_ambient_light_color","color"),&Environment::set_ambient_light_color); ObjectTypeDB::bind_method(_MD("set_ambient_light_energy","energy"),&Environment::set_ambient_light_energy); - ObjectTypeDB::bind_method(_MD("set_ambient_light_skybox_energy","energy"),&Environment::set_ambient_light_skybox_energy); + ObjectTypeDB::bind_method(_MD("set_ambient_light_skybox_contribution","energy"),&Environment::set_ambient_light_skybox_contribution); ObjectTypeDB::bind_method(_MD("get_background"),&Environment::get_background); @@ -177,7 +177,7 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_canvas_max_layer"),&Environment::get_canvas_max_layer); ObjectTypeDB::bind_method(_MD("get_ambient_light_color"),&Environment::get_ambient_light_color); ObjectTypeDB::bind_method(_MD("get_ambient_light_energy"),&Environment::get_ambient_light_energy); - ObjectTypeDB::bind_method(_MD("get_ambient_light_skybox_energy"),&Environment::get_ambient_light_skybox_energy); + ObjectTypeDB::bind_method(_MD("get_ambient_light_skybox_contribution"),&Environment::get_ambient_light_skybox_contribution); ADD_PROPERTY(PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Clear Color,Custom Color,Skybox,Canvas,Keep"),_SCS("set_background"),_SCS("get_background") ); @@ -188,7 +188,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT,"background/canvas_max_layer",PROPERTY_HINT_RANGE,"-1000,1000,1"),_SCS("set_canvas_max_layer"),_SCS("get_canvas_max_layer") ); ADD_PROPERTY(PropertyInfo(Variant::COLOR,"ambient_light/color"),_SCS("set_ambient_light_color"),_SCS("get_ambient_light_color") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_ambient_light_energy"),_SCS("get_ambient_light_energy") ); - ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/skybox_energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_ambient_light_skybox_energy"),_SCS("get_ambient_light_skybox_energy") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/skybox_contribution",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_ambient_light_skybox_contribution"),_SCS("get_ambient_light_skybox_contribution") ); GLOBAL_DEF("rendering/skybox/irradiance_cube_resolution",256); GLOBAL_DEF("rendering/skybox/radiance_cube_resolution",64); @@ -209,10 +209,11 @@ void Environment::_bind_methods() { Environment::Environment() { bg_mode=BG_CLEAR_COLOR; + bg_skybox_scale=1.0; bg_energy=1.0; bg_canvas_max_layer=0; ambient_energy=1.0; - ambient_skybox_energy=0; + ambient_skybox_contribution=0; environment = VS::get_singleton()->environment_create(); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 0435ffc6cb..6478f6420f 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -66,7 +66,7 @@ private: int bg_canvas_max_layer; Color ambient_color; float ambient_energy; - float ambient_skybox_energy; + float ambient_skybox_contribution; protected: @@ -84,7 +84,7 @@ public: void set_canvas_max_layer(int p_max_layer); void set_ambient_light_color(const Color& p_color); void set_ambient_light_energy(float p_energy); - void set_ambient_light_skybox_energy(float p_energy); + void set_ambient_light_skybox_contribution(float p_energy); BGMode get_background() const; Ref<CubeMap> get_skybox() const; @@ -94,7 +94,7 @@ public: int get_canvas_max_layer() const; Color get_ambient_light_color() const; float get_ambient_light_energy() const; - float get_ambient_light_skybox_energy() const; + float get_ambient_light_skybox_contribution() const; virtual RID get_rid() const; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 3ebe5b7800..e3df1461c7 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -45,14 +45,762 @@ Material::~Material() { } -FixedMaterial::FixedMaterial() { +///////////////////////////////// + +Mutex *FixedSpatialMaterial::material_mutex=NULL; +SelfList<FixedSpatialMaterial>::List FixedSpatialMaterial::dirty_materials; +Map<FixedSpatialMaterial::MaterialKey,FixedSpatialMaterial::ShaderData> FixedSpatialMaterial::shader_map; +FixedSpatialMaterial::ShaderNames* FixedSpatialMaterial::shader_names=NULL; + +void FixedSpatialMaterial::init_shaders() { + +#ifndef NO_THREADS + material_mutex = Mutex::create(); +#endif + + shader_names = memnew( ShaderNames ); + shader_names->albedo="albedo"; + shader_names->specular="specular"; + shader_names->roughness="roughness"; + shader_names->emission="emission"; + shader_names->normal_scale="normal_scale"; + shader_names->sheen="sheen"; + shader_names->sheen_color="sheen_color"; + shader_names->clearcoat="clearcoat"; + shader_names->clearcoat_gloss="clearcoat_gloss"; + shader_names->anisotropy="anisotropy"; + shader_names->height_scale="height_scale"; + shader_names->subsurface_scattering="subsurface_scattering"; + shader_names->refraction="refraction"; + shader_names->refraction_roughness="refraction_roughness"; + + shader_names->texture_names[TEXTURE_ALBEDO]="texture_albedo"; + shader_names->texture_names[TEXTURE_SPECULAR]="texture_specular"; + shader_names->texture_names[TEXTURE_EMISSION]="texture_emission"; + shader_names->texture_names[TEXTURE_NORMAL]="texture_normal"; + shader_names->texture_names[TEXTURE_SHEEN]="texture_sheen"; + shader_names->texture_names[TEXTURE_CLEARCOAT]="texture_clearcoat"; + shader_names->texture_names[TEXTURE_ANISOTROPY]="texture_anisotropy"; + shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION]="texture_ambient_occlusion"; + shader_names->texture_names[TEXTURE_HEIGHT]="texture_height"; + shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING]="texture_subsurface_scattering"; + shader_names->texture_names[TEXTURE_REFRACTION]="texture_refraction"; + shader_names->texture_names[TEXTURE_REFRACTION_ROUGHNESS]="texture_refraction_roughness"; + shader_names->texture_names[TEXTURE_DETAIL_MASK]="texture_detail_mask"; + shader_names->texture_names[TEXTURE_DETAIL_ALBEDO]="texture_detail_albedo"; + shader_names->texture_names[TEXTURE_DETAIL_NORMAL]="texture_detail_normal"; } -FixedMaterial::~FixedMaterial() { +void FixedSpatialMaterial::finish_shaders(){ + +#ifndef NO_THREADS + memdelete( material_mutex ); +#endif + memdelete( shader_names ); } -///////////////////////////////// + + +void FixedSpatialMaterial::_update_shader() { + + dirty_materials.remove( &element ); + + MaterialKey mk = _compute_key(); + if (mk.key==current_key.key) + return; //no update required in the end + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users==0) { + //deallocate shader, as it's no longer in use + VS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + } + + current_key=mk; + + if (shader_map.has(mk)) { + + VS::get_singleton()->material_set_shader(_get_material(),shader_map[mk].shader); + shader_map[mk].users++; + return; + } + + //must create a shader! + + String code="render_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; + } + + switch(depth_draw_mode) { + 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_ALPHA_OPAQUE_PREPASS: code+=",depth_draw_alpha_prepass"; break; + } + + switch(cull_mode) { + case CULL_BACK: code+=",cull_back"; break; + case CULL_FRONT: code+=",cull_front"; break; + case CULL_DISABLED: code+=",cull_disable"; break; + + } + + if (flags[FLAG_UNSHADED]) { + code+=",unshaded"; + } + if (flags[FLAG_ONTOP]) { + code+=",ontop"; + } + + code+=";\n"; + + + code+="uniform vec4 albedo : hint_color;\n"; + code+="uniform sampler2D albedo_texture : hint_albedo;\n"; + code+="uniform vec4 specular : hint_color;\n"; + code+="uniform float roughness : hint_range(0,1);\n"; + code+="uniform sampler2D specular_texture : hint_white;\n"; + code+="\n\n"; + + code+="\n\n"; + code+="void fragment() {\n"; + code+="\tvec4 albedo_tex = texture(albedo_texture,UV);\n"; + + if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) { + code+="\talbedo_tex *= COLOR;\n"; + } + + code+="\tALBEDO = albedo.rgb * albedo_tex.rgb;\n"; + if (features[FEATURE_TRANSPARENT]) { + code+="\tALPHA = albedo.a * albedo_tex.a;\n"; + } + code+="\tvec4 specular_tex = texture(specular_texture,UV);\n"; + code+="\tSPECULAR = specular.rgb * specular_tex.rgb;\n"; + code+="\tROUGHNESS = specular.a * roughness;\n"; + code+="}\n"; + + ShaderData shader_data; + shader_data.shader = VS::get_singleton()->shader_create(VS::SHADER_SPATIAL); + shader_data.users=1; + + VS::get_singleton()->shader_set_code( shader_data.shader, code ); + + shader_map[mk]=shader_data; + + VS::get_singleton()->material_set_shader(_get_material(),shader_data.shader); + +} + +void FixedSpatialMaterial::flush_changes() { + + if (material_mutex) + material_mutex->lock(); + + while (dirty_materials.first()) { + + dirty_materials.first()->self()->_update_shader(); + } + + if (material_mutex) + material_mutex->unlock(); +} + +void FixedSpatialMaterial::_queue_shader_change() { + + if (material_mutex) + material_mutex->lock(); + + if (!element.in_list()) { + dirty_materials.add(&element); + } + + if (material_mutex) + material_mutex->unlock(); + + +} + +bool FixedSpatialMaterial::_is_shader_dirty() const { + + bool dirty=false; + + if (material_mutex) + material_mutex->lock(); + + dirty=element.in_list(); + + if (material_mutex) + material_mutex->unlock(); + + return dirty; +} +void FixedSpatialMaterial::set_albedo(const Color& p_albedo) { + + albedo=p_albedo; + + VS::get_singleton()->material_set_param(_get_material(),shader_names->albedo,p_albedo); +} + +Color FixedSpatialMaterial::get_albedo() const{ + + return albedo; +} + +void FixedSpatialMaterial::set_specular(const Color& p_specular){ + + specular=p_specular; + VS::get_singleton()->material_set_param(_get_material(),shader_names->specular,p_specular); + +} +Color FixedSpatialMaterial::get_specular() const{ + + return specular; +} + +void FixedSpatialMaterial::set_roughness(float p_roughness){ + + roughness=p_roughness; + VS::get_singleton()->material_set_param(_get_material(),shader_names->roughness,p_roughness); + +} +float FixedSpatialMaterial::get_roughness() const{ + + return roughness; +} + +void FixedSpatialMaterial::set_emission(const Color& p_emission){ + + emission=p_emission; + VS::get_singleton()->material_set_param(_get_material(),shader_names->emission,p_emission); + +} +Color FixedSpatialMaterial::get_emission() const{ + + return emission; +} + +void FixedSpatialMaterial::set_normal_scale(float p_normal_scale){ + + normal_scale=p_normal_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->normal_scale,p_normal_scale); + +} +float FixedSpatialMaterial::get_normal_scale() const{ + + return normal_scale; +} + +void FixedSpatialMaterial::set_sheen(float p_sheen){ + + sheen=p_sheen; + VS::get_singleton()->material_set_param(_get_material(),shader_names->sheen,p_sheen); + + +} +float FixedSpatialMaterial::get_sheen() const{ + + return sheen; +} + +void FixedSpatialMaterial::set_sheen_color(const Color& p_sheen_color){ + + sheen_color=p_sheen_color; + VS::get_singleton()->material_set_param(_get_material(),shader_names->sheen_color,p_sheen_color); + +} +Color FixedSpatialMaterial::get_sheen_color() const{ + + return sheen_color; +} + +void FixedSpatialMaterial::set_clearcoat(float p_clearcoat){ + + clearcoat=p_clearcoat; + VS::get_singleton()->material_set_param(_get_material(),shader_names->clearcoat,p_clearcoat); + +} + +float FixedSpatialMaterial::get_clearcoat() const{ + + return clearcoat; +} + +void FixedSpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss){ + + clearcoat_gloss=p_clearcoat_gloss; + VS::get_singleton()->material_set_param(_get_material(),shader_names->clearcoat_gloss,p_clearcoat_gloss); + + +} + +float FixedSpatialMaterial::get_clearcoat_gloss() const{ + + return clearcoat_gloss; +} + +void FixedSpatialMaterial::set_anisotropy(float p_anisotropy){ + + anisotropy=p_anisotropy; + VS::get_singleton()->material_set_param(_get_material(),shader_names->anisotropy,p_anisotropy); + +} +float FixedSpatialMaterial::get_anisotropy() const{ + + return anisotropy; +} + +void FixedSpatialMaterial::set_height_scale(float p_height_scale){ + + height_scale=p_height_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->height_scale,p_height_scale); + + +} + +float FixedSpatialMaterial::get_height_scale() const{ + + return height_scale; +} + +void FixedSpatialMaterial::set_subsurface_scattering(float p_subsurface_scattering){ + + subsurface_scattering=p_subsurface_scattering; + VS::get_singleton()->material_set_param(_get_material(),shader_names->subsurface_scattering,subsurface_scattering); + + +} + +float FixedSpatialMaterial::get_subsurface_scattering() const{ + + return subsurface_scattering; +} + +void FixedSpatialMaterial::set_refraction(float p_refraction){ + + refraction=p_refraction; + VS::get_singleton()->material_set_param(_get_material(),shader_names->refraction,refraction); + +} + +float FixedSpatialMaterial::get_refraction() const { + + return refraction; +} + +void FixedSpatialMaterial::set_refraction_roughness(float p_refraction_roughness) { + + refraction_roughness=p_refraction_roughness; + VS::get_singleton()->material_set_param(_get_material(),shader_names->refraction_roughness,refraction_roughness); + + +} +float FixedSpatialMaterial::get_refraction_roughness() const { + + return refraction_roughness; +} + +void FixedSpatialMaterial::set_detail_uv(DetailUV p_detail_uv) { + + if (detail_uv==p_detail_uv) + return; + + detail_uv=p_detail_uv; + _queue_shader_change(); +} +FixedSpatialMaterial::DetailUV FixedSpatialMaterial::get_detail_uv() const { + + return detail_uv; +} + +void FixedSpatialMaterial::set_blend_mode(BlendMode p_mode) { + + if (blend_mode==p_mode) + return; + + blend_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_blend_mode() const { + + return blend_mode; +} + +void FixedSpatialMaterial::set_detail_blend_mode(BlendMode p_mode) { + + detail_blend_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_detail_blend_mode() const { + + return detail_blend_mode; +} + +void FixedSpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) { + + if (depth_draw_mode==p_mode) + return; + + depth_draw_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::DepthDrawMode FixedSpatialMaterial::get_depth_draw_mode() const { + + return depth_draw_mode; +} + +void FixedSpatialMaterial::set_cull_mode(CullMode p_mode) { + + if (cull_mode==p_mode) + return; + + cull_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::CullMode FixedSpatialMaterial::get_cull_mode() const { + + return cull_mode; +} + +void FixedSpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) { + + if (diffuse_mode==p_mode) + return; + + diffuse_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::DiffuseMode FixedSpatialMaterial::get_diffuse_mode() const { + + return diffuse_mode; +} + +void FixedSpatialMaterial::set_flag(Flags p_flag,bool p_enabled) { + + ERR_FAIL_INDEX(p_flag,FLAG_MAX); + + if (flags[p_flag]==p_enabled) + return; + + flags[p_flag]=p_enabled; + _queue_shader_change(); +} + +bool FixedSpatialMaterial::get_flag(Flags p_flag) const { + + ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false); + return flags[p_flag]; +} + +void FixedSpatialMaterial::set_feature(Feature p_feature,bool p_enabled) { + + ERR_FAIL_INDEX(p_feature,FEATURE_MAX); + if (features[p_feature]==p_enabled) + return; + + features[p_feature]=p_enabled; + _change_notify(); + _queue_shader_change(); + + +} + +bool FixedSpatialMaterial::get_feature(Feature p_feature) const { + + ERR_FAIL_INDEX_V(p_feature,FEATURE_MAX,false); + return features[p_feature]; +} + + + +void FixedSpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) { + + ERR_FAIL_INDEX(p_param,TEXTURE_MAX); + textures[p_param]=p_texture; + VS::get_singleton()->material_set_param(_get_material(),shader_names->texture_names[p_param],p_texture); +} + +Ref<Texture> FixedSpatialMaterial::get_texture(TextureParam p_param) const { + + ERR_FAIL_INDEX_V(p_param,TEXTURE_MAX,Ref<Texture>()); + return textures[p_param]; +} + + +void FixedSpatialMaterial::_validate_feature(const String& text, Feature feature,PropertyInfo& property) const { + if (property.name.begins_with(text) && property.name!=text+"/enabled" && !features[feature]) { + property.usage=0; + } +} + +void FixedSpatialMaterial::_validate_property(PropertyInfo& property) const { + _validate_feature("normal",FEATURE_NORMAL_MAPPING,property); + _validate_feature("sheen",FEATURE_SHEEN,property); + _validate_feature("clearcoat",FEATURE_CLEARCOAT,property); + _validate_feature("anisotropy",FEATURE_ANISOTROPY,property); + _validate_feature("ao",FEATURE_AMBIENT_OCCLUSION,property); + _validate_feature("height",FEATURE_HEIGHT_MAPPING,property); + _validate_feature("subsurf_scatter",FEATURE_SUBSURACE_SCATTERING,property); + _validate_feature("refraction",FEATURE_REFRACTION,property); + _validate_feature("detail",FEATURE_DETAIL,property); + +} + +void FixedSpatialMaterial::_bind_methods() { + + + ObjectTypeDB::bind_method(_MD("set_albedo","albedo"),&FixedSpatialMaterial::set_albedo); + ObjectTypeDB::bind_method(_MD("get_albedo"),&FixedSpatialMaterial::get_albedo); + + ObjectTypeDB::bind_method(_MD("set_specular","specular"),&FixedSpatialMaterial::set_specular); + ObjectTypeDB::bind_method(_MD("get_specular"),&FixedSpatialMaterial::get_specular); + + ObjectTypeDB::bind_method(_MD("set_roughness","roughness"),&FixedSpatialMaterial::set_roughness); + ObjectTypeDB::bind_method(_MD("get_roughness"),&FixedSpatialMaterial::get_roughness); + + ObjectTypeDB::bind_method(_MD("set_emission","emission"),&FixedSpatialMaterial::set_emission); + ObjectTypeDB::bind_method(_MD("get_emission"),&FixedSpatialMaterial::get_emission); + + ObjectTypeDB::bind_method(_MD("set_normal_scale","normal_scale"),&FixedSpatialMaterial::set_normal_scale); + ObjectTypeDB::bind_method(_MD("get_normal_scale"),&FixedSpatialMaterial::get_normal_scale); + + ObjectTypeDB::bind_method(_MD("set_sheen","sheen"),&FixedSpatialMaterial::set_sheen); + ObjectTypeDB::bind_method(_MD("get_sheen"),&FixedSpatialMaterial::get_sheen); + + ObjectTypeDB::bind_method(_MD("set_sheen_color","sheen_color"),&FixedSpatialMaterial::set_sheen_color); + ObjectTypeDB::bind_method(_MD("get_sheen_color"),&FixedSpatialMaterial::get_sheen_color); + + ObjectTypeDB::bind_method(_MD("set_clearcoat","clearcoat"),&FixedSpatialMaterial::set_clearcoat); + ObjectTypeDB::bind_method(_MD("get_clearcoat"),&FixedSpatialMaterial::get_clearcoat); + + ObjectTypeDB::bind_method(_MD("set_clearcoat_gloss","clearcoat_gloss"),&FixedSpatialMaterial::set_clearcoat_gloss); + ObjectTypeDB::bind_method(_MD("get_clearcoat_gloss"),&FixedSpatialMaterial::get_clearcoat_gloss); + + ObjectTypeDB::bind_method(_MD("set_anisotropy","anisotropy"),&FixedSpatialMaterial::set_anisotropy); + ObjectTypeDB::bind_method(_MD("get_anisotropy"),&FixedSpatialMaterial::get_anisotropy); + + ObjectTypeDB::bind_method(_MD("set_height_scale","height_scale"),&FixedSpatialMaterial::set_height_scale); + ObjectTypeDB::bind_method(_MD("get_height_scale"),&FixedSpatialMaterial::get_height_scale); + + ObjectTypeDB::bind_method(_MD("set_subsurface_scattering","subsurface_scattering"),&FixedSpatialMaterial::set_subsurface_scattering); + ObjectTypeDB::bind_method(_MD("get_subsurface_scattering"),&FixedSpatialMaterial::get_subsurface_scattering); + + ObjectTypeDB::bind_method(_MD("set_refraction","refraction"),&FixedSpatialMaterial::set_refraction); + ObjectTypeDB::bind_method(_MD("get_refraction"),&FixedSpatialMaterial::get_refraction); + + ObjectTypeDB::bind_method(_MD("set_refraction_roughness","refraction_roughness"),&FixedSpatialMaterial::set_refraction_roughness); + ObjectTypeDB::bind_method(_MD("get_refraction_roughness"),&FixedSpatialMaterial::get_refraction_roughness); + + ObjectTypeDB::bind_method(_MD("set_detail_uv","detail_uv"),&FixedSpatialMaterial::set_detail_uv); + ObjectTypeDB::bind_method(_MD("get_detail_uv"),&FixedSpatialMaterial::get_detail_uv); + + ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&FixedSpatialMaterial::set_blend_mode); + ObjectTypeDB::bind_method(_MD("get_blend_mode"),&FixedSpatialMaterial::get_blend_mode); + + ObjectTypeDB::bind_method(_MD("set_depth_draw_mode","depth_draw_mode"),&FixedSpatialMaterial::set_depth_draw_mode); + ObjectTypeDB::bind_method(_MD("get_depth_draw_mode"),&FixedSpatialMaterial::get_depth_draw_mode); + + ObjectTypeDB::bind_method(_MD("set_cull_mode","cull_mode"),&FixedSpatialMaterial::set_cull_mode); + ObjectTypeDB::bind_method(_MD("get_cull_mode"),&FixedSpatialMaterial::get_cull_mode); + + ObjectTypeDB::bind_method(_MD("set_diffuse_mode","diffuse_mode"),&FixedSpatialMaterial::set_diffuse_mode); + ObjectTypeDB::bind_method(_MD("get_diffuse_mode"),&FixedSpatialMaterial::get_diffuse_mode); + + ObjectTypeDB::bind_method(_MD("set_flag","flag","enable"),&FixedSpatialMaterial::set_flag); + ObjectTypeDB::bind_method(_MD("get_flag"),&FixedSpatialMaterial::get_flag); + + ObjectTypeDB::bind_method(_MD("set_feature","feature","enable"),&FixedSpatialMaterial::set_feature); + ObjectTypeDB::bind_method(_MD("get_feature","feature"),&FixedSpatialMaterial::get_feature); + + ObjectTypeDB::bind_method(_MD("set_texture","param:Texture","texture"),&FixedSpatialMaterial::set_texture); + ObjectTypeDB::bind_method(_MD("get_texture:Texture","param:Texture"),&FixedSpatialMaterial::get_texture); + + ObjectTypeDB::bind_method(_MD("set_detail_blend_mode","detail_blend_mode"),&FixedSpatialMaterial::set_detail_blend_mode); + ObjectTypeDB::bind_method(_MD("get_detail_blend_mode"),&FixedSpatialMaterial::get_detail_blend_mode); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/transparent"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_TRANSPARENT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/unshaded"),_SCS("set_flag"),_SCS("get_flag"),FLAG_UNSHADED); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/on_top"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ONTOP); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/vcol_albedo"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ALBEDO_FROM_VERTEX_COLOR); + + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/diffuse_mode",PROPERTY_HINT_ENUM,"Labert,Lambert Wrap,Oren Nayar,Burley"),_SCS("set_diffuse_mode"),_SCS("get_diffuse_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul"),_SCS("set_blend_mode"),_SCS("get_blend_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/cull_mode",PROPERTY_HINT_ENUM,"Back,Front,Disabled"),_SCS("set_cull_mode"),_SCS("get_cull_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/depth_draw_mode",PROPERTY_HINT_ENUM,"Opaque Only,Always,Never,Opaque Pre-Pass"),_SCS("set_depth_draw_mode"),_SCS("get_depth_draw_mode")); + + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"albedo/color"),_SCS("set_albedo"),_SCS("get_albedo")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"albedo/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ALBEDO); + + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"specular/color"),_SCS("set_specular"),_SCS("get_specular")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"specular/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_roughness"),_SCS("get_roughness")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"specular/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SPECULAR); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"normal/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_NORMAL_MAPPING); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"normal/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_normal_scale"),_SCS("get_normal_scale")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"normal/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_NORMAL); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"sheen/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SHEEN); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"sheen/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_sheen"),_SCS("get_sheen")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"sheen/color"),_SCS("set_sheen_color"),_SCS("get_sheen_color")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"sheen/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SHEEN); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"clearcoat/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_CLEARCOAT); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_clearcoat"),_SCS("get_clearcoat")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/gloss"),_SCS("set_clearcoat_gloss"),_SCS("get_clearcoat_gloss")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"clearcoat/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_CLEARCOAT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"anisotropy/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_ANISOTROPY); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"anisotropy/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_anisotropy"),_SCS("get_anisotropy")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"anisotropy/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ANISOTROPY); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"ao/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_AMBIENT_OCCLUSION); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"ao/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_AMBIENT_OCCLUSION); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"height/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_HEIGHT_MAPPING); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"height/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_height_scale"),_SCS("get_height_scale")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"height/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_HEIGHT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"subsurf_scatter/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SUBSURACE_SCATTERING); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"subsurf_scatter/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_subsurface_scattering"),_SCS("get_subsurface_scattering")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"subsurf_scatter/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SUBSURFACE_SCATTERING); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"refraction/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_REFRACTION); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"refraction/displacement",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_refraction"),_SCS("get_refraction")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"refraction/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_refraction_roughness"),_SCS("get_refraction_roughness")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"refraction/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_REFRACTION); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"detail/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_DETAIL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/mask",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_MASK); + ADD_PROPERTY(PropertyInfo(Variant::INT,"detail/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul"),_SCS("set_detail_blend_mode"),_SCS("get_detail_blend_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"detail/uv_layer",PROPERTY_HINT_ENUM,"UV1,UV2"),_SCS("set_detail_uv"),_SCS("get_detail_uv")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/albedo",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/normal",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_NORMAL); + + BIND_CONSTANT( TEXTURE_ALBEDO ); + BIND_CONSTANT( TEXTURE_SPECULAR ); + BIND_CONSTANT( TEXTURE_EMISSION ); + BIND_CONSTANT( TEXTURE_NORMAL ); + BIND_CONSTANT( TEXTURE_SHEEN ); + BIND_CONSTANT( TEXTURE_CLEARCOAT ); + BIND_CONSTANT( TEXTURE_ANISOTROPY ); + BIND_CONSTANT( TEXTURE_AMBIENT_OCCLUSION ); + BIND_CONSTANT( TEXTURE_HEIGHT ); + BIND_CONSTANT( TEXTURE_SUBSURFACE_SCATTERING ); + BIND_CONSTANT( TEXTURE_REFRACTION ); + BIND_CONSTANT( TEXTURE_REFRACTION_ROUGHNESS ); + BIND_CONSTANT( TEXTURE_DETAIL_MASK ); + BIND_CONSTANT( TEXTURE_DETAIL_ALBEDO ); + BIND_CONSTANT( TEXTURE_DETAIL_NORMAL ); + BIND_CONSTANT( TEXTURE_MAX ); + + + BIND_CONSTANT( DETAIL_UV_1 ); + BIND_CONSTANT( DETAIL_UV_2 ); + + BIND_CONSTANT( FEATURE_TRANSPARENT ); + BIND_CONSTANT( FEATURE_EMISSION ); + BIND_CONSTANT( FEATURE_NORMAL_MAPPING ); + BIND_CONSTANT( FEATURE_SHEEN ); + BIND_CONSTANT( FEATURE_CLEARCOAT ); + BIND_CONSTANT( FEATURE_ANISOTROPY ); + BIND_CONSTANT( FEATURE_AMBIENT_OCCLUSION ); + BIND_CONSTANT( FEATURE_HEIGHT_MAPPING ); + BIND_CONSTANT( FEATURE_SUBSURACE_SCATTERING ); + BIND_CONSTANT( FEATURE_REFRACTION ); + BIND_CONSTANT( FEATURE_DETAIL ); + BIND_CONSTANT( FEATURE_MAX ); + + BIND_CONSTANT( BLEND_MODE_MIX ); + BIND_CONSTANT( BLEND_MODE_ADD ); + BIND_CONSTANT( BLEND_MODE_SUB ); + BIND_CONSTANT( BLEND_MODE_MUL ); + + BIND_CONSTANT( DEPTH_DRAW_OPAQUE_ONLY ); + BIND_CONSTANT( DEPTH_DRAW_ALWAYS ); + BIND_CONSTANT( DEPTH_DRAW_DISABLED ); + BIND_CONSTANT( DEPTH_DRAW_ALPHA_OPAQUE_PREPASS ); + + + BIND_CONSTANT( CULL_BACK ); + BIND_CONSTANT( CULL_FRONT ); + BIND_CONSTANT( CULL_DISABLED ); + + BIND_CONSTANT( FLAG_UNSHADED ); + BIND_CONSTANT( FLAG_ONTOP ); + BIND_CONSTANT( FLAG_ALBEDO_FROM_VERTEX_COLOR ); + BIND_CONSTANT( FLAG_MAX ); + + BIND_CONSTANT( DIFFUSE_LAMBERT ); + BIND_CONSTANT( DIFFUSE_LAMBERT_WRAP ); + BIND_CONSTANT( DIFFUSE_OREN_NAYAR ); + BIND_CONSTANT( DIFFUSE_BURLEY ); +} + + +FixedSpatialMaterial::FixedSpatialMaterial() : element(this) { + + //initialize to right values + set_albedo(Color(0.7,0.7,0.7,1.0)); + set_specular(Color(0.1,0.1,0.1)); + set_roughness(0.0); + set_emission(Color(0,0,0)); + set_normal_scale(1); + set_sheen(0); + set_sheen_color(Color(1,1,1,1)); + set_clearcoat(0); + set_clearcoat_gloss(0.5); + set_anisotropy(0); + set_height_scale(1); + set_subsurface_scattering(0); + set_refraction(0); + set_refraction_roughness(0); + + detail_uv=DETAIL_UV_1; + blend_mode=BLEND_MODE_MIX; + detail_blend_mode=BLEND_MODE_MIX; + depth_draw_mode=DEPTH_DRAW_OPAQUE_ONLY; + cull_mode=CULL_BACK; + for(int i=0;i<FLAG_MAX;i++) { + flags[i]=0; + } + diffuse_mode=DIFFUSE_LAMBERT; + + for(int i=0;i<FEATURE_MAX;i++) { + features[i]=false; + } + + current_key.key=0; + current_key.invalid_key=1; + _queue_shader_change(); +} + +FixedSpatialMaterial::~FixedSpatialMaterial() { + + if (material_mutex) + material_mutex->lock(); + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users==0) { + //deallocate shader, as it's no longer in use + VS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + + VS::get_singleton()->material_set_shader(_get_material(),RID()); + } + + + if (material_mutex) + material_mutex->unlock(); + +} diff --git a/scene/resources/material.h b/scene/resources/material.h index 1acc031641..0f0bf48025 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -34,7 +34,7 @@ #include "scene/resources/shader.h" #include "resource.h" #include "servers/visual/shader_language.h" - +#include "self_list.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -57,17 +57,298 @@ public: }; -class FixedMaterial : public Material { +class FixedSpatialMaterial : public Material { - OBJ_TYPE(FixedMaterial,Resource); + OBJ_TYPE(FixedSpatialMaterial,Material) public: - FixedMaterial(); - virtual ~FixedMaterial(); + enum TextureParam { + TEXTURE_ALBEDO, + TEXTURE_SPECULAR, + TEXTURE_EMISSION, + TEXTURE_NORMAL, + TEXTURE_SHEEN, + TEXTURE_CLEARCOAT, + TEXTURE_ANISOTROPY, + TEXTURE_AMBIENT_OCCLUSION, + TEXTURE_HEIGHT, + TEXTURE_SUBSURFACE_SCATTERING, + TEXTURE_REFRACTION, + TEXTURE_REFRACTION_ROUGHNESS, + TEXTURE_DETAIL_MASK, + TEXTURE_DETAIL_ALBEDO, + TEXTURE_DETAIL_NORMAL, + TEXTURE_MAX + + + }; + + + enum DetailUV { + DETAIL_UV_1, + DETAIL_UV_2 + }; + + enum Feature { + FEATURE_TRANSPARENT, + FEATURE_EMISSION, + FEATURE_NORMAL_MAPPING, + FEATURE_SHEEN, + FEATURE_CLEARCOAT, + FEATURE_ANISOTROPY, + FEATURE_AMBIENT_OCCLUSION, + FEATURE_HEIGHT_MAPPING, + FEATURE_SUBSURACE_SCATTERING, + FEATURE_REFRACTION, + FEATURE_DETAIL, + FEATURE_MAX + }; + + + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + }; + + enum DepthDrawMode { + DEPTH_DRAW_OPAQUE_ONLY, + DEPTH_DRAW_ALWAYS, + DEPTH_DRAW_DISABLED, + DEPTH_DRAW_ALPHA_OPAQUE_PREPASS + + }; + + enum CullMode { + CULL_BACK, + CULL_FRONT, + CULL_DISABLED + }; + + enum Flags { + FLAG_UNSHADED, + FLAG_ONTOP, + FLAG_ALBEDO_FROM_VERTEX_COLOR, + FLAG_MAX + }; + + enum DiffuseMode { + DIFFUSE_LAMBERT, + DIFFUSE_LAMBERT_WRAP, + DIFFUSE_OREN_NAYAR, + DIFFUSE_BURLEY, + }; + +private: + union MaterialKey { + + struct { + uint32_t feature_mask : 16; + uint32_t detail_uv : 1; + uint32_t blend_mode : 2; + uint32_t depth_draw_mode : 2; + uint32_t cull_mode : 2; + uint32_t flags : 3; + uint32_t detail_blend_mode : 2; + uint32_t diffuse_mode : 2; + uint32_t invalid_key : 1; + }; + + uint32_t key; + + bool operator<(const MaterialKey& p_key) const { + return key < p_key.key; + } + + }; + + struct ShaderData { + RID shader; + int users; + }; + + static Map<MaterialKey,ShaderData> shader_map; + + MaterialKey current_key; + + _FORCE_INLINE_ MaterialKey _compute_key() const { + + MaterialKey mk; + mk.key=0; + for(int i=0;i<FEATURE_MAX;i++) { + if (features[i]) { + mk.feature_mask|=(1<<i); + } + } + mk.detail_uv=detail_uv; + mk.blend_mode=blend_mode; + mk.depth_draw_mode=depth_draw_mode; + mk.cull_mode=cull_mode; + for(int i=0;i<FLAG_MAX;i++) { + if (flags[i]) { + mk.flags|=(1<<i); + } + } + mk.detail_blend_mode=detail_blend_mode; + mk.diffuse_mode=diffuse_mode; + + return mk; + } + + struct ShaderNames { + StringName albedo; + StringName specular; + StringName roughness; + StringName emission; + StringName normal_scale; + StringName sheen; + StringName sheen_color; + StringName clearcoat; + StringName clearcoat_gloss; + StringName anisotropy; + StringName height_scale; + StringName subsurface_scattering; + StringName refraction; + StringName refraction_roughness; + StringName texture_names[TEXTURE_MAX]; + }; + + static Mutex *material_mutex; + static SelfList<FixedSpatialMaterial>::List dirty_materials; + static ShaderNames* shader_names; + + SelfList<FixedSpatialMaterial> element; + + void _update_shader(); + _FORCE_INLINE_ void _queue_shader_change(); + _FORCE_INLINE_ bool _is_shader_dirty() const; + + Color albedo; + Color specular; + float roughness; + Color emission; + float normal_scale; + float sheen; + Color sheen_color; + float clearcoat; + float clearcoat_gloss; + float anisotropy; + float height_scale; + float subsurface_scattering; + float refraction; + float refraction_roughness; + + DetailUV detail_uv; + + BlendMode blend_mode; + BlendMode detail_blend_mode; + DepthDrawMode depth_draw_mode; + CullMode cull_mode; + bool flags[FLAG_MAX]; + DiffuseMode diffuse_mode; + + bool features[FEATURE_MAX]; + + Ref<Texture> textures[TEXTURE_MAX]; + + _FORCE_INLINE_ void _validate_feature(const String& text, Feature feature,PropertyInfo& property) const; + +protected: + + static void _bind_methods(); + void _validate_property(PropertyInfo& property) const; + +public: + + + void set_albedo(const Color& p_albedo); + Color get_albedo() const; + + void set_specular(const Color& p_specular); + Color get_specular() const; + + void set_roughness(float p_roughness); + float get_roughness() const; + + void set_emission(const Color& p_emission); + Color get_emission() const; + + void set_normal_scale(float p_normal_scale); + float get_normal_scale() const; + + void set_sheen(float p_sheen); + float get_sheen() const; + + void set_sheen_color(const Color& p_sheen_color); + Color get_sheen_color() const; + + void set_clearcoat(float p_clearcoat); + float get_clearcoat() const; + + void set_clearcoat_gloss(float p_clearcoat_gloss); + float get_clearcoat_gloss() const; + + void set_anisotropy(float p_anisotropy); + float get_anisotropy() const; + + void set_height_scale(float p_height_scale); + float get_height_scale() const; + + void set_subsurface_scattering(float p_subsurface_scattering); + float get_subsurface_scattering() const; + + void set_refraction(float p_refraction); + float get_refraction() const; + + void set_refraction_roughness(float p_refraction_roughness); + float get_refraction_roughness() const; + + void set_detail_uv(DetailUV p_detail_uv); + DetailUV get_detail_uv() const; + + void set_blend_mode(BlendMode p_mode); + BlendMode get_blend_mode() const; + + void set_detail_blend_mode(BlendMode p_mode); + BlendMode get_detail_blend_mode() const; + + void set_depth_draw_mode(DepthDrawMode p_mode); + DepthDrawMode get_depth_draw_mode() const; + + void set_cull_mode(CullMode p_mode); + CullMode get_cull_mode() const; + + void set_diffuse_mode(DiffuseMode p_mode); + DiffuseMode get_diffuse_mode() const; + + void set_flag(Flags p_flag,bool p_enabled); + bool get_flag(Flags p_flag) const; + + void set_texture(TextureParam p_param,const Ref<Texture>& p_texture); + Ref<Texture> get_texture(TextureParam p_param) const; + + void set_feature(Feature p_feature,bool p_enabled); + bool get_feature(Feature p_feature) const; + + static void init_shaders(); + static void finish_shaders(); + static void flush_changes(); + + FixedSpatialMaterial(); + virtual ~FixedSpatialMaterial(); }; +VARIANT_ENUM_CAST( FixedSpatialMaterial::TextureParam ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::DetailUV ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::Feature ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::BlendMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::DepthDrawMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::CullMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::Flags ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::DiffuseMode ) ////////////////////// |