Browse Source

GLTFLoader: Implement KHR_materials_clearcoat extension.

Don McCurdy 5 năm trước cách đây
mục cha
commit
a7c8e06c16

+ 84 - 0
examples/js/loaders/GLTFLoader.js

@@ -168,6 +168,10 @@ THREE.GLTFLoader = ( function () {
 							extensions[ extensionName ] = new GLTFLightsExtension( json );
 							break;
 
+						case EXTENSIONS.KHR_MATERIALS_CLEARCOAT:
+							extensions[ extensionName ] = new GLTFMaterialsClearcoatExtension();
+							break;
+
 						case EXTENSIONS.KHR_MATERIALS_UNLIT:
 							extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
 							break;
@@ -264,6 +268,7 @@ THREE.GLTFLoader = ( function () {
 		KHR_BINARY_GLTF: 'KHR_binary_glTF',
 		KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
 		KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
+		KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
 		KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
 		KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
 		KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
@@ -408,6 +413,71 @@ THREE.GLTFLoader = ( function () {
 
 	};
 
+	/**
+	 * Clearcoat Materials Extension
+	 *
+	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
+	 */
+	function GLTFMaterialsClearcoatExtension() {
+
+		this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
+
+	}
+
+	GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function () {
+
+		return THREE.MeshPhysicalMaterial;
+
+	};
+
+	GLTFMaterialsClearcoatExtension.prototype.extendParams = function ( materialParams, materialDef, parser ) {
+
+		var pending = [];
+
+		var extension = materialDef.extensions[ this.name ];
+
+		if ( extension.clearcoatFactor !== undefined ) {
+
+			materialParams.clearcoat = extension.clearcoatFactor;
+
+		}
+
+		if ( extension.clearcoatTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );
+
+		}
+
+		if ( extension.clearcoatRoughnessFactor !== undefined ) {
+
+			materialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;
+
+		}
+
+		if ( extension.clearcoatRoughnessTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );
+
+		}
+
+		if ( extension.clearcoatNormalTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );
+
+			if ( extension.clearcoatNormalTexture.scale !== undefined ) {
+
+				var scale = extension.clearcoatNormalTexture.scale;
+
+				materialParams.clearcoatNormalScale = new THREE.Vector2( scale, scale );
+
+			}
+
+		}
+
+		return Promise.all( pending );
+
+	};
+
 	/* BINARY EXTENSION */
 	var BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
 	var BINARY_EXTENSION_HEADER_LENGTH = 12;
@@ -2013,6 +2083,12 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
+		if ( material.clearcoatNormalScale && ! useVertexTangents ) {
+
+			material.clearcoatNormalScale.y = - material.clearcoatNormalScale.y;
+
+		}
+
 		mesh.material = material;
 
 	};
@@ -2151,6 +2227,14 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
+		if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ] ) {
+
+			var clearcoatExtension = extensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ];
+			materialType = clearcoatExtension.getMaterialType();
+			pending.push( clearcoatExtension.extendParams( materialParams, { extensions: materialExtensions }, parser ) );
+
+		}
+
 		return Promise.all( pending ).then( function () {
 
 			var material;

+ 85 - 0
examples/jsm/loaders/GLTFLoader.js

@@ -38,6 +38,7 @@ import {
 	Matrix4,
 	Mesh,
 	MeshBasicMaterial,
+	MeshPhysicalMaterial,
 	MeshStandardMaterial,
 	MirroredRepeatWrapping,
 	NearestFilter,
@@ -231,6 +232,10 @@ var GLTFLoader = ( function () {
 							extensions[ extensionName ] = new GLTFLightsExtension( json );
 							break;
 
+						case EXTENSIONS.KHR_MATERIALS_CLEARCOAT:
+							extensions[ extensionName ] = new GLTFMaterialsClearcoatExtension();
+							break;
+
 						case EXTENSIONS.KHR_MATERIALS_UNLIT:
 							extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
 							break;
@@ -327,6 +332,7 @@ var GLTFLoader = ( function () {
 		KHR_BINARY_GLTF: 'KHR_binary_glTF',
 		KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
 		KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
+		KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
 		KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
 		KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
 		KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
@@ -471,6 +477,71 @@ var GLTFLoader = ( function () {
 
 	};
 
+	/**
+	 * Clearcoat Materials Extension
+	 *
+	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
+	 */
+	function GLTFMaterialsClearcoatExtension() {
+
+		this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
+
+	}
+
+	GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function () {
+
+		return MeshPhysicalMaterial;
+
+	};
+
+	GLTFMaterialsClearcoatExtension.prototype.extendParams = function ( materialParams, materialDef, parser ) {
+
+		var pending = [];
+
+		var extension = materialDef.extensions[ this.name ];
+
+		if ( extension.clearcoatFactor !== undefined ) {
+
+			materialParams.clearcoat = extension.clearcoatFactor;
+
+		}
+
+		if ( extension.clearcoatTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );
+
+		}
+
+		if ( extension.clearcoatRoughnessFactor !== undefined ) {
+
+			materialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;
+
+		}
+
+		if ( extension.clearcoatRoughnessTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );
+
+		}
+
+		if ( extension.clearcoatNormalTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );
+
+			if ( extension.clearcoatNormalTexture.scale !== undefined ) {
+
+				var scale = extension.clearcoatNormalTexture.scale;
+
+				materialParams.clearcoatNormalScale = new Vector2( scale, scale );
+
+			}
+
+		}
+
+		return Promise.all( pending );
+
+	};
+
 	/* BINARY EXTENSION */
 	var BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
 	var BINARY_EXTENSION_HEADER_LENGTH = 12;
@@ -2076,6 +2147,12 @@ var GLTFLoader = ( function () {
 
 		}
 
+		if ( material.clearcoatNormalScale && ! useVertexTangents ) {
+
+			material.clearcoatNormalScale.y = - material.clearcoatNormalScale.y;
+
+		}
+
 		mesh.material = material;
 
 	};
@@ -2214,6 +2291,14 @@ var GLTFLoader = ( function () {
 
 		}
 
+		if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ] ) {
+
+			var clearcoatExtension = extensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ];
+			materialType = clearcoatExtension.getMaterialType();
+			pending.push( clearcoatExtension.extendParams( materialParams, { extensions: materialExtensions }, parser ) );
+
+		}
+
 		return Promise.all( pending ).then( function () {
 
 			var material;

BIN
examples/models/gltf/ClearCoatTest/ClearCoatTest.glb


+ 7 - 0
examples/models/gltf/ClearCoatTest/README.md

@@ -0,0 +1,7 @@
+# Clearcoat Test
+
+This model tests various settings and textures from the KHR_materials_clearcoat extension. Original version and further details in [glTF-Sample-Models / 2.0 / ClearcoatTest](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/ClearCoatTest).
+
+## License Information
+
+Copyright 2020 Analytical Graphics, Inc. [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/). Model and textures by Ed Mackey.

+ 9 - 0
examples/webgl_loader_gltf_extensions.html

@@ -67,6 +67,15 @@
 					extensions: [ 'glTF', 'glTF-Embedded' ],
 					addEnvMap: true
 				},
+				'Clearcoat Test': {
+					name: 'Clearcoat Test',
+					url: './models/gltf/ClearcoatTest/ClearcoatTest.glb',
+					author: 'Ed Mackey (Analytical Graphics, Inc.)',
+					authorURL: 'https://www.agi.com/',
+					cameraPos: new THREE.Vector3( 0, 0, 20 ),
+					extensions: [ 'glTF' ],
+					addEnvMap: true
+				},
 				Duck: {
 					name: 'Duck',
 					url: './models/gltf/Duck/%s/Duck.gltf',