Browse Source

rewritten PBR implementation to make it friendlier with Blender

Juan Linietsky 8 years ago
parent
commit
a134f58fb3

+ 5 - 15
core/image.cpp

@@ -59,8 +59,6 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
 	"DXT1 RGB8", //s3tc
 	"DXT3 RGBA8",
 	"DXT5 RGBA8",
-	"LATC Lum8",
-	"LATC LumAlpha8",
 	"RGTC Red8",
 	"RGTC RedGreen8",
 	"BPTC_RGBA",
@@ -131,10 +129,8 @@ int Image::get_format_pixel_size(Format p_format) {
 			return 1; //bc2
 		case FORMAT_DXT5:
 			return 1; //bc3
-		case FORMAT_LATC_L:
 		case FORMAT_RGTC_R:
 			return 1; //bc4
-		case FORMAT_LATC_LA:
 		case FORMAT_RGTC_RG:
 			return 1; //bc5
 		case FORMAT_BPTC_RGBA:
@@ -171,8 +167,6 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
 		case FORMAT_DXT1: //s3tc bc1
 		case FORMAT_DXT3: //bc2
 		case FORMAT_DXT5: //bc3
-		case FORMAT_LATC_L: //bc4
-		case FORMAT_LATC_LA: //bc4
 		case FORMAT_RGTC_R: //bc4
 		case FORMAT_RGTC_RG: { //bc5		case case FORMAT_DXT1:
 
@@ -225,7 +219,7 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
 
 int Image::get_format_pixel_rshift(Format p_format) {
 
-	if (p_format == FORMAT_DXT1 || p_format == FORMAT_LATC_L || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1)
+	if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1)
 		return 1;
 	else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A)
 		return 2;
@@ -239,8 +233,6 @@ int Image::get_format_block_size(Format p_format) {
 		case FORMAT_DXT1: //s3tc bc1
 		case FORMAT_DXT3: //bc2
 		case FORMAT_DXT5: //bc3
-		case FORMAT_LATC_L: //bc4
-		case FORMAT_LATC_LA: //bc4
 		case FORMAT_RGTC_R: //bc4
 		case FORMAT_RGTC_RG: { //bc5		case case FORMAT_DXT1:
 
@@ -1500,14 +1492,14 @@ Error Image::decompress() {
 	return OK;
 }
 
-Error Image::compress(CompressMode p_mode) {
+Error Image::compress(CompressMode p_mode, bool p_for_srgb) {
 
 	switch (p_mode) {
 
 		case COMPRESS_S3TC: {
 
 			ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE);
-			_image_compress_bc_func(this);
+			_image_compress_bc_func(this, p_for_srgb);
 		} break;
 		case COMPRESS_PVRTC2: {
 
@@ -1657,7 +1649,7 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
 Ref<Image> (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL;
 Ref<Image> (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL;
 
-void (*Image::_image_compress_bc_func)(Image *) = NULL;
+void (*Image::_image_compress_bc_func)(Image *, bool) = NULL;
 void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL;
 void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL;
 void (*Image::_image_compress_etc_func)(Image *) = NULL;
@@ -2116,8 +2108,6 @@ void Image::_bind_methods() {
 	BIND_CONSTANT(FORMAT_DXT1); //s3tc bc1
 	BIND_CONSTANT(FORMAT_DXT3); //bc2
 	BIND_CONSTANT(FORMAT_DXT5); //bc3
-	BIND_CONSTANT(FORMAT_LATC_L);
-	BIND_CONSTANT(FORMAT_LATC_LA);
 	BIND_CONSTANT(FORMAT_RGTC_R);
 	BIND_CONSTANT(FORMAT_RGTC_RG);
 	BIND_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h
@@ -2152,7 +2142,7 @@ void Image::_bind_methods() {
 	BIND_CONSTANT(COMPRESS_ETC2);
 }
 
-void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) {
+void Image::set_compress_bc_func(void (*p_compress_func)(Image *, bool)) {
 
 	_image_compress_bc_func = p_compress_func;
 }

+ 3 - 5
core/image.h

@@ -80,8 +80,6 @@ public:
 		FORMAT_DXT1, //s3tc bc1
 		FORMAT_DXT3, //bc2
 		FORMAT_DXT5, //bc3
-		FORMAT_LATC_L,
-		FORMAT_LATC_LA,
 		FORMAT_RGTC_R,
 		FORMAT_RGTC_RG,
 		FORMAT_BPTC_RGBA, //btpc bc7
@@ -116,7 +114,7 @@ public:
 	static Ref<Image> (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
 	static Ref<Image> (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
 
-	static void (*_image_compress_bc_func)(Image *);
+	static void (*_image_compress_bc_func)(Image *, bool p_srgb);
 	static void (*_image_compress_pvrtc2_func)(Image *);
 	static void (*_image_compress_pvrtc4_func)(Image *);
 	static void (*_image_compress_etc_func)(Image *);
@@ -269,7 +267,7 @@ public:
 		COMPRESS_ETC2,
 	};
 
-	Error compress(CompressMode p_mode = COMPRESS_S3TC);
+	Error compress(CompressMode p_mode = COMPRESS_S3TC, bool p_for_srgb = false);
 	Error decompress();
 	bool is_compressed() const;
 
@@ -283,7 +281,7 @@ public:
 	Rect2 get_used_rect() const;
 	Ref<Image> get_rect(const Rect2 &p_area) const;
 
-	static void set_compress_bc_func(void (*p_compress_func)(Image *));
+	static void set_compress_bc_func(void (*p_compress_func)(Image *, bool));
 	static String get_format_name(Format p_format);
 
 	Image(const uint8_t *p_mem_png_jpg, int p_len = -1);

+ 0 - 31
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -282,36 +282,6 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
 				need_decompress = true;
 			}
 
-		} break;
-		case Image::FORMAT_LATC_L: {
-
-			if (config.latc_supported) {
-
-				r_gl_internal_format = _EXT_COMPRESSED_LUMINANCE_LATC1_EXT;
-				r_gl_format = GL_RGBA;
-				r_gl_type = GL_UNSIGNED_BYTE;
-				r_compressed = true;
-				srgb = true;
-
-			} else {
-
-				need_decompress = true;
-			}
-
-		} break;
-		case Image::FORMAT_LATC_LA: {
-
-			if (config.latc_supported) {
-
-				r_gl_internal_format = _EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
-				r_gl_format = GL_RGBA;
-				r_gl_type = GL_UNSIGNED_BYTE;
-				r_compressed = true;
-			} else {
-
-				need_decompress = true;
-			}
-
 		} break;
 		case Image::FORMAT_RGTC_R: {
 
@@ -321,7 +291,6 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
 				r_gl_format = GL_RGBA;
 				r_gl_type = GL_UNSIGNED_BYTE;
 				r_compressed = true;
-				srgb = true;
 
 			} else {
 

+ 1 - 0
drivers/gles3/shader_compiler_gles3.cpp

@@ -723,6 +723,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
 	actions[VS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth";
 	actions[VS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo";
 	actions[VS::SHADER_SPATIAL].renames["ALPHA"] = "alpha";
+	actions[VS::SHADER_SPATIAL].renames["METALLIC"] = "metallic";
 	actions[VS::SHADER_SPATIAL].renames["SPECULAR"] = "specular";
 	actions[VS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness";
 	actions[VS::SHADER_SPATIAL].renames["RIM"] = "rim";

+ 40 - 25
drivers/gles3/shaders/scene.glsl

@@ -596,7 +596,6 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
 	return 1.0;
 }
 
-
 // GGX Specular
 // Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
 float G1V(float dotNV, float k)
@@ -622,7 +621,7 @@ float GTR1(float NdotH, float a)
 
 
 
-void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 specular_color, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
+void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color,  float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
 
 	float dotNL = max(dot(N,L), 0.0 );
 	float dotNV = max(dot(N,V), 0.0 );
@@ -674,7 +673,7 @@ void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 di
 
 		float speci = dotNL * D * F * vis;
 
-		specular += speci * light_color /* specular_color*/ * specular_blob_intensity;
+		specular += speci * light_color * specular_blob_intensity;
 
 #if defined(LIGHT_USE_CLEARCOAT)
 		float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss));
@@ -733,6 +732,8 @@ in highp float dp_clip;
 
 #endif
 
+
+
 #if 0
 //need to save texture depth for this
 
@@ -762,7 +763,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
 }
 #endif
 
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 specular, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) {
 
 	vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
 	float light_length = length( light_rel_vec );
@@ -813,11 +814,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
 		light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
 	}
 
-	light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+	light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
 
 }
 
-void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 specular, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
 
 	vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
 	float light_length = length( light_rel_vec );
@@ -846,11 +847,11 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
 		light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
 	}
 
-	light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+	light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
 
 }
 
-void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 tangent,float roughness,float anisotropy,vec3 ambient,vec3 skybox,vec2 brdf, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) {
+void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 tangent,float roughness,float anisotropy,vec3 ambient,vec3 skybox, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) {
 
 	vec3 ref_vec = normalize(reflect(vertex,normal));
 	vec3 local_pos = (reflections[idx].local_matrix * vec4(vertex,1.0)).xyz;
@@ -906,7 +907,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
 		splane.xy = clamp(splane.xy,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw);
 
 		highp vec4 reflection;
-		reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb *  brdf.x + brdf.y;
+		reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb;
 
 		if (reflections[idx].params.z < 0.5) {
 			reflection.rgb = mix(skybox,reflection.rgb,blend);
@@ -1160,7 +1161,8 @@ void main() {
 	//lay out everything, whathever is unused is optimized away anyway
 	highp vec3 vertex = vertex_interp;
 	vec3 albedo = vec3(0.8,0.8,0.8);
-	vec3 specular = vec3(0.2,0.2,0.2);
+	float metallic = 0.0;
+	float specular = 0.5;
 	vec3 emission = vec3(0.0,0.0,0.0);
 	float roughness = 1.0;
 	float rim = 0.0;
@@ -1275,13 +1277,7 @@ FRAGMENT_SHADER_CODE
 
 	vec3 eye_vec = -normalize( vertex_interp );
 
-#ifndef RENDER_DEPTH
-	float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
 
-	vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy;
-	brdf.x=1.0;
-	brdf.y=0.0;
-#endif
 
 #ifdef USE_RADIANCE_MAP
 
@@ -1299,7 +1295,7 @@ FRAGMENT_SHADER_CODE
 				vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
 				ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);				
 				vec3 radiance = textureDualParabolod(radiance_map,ref_vec,lod) * bg_energy;
-				specular_light = radiance * brdf.x + brdf.y;
+				specular_light = radiance;
 
 			}
 			//no longer a cubemap
@@ -1467,7 +1463,7 @@ FRAGMENT_SHADER_CODE
 
 #endif //LIGHT_DIRECTIONAL_SHADOW
 
-	light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,specular,light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+	light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
 
 
 #endif //#USE_LIGHT_DIRECTIONAL
@@ -1485,7 +1481,7 @@ FRAGMENT_SHADER_CODE
 
 
 	for(int i=0;i<reflection_count;i++) {
-		reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,brdf,reflection_accum,ambient_accum);
+		reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,reflection_accum,ambient_accum);
 	}
 
 	if (reflection_accum.a>0.0) {
@@ -1496,11 +1492,11 @@ FRAGMENT_SHADER_CODE
 	}
 
 	for(int i=0;i<omni_light_count;i++) {
-		light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,specular,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+		light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
 	}
 
 	for(int i=0;i<spot_light_count;i++) {
-		light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,specular,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+		light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
 	}
 
 
@@ -1530,10 +1526,29 @@ LIGHT_SHADER_CODE
 	ambient_light*=ao;
 #endif
 
-	//energy conservation
-	diffuse_light=mix(diffuse_light,vec3(0.0),specular);
-	ambient_light=mix(ambient_light,vec3(0.0),specular);
-	specular_light *= max(vec3(0.04),specular);
+
+
+
+
+
+	//energu conservation
+	diffuse_light=mix(diffuse_light,vec3(0.0),metallic);
+	ambient_light=mix(ambient_light,vec3(0.0),metallic);
+	{
+		//brdf approximation (Lazarov 2013)
+		float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
+
+		//energy conservation
+		vec3 dielectric = vec3(0.034) * 0.5 * 2.0;
+		vec3 f0 = mix(dielectric, albedo, metallic);
+		const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
+		const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);
+		vec4 r = roughness * c0 + c1;
+		float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y;
+		vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw;
+
+		specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
+	}
 
 #ifdef USE_MULTIPLE_RENDER_TARGETS
 

+ 6 - 5
editor/import/editor_import_collada.cpp

@@ -402,8 +402,8 @@ Error ColladaImport::_create_material(const String &p_target) {
 
 			Ref<Texture> texture = ResourceLoader::load(texfile, "Texture");
 			if (texture.is_valid()) {
-				material->set_texture(SpatialMaterial::TEXTURE_SPECULAR, texture);
-				material->set_specular(Color(1, 1, 1, 1));
+				material->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
+				material->set_specular(1.0);
 
 				//material->set_texture(SpatialMaterial::PARAM_SPECULAR,texture);
 				//material->set_parameter(SpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1));
@@ -411,8 +411,9 @@ Error ColladaImport::_create_material(const String &p_target) {
 				missing_textures.push_back(texfile.get_file());
 			}
 		}
+
 	} else {
-		material->set_metalness(effect.specular.color.get_v());
+		material->set_metallic(effect.specular.color.get_v());
 	}
 
 	// EMISSION
@@ -553,10 +554,10 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
 			tangent = Vector3();
 		} else {
 			tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
-					(t2 * z1 - t1 * z2) * r)
+							  (t2 * z1 - t1 * z2) * r)
 							  .normalized();
 			binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
-					(s1 * z2 - s2 * z1) * r)
+							   (s1 * z2 - s2 * z1) * r)
 							   .normalized();
 		}
 

+ 1 - 1
editor/import/resource_importer_texture.cpp

@@ -277,7 +277,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String
 			if (p_force_rgbe && image->get_format() >= Image::FORMAT_R8 && image->get_format() <= Image::FORMAT_RGBE9995) {
 				image->convert(Image::FORMAT_RGBE9995);
 			} else {
-				image->compress(p_vram_compression);
+				image->compress(p_vram_compression, p_texture_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR);
 			}
 
 			format |= image->get_format();

+ 0 - 2
modules/dds/texture_loader_dds.cpp

@@ -76,8 +76,6 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
 	{ "DXT1", true, false, 4, 8, Image::FORMAT_DXT1 },
 	{ "DXT3", true, false, 4, 16, Image::FORMAT_DXT3 },
 	{ "DXT5", true, false, 4, 16, Image::FORMAT_DXT5 },
-	{ "ATI1", true, false, 4, 8, Image::FORMAT_LATC_L },
-	{ "ATI2", true, false, 4, 16, Image::FORMAT_LATC_LA },
 	{ "BGRA8", false, false, 1, 4, Image::FORMAT_RGBA8 },
 	{ "BGR8", false, false, 1, 3, Image::FORMAT_RGB8 },
 	{ "RGBA8", false, false, 1, 4, Image::FORMAT_RGBA8 },

+ 12 - 7
modules/squish/image_compress_squish.cpp

@@ -59,9 +59,9 @@ void image_decompress_squish(Image *p_image) {
 		squish_flags = squish::kDxt3;
 	} else if (p_image->get_format() == Image::FORMAT_DXT5) {
 		squish_flags = squish::kDxt5;
-	} else if (p_image->get_format() == Image::FORMAT_LATC_L || p_image->get_format() == Image::FORMAT_RGTC_R) {
+	} else if (p_image->get_format() == Image::FORMAT_RGTC_R) {
 		squish_flags = squish::kBc4;
-	} else if (p_image->get_format() == Image::FORMAT_LATC_LA || p_image->get_format() == Image::FORMAT_RGTC_RG) {
+	} else if (p_image->get_format() == Image::FORMAT_RGTC_RG) {
 		squish_flags = squish::kBc5;
 	} else {
 		ERR_FAIL_COND(true);
@@ -79,7 +79,7 @@ void image_decompress_squish(Image *p_image) {
 	p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
 }
 
-void image_compress_squish(Image *p_image) {
+void image_compress_squish(Image *p_image, bool p_srgb) {
 
 	if (p_image->get_format() >= Image::FORMAT_DXT1)
 		return; //do not compress, already compressed
@@ -96,16 +96,21 @@ void image_compress_squish(Image *p_image) {
 
 		p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
 
+		if (p_srgb && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) {
+			//R and RG do not support SRGB
+			dc = Image::DETECTED_RGB;
+		}
+
 		switch (dc) {
 			case Image::DETECTED_L: {
 
-				target_format = Image::FORMAT_LATC_L;
-				squish_comp |= squish::kBc4;
+				target_format = Image::FORMAT_DXT1;
+				squish_comp |= squish::kDxt1;
 			} break;
 			case Image::DETECTED_LA: {
 
-				target_format = Image::FORMAT_LATC_LA;
-				squish_comp |= squish::kBc5;
+				target_format = Image::FORMAT_DXT5;
+				squish_comp |= squish::kDxt5;
 			} break;
 			case Image::DETECTED_R: {
 

+ 1 - 1
modules/squish/image_compress_squish.h

@@ -32,7 +32,7 @@
 
 #include "image.h"
 
-void image_compress_squish(Image *p_image);
+void image_compress_squish(Image *p_image, bool p_srgb);
 void image_decompress_squish(Image *p_image);
 
 #endif // IMAGE_COMPRESS_SQUISH_H

+ 34 - 63
scene/resources/material.cpp

@@ -181,7 +181,7 @@ void SpatialMaterial::init_shaders() {
 	shader_names->albedo = "albedo";
 	shader_names->specular = "specular";
 	shader_names->roughness = "roughness";
-	shader_names->metalness = "metalness";
+	shader_names->metallic = "metallic";
 	shader_names->emission = "emission";
 	shader_names->emission_energy = "emission_energy";
 	shader_names->normal_scale = "normal_scale";
@@ -205,7 +205,8 @@ void SpatialMaterial::init_shaders() {
 	shader_names->particles_anim_loop = "particles_anim_loop";
 
 	shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
-	shader_names->texture_names[TEXTURE_SPECULAR] = "texture_specular";
+	shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic";
+	shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness";
 	shader_names->texture_names[TEXTURE_EMISSION] = "texture_emission";
 	shader_names->texture_names[TEXTURE_NORMAL] = "texture_normal";
 	shader_names->texture_names[TEXTURE_RIM] = "texture_rim";
@@ -215,7 +216,6 @@ void SpatialMaterial::init_shaders() {
 	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";
@@ -290,15 +290,13 @@ void SpatialMaterial::_update_shader() {
 
 	code += "uniform vec4 albedo : hint_color;\n";
 	code += "uniform sampler2D texture_albedo : hint_albedo;\n";
-	if (specular_mode == SPECULAR_MODE_SPECULAR) {
-		code += "uniform vec4 specular : hint_color;\n";
-	} else {
-		code += "uniform float metalness;\n";
-	}
+	code += "uniform float specular;\n";
+	code += "uniform float metallic;\n";
 
 	code += "uniform float roughness : hint_range(0,1);\n";
 	code += "uniform float point_size : hint_range(0,128);\n";
-	code += "uniform sampler2D texture_specular : hint_white;\n";
+	code += "uniform sampler2D texture_metallic : hint_white;\n";
+	code += "uniform sampler2D texture_roughness : hint_white;\n";
 	code += "uniform vec2 uv1_scale;\n";
 	code += "uniform vec2 uv1_offset;\n";
 	code += "uniform vec2 uv2_scale;\n";
@@ -502,16 +500,11 @@ void SpatialMaterial::_update_shader() {
 		code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
 	}
 
-	if (specular_mode == SPECULAR_MODE_SPECULAR) {
-
-		code += "\tvec4 specular_tex = texture(texture_specular,UV);\n";
-		code += "\tSPECULAR = specular.rgb * specular_tex.rgb;\n";
-		code += "\tROUGHNESS = specular_tex.a * roughness;\n";
-	} else {
-		code += "\tvec4 specular_tex = texture(texture_specular,UV);\n";
-		code += "\tSPECULAR = vec3(ALBEDO.rgb * metalness * specular_tex.r);\n";
-		code += "\tROUGHNESS = specular_tex.g * roughness;\n";
-	}
+	code += "\tfloat metallic_tex = texture(texture_metallic,UV).r;\n";
+	code += "\tMETALLIC = metallic_tex * metallic;\n";
+	code += "\tfloat roughness_tex = texture(texture_roughness,UV).r;\n";
+	code += "\tROUGHNESS = roughness_tex * roughness;\n";
+	code += "\tSPECULAR = specular;\n";
 
 	code += "}\n";
 
@@ -579,23 +572,13 @@ Color SpatialMaterial::get_albedo() const {
 	return albedo;
 }
 
-void SpatialMaterial::set_specular_mode(SpecularMode p_mode) {
-	specular_mode = p_mode;
-	_change_notify();
-	_queue_shader_change();
-}
-
-SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const {
-
-	return specular_mode;
-}
-
-void SpatialMaterial::set_specular(const Color &p_specular) {
+void SpatialMaterial::set_specular(float p_specular) {
 
 	specular = p_specular;
 	VS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
 }
-Color SpatialMaterial::get_specular() const {
+
+float SpatialMaterial::get_specular() const {
 
 	return specular;
 }
@@ -611,15 +594,15 @@ float SpatialMaterial::get_roughness() const {
 	return roughness;
 }
 
-void SpatialMaterial::set_metalness(float p_metalness) {
+void SpatialMaterial::set_metallic(float p_metallic) {
 
-	metalness = p_metalness;
-	VS::get_singleton()->material_set_param(_get_material(), shader_names->metalness, p_metalness);
+	metallic = p_metallic;
+	VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
 }
 
-float SpatialMaterial::get_metalness() const {
+float SpatialMaterial::get_metallic() const {
 
-	return metalness;
+	return metallic;
 }
 
 void SpatialMaterial::set_emission(const Color &p_emission) {
@@ -888,13 +871,6 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
 	_validate_feature("refraction", FEATURE_REFRACTION, property);
 	_validate_feature("detail", FEATURE_DETAIL, property);
 
-	if (property.name == "specular_color" && specular_mode == SPECULAR_MODE_METALLIC) {
-		property.usage = 0;
-	}
-	if (property.name == "specular_metalness" && specular_mode == SPECULAR_MODE_SPECULAR) {
-		property.usage = 0;
-	}
-
 	if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
 		property.usage = 0;
 	}
@@ -1014,14 +990,11 @@ void SpatialMaterial::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
 	ClassDB::bind_method(D_METHOD("get_albedo"), &SpatialMaterial::get_albedo);
 
-	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_specular", "specular"), &SpatialMaterial::set_specular);
 	ClassDB::bind_method(D_METHOD("get_specular"), &SpatialMaterial::get_specular);
 
-	ClassDB::bind_method(D_METHOD("set_metalness", "metalness"), &SpatialMaterial::set_metalness);
-	ClassDB::bind_method(D_METHOD("get_metalness"), &SpatialMaterial::get_metalness);
+	ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &SpatialMaterial::set_metallic);
+	ClassDB::bind_method(D_METHOD("get_metallic"), &SpatialMaterial::get_metallic);
 
 	ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &SpatialMaterial::set_roughness);
 	ClassDB::bind_method(D_METHOD("get_roughness"), &SpatialMaterial::get_roughness);
@@ -1146,12 +1119,14 @@ void SpatialMaterial::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo");
 	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);
 
-	ADD_GROUP("Specular", "specular_");
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "Metallic,Specular"), "set_specular_mode", "get_specular_mode");
-	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular", "get_specular");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "specular_metalness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metalness", "get_metalness");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "specular_roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
-	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "specular_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_SPECULAR);
+	ADD_GROUP("Metallic", "metallic_");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_METALLIC);
+
+	ADD_GROUP("Roughness", "roughness_");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "roughness_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
 
 	ADD_GROUP("Emission", "emission_");
 	ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled"), "set_feature", "get_feature", FEATURE_EMISSION);
@@ -1218,7 +1193,8 @@ void SpatialMaterial::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "uv2_offset"), "set_uv2_offset", "get_uv2_offset");
 
 	BIND_CONSTANT(TEXTURE_ALBEDO);
-	BIND_CONSTANT(TEXTURE_SPECULAR);
+	BIND_CONSTANT(TEXTURE_METALLIC);
+	BIND_CONSTANT(TEXTURE_ROUGHNESS);
 	BIND_CONSTANT(TEXTURE_EMISSION);
 	BIND_CONSTANT(TEXTURE_NORMAL);
 	BIND_CONSTANT(TEXTURE_RIM);
@@ -1228,7 +1204,6 @@ void SpatialMaterial::_bind_methods() {
 	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);
@@ -1277,9 +1252,6 @@ void SpatialMaterial::_bind_methods() {
 	BIND_CONSTANT(DIFFUSE_OREN_NAYAR);
 	BIND_CONSTANT(DIFFUSE_BURLEY);
 
-	BIND_CONSTANT(SPECULAR_MODE_METALLIC);
-	BIND_CONSTANT(SPECULAR_MODE_SPECULAR);
-
 	BIND_CONSTANT(BILLBOARD_DISABLED);
 	BIND_CONSTANT(BILLBOARD_ENABLED);
 	BIND_CONSTANT(BILLBOARD_FIXED_Y);
@@ -1290,11 +1262,10 @@ SpatialMaterial::SpatialMaterial()
 	: element(this) {
 
 	//initialize to right values
-	specular_mode = SPECULAR_MODE_METALLIC;
 	set_albedo(Color(0.7, 0.7, 0.7, 1.0));
-	set_specular(Color(0.1, 0.1, 0.1));
+	set_specular(0.5);
 	set_roughness(0.0);
-	set_metalness(0.1);
+	set_metallic(0.1);
 	set_emission(Color(0, 0, 0));
 	set_emission_energy(1.0);
 	set_normal_scale(1);

+ 9 - 20
scene/resources/material.h

@@ -89,7 +89,8 @@ class SpatialMaterial : public Material {
 public:
 	enum TextureParam {
 		TEXTURE_ALBEDO,
-		TEXTURE_SPECULAR,
+		TEXTURE_METALLIC,
+		TEXTURE_ROUGHNESS,
 		TEXTURE_EMISSION,
 		TEXTURE_NORMAL,
 		TEXTURE_RIM,
@@ -99,7 +100,6 @@ public:
 		TEXTURE_HEIGHT,
 		TEXTURE_SUBSURFACE_SCATTERING,
 		TEXTURE_REFRACTION,
-		TEXTURE_REFRACTION_ROUGHNESS,
 		TEXTURE_DETAIL_MASK,
 		TEXTURE_DETAIL_ALBEDO,
 		TEXTURE_DETAIL_NORMAL,
@@ -165,11 +165,6 @@ public:
 		DIFFUSE_BURLEY,
 	};
 
-	enum SpecularMode {
-		SPECULAR_MODE_METALLIC,
-		SPECULAR_MODE_SPECULAR,
-	};
-
 	enum BillboardMode {
 		BILLBOARD_DISABLED,
 		BILLBOARD_ENABLED,
@@ -230,7 +225,6 @@ private:
 		}
 		mk.detail_blend_mode = detail_blend_mode;
 		mk.diffuse_mode = diffuse_mode;
-		mk.specular_mode = specular_mode;
 		mk.billboard_mode = billboard_mode;
 
 		return mk;
@@ -239,7 +233,7 @@ private:
 	struct ShaderNames {
 		StringName albedo;
 		StringName specular;
-		StringName metalness;
+		StringName metallic;
 		StringName roughness;
 		StringName emission;
 		StringName emission_energy;
@@ -275,8 +269,8 @@ private:
 	_FORCE_INLINE_ bool _is_shader_dirty() const;
 
 	Color albedo;
-	Color specular;
-	float metalness;
+	float specular;
+	float metallic;
 	float roughness;
 	Color emission;
 	float emission_energy;
@@ -310,7 +304,6 @@ private:
 	CullMode cull_mode;
 	bool flags[FLAG_MAX];
 	DiffuseMode diffuse_mode;
-	SpecularMode specular_mode;
 	BillboardMode billboard_mode;
 
 	bool features[FEATURE_MAX];
@@ -327,14 +320,11 @@ public:
 	void set_albedo(const Color &p_albedo);
 	Color get_albedo() const;
 
-	void set_specular_mode(SpecularMode p_mode);
-	SpecularMode get_specular_mode() const;
-
-	void set_specular(const Color &p_specular);
-	Color get_specular() const;
+	void set_specular(float p_specular);
+	float get_specular() const;
 
-	void set_metalness(float p_metalness);
-	float get_metalness() const;
+	void set_metallic(float p_metallic);
+	float get_metallic() const;
 
 	void set_roughness(float p_roughness);
 	float get_roughness() const;
@@ -447,7 +437,6 @@ 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)
 
 //////////////////////

+ 2 - 1
servers/visual/shader_types.cpp

@@ -91,7 +91,8 @@ ShaderTypes::ShaderTypes() {
 	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
 	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALBEDO"] = ShaderLanguage::TYPE_VEC3;
 	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
-	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_VEC3;
+	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["METALLIC"] = ShaderLanguage::TYPE_FLOAT;
+	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT;