فهرست منبع

Set roughness/metallic to 1 when assigning a texture in BaseMaterial3D

This makes material setup faster and avoids mistakes, especially with
the metallic channel which defaults to 0.

The value is only changed when adding a texture when none was
previously assigned, not when assigning a different texture.
Hugo Locurcio 3 سال پیش
والد
کامیت
bad74311db
2فایلهای تغییر یافته به همراه18 افزوده شده و 0 حذف شده
  1. 3 0
      doc/classes/BaseMaterial3D.xml
  2. 15 0
      scene/resources/material.cpp

+ 3 - 0
doc/classes/BaseMaterial3D.xml

@@ -53,6 +53,7 @@
 			<argument index="1" name="texture" type="Texture2D" />
 			<argument index="1" name="texture" type="Texture2D" />
 			<description>
 			<description>
 				Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots.
 				Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots.
+				[b]Note:[/b] When setting a roughness or metallic texture on a material that has no texture assigned to those slots, [member roughness] or [member metallic] will automatically be set to [code]1.0[/code] to ensure correct appearance.
 			</description>
 			</description>
 		</method>
 		</method>
 	</methods>
 	</methods>
@@ -229,6 +230,7 @@
 		</member>
 		</member>
 		<member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0">
 		<member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0">
 			A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness].
 			A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness].
+			[b]Note:[/b] [member metallic] is automatically set to [code]1.0[/code] when assigning a metallic texture using [method set_texture].
 		</member>
 		</member>
 		<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5">
 		<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5">
 			Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources.
 			Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources.
@@ -301,6 +303,7 @@
 		</member>
 		</member>
 		<member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0">
 		<member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0">
 			Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic].
 			Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic].
+			[b]Note:[/b] [member roughness] is automatically set to [code]1.0[/code] when assigning a roughness texture using [method set_texture].
 		</member>
 		</member>
 		<member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture">
 		<member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture">
 			Texture used to control the roughness per-pixel. Multiplied by [member roughness].
 			Texture used to control the roughness per-pixel. Multiplied by [member roughness].

+ 15 - 0
scene/resources/material.cpp

@@ -1658,13 +1658,28 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const {
 
 
 void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
 void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
 	ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
 	ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
+
+	if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) {
+		// If no roughness texture is currently set, automatically set the recommended value
+		// for roughness when using a roughness map.
+		set_roughness(1.0);
+	}
+
+	if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) {
+		// If no metallic texture is currently set, automatically set the recommended value
+		// for metallic when using a metallic map.
+		set_metallic(1.0);
+	}
+
 	textures[p_param] = p_texture;
 	textures[p_param] = p_texture;
 	RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
 	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);
 	RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+
 	if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) {
 	if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) {
 		RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
 		RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
 				Vector2i(p_texture->get_width(), p_texture->get_height()));
 				Vector2i(p_texture->get_width(), p_texture->get_height()));
 	}
 	}
+
 	notify_property_list_changed();
 	notify_property_list_changed();
 	_queue_shader_change();
 	_queue_shader_change();
 }
 }