Pārlūkot izejas kodu

Merge pull request #7382 from WestLangley/dev-standard

Inital PR for MeshStandardMaterial - Part 2
Mr.doob 9 gadi atpakaļ
vecāks
revīzija
1a9e254af6

+ 191 - 0
src/materials/MeshStandardMaterial.js

@@ -0,0 +1,191 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ * parameters = {
+ *  color: <hex>,
+ *  roughness: <float>,
+ *  reflectivity: <float>,
+ *  metalness: <float>,
+
+ *  emissive: <hex>,
+ *  opacity: <float>,
+ *
+ *  map: new THREE.Texture( <Image> ),
+ *
+ *  lightMap: new THREE.Texture( <Image> ),
+ *  lightMapIntensity: <float>
+ *
+ *  aoMap: new THREE.Texture( <Image> ),
+ *  aoMapIntensity: <float>
+ *
+ *  emissiveMap: new THREE.Texture( <Image> ),
+ *
+ *  bumpMap: new THREE.Texture( <Image> ),
+ *  bumpScale: <float>,
+ *
+ *  normalMap: new THREE.Texture( <Image> ),
+ *  normalScale: <Vector2>,
+ *
+ *  displacementMap: new THREE.Texture( <Image> ),
+ *  displacementScale: <float>,
+ *  displacementBias: <float>,
+ *
+ *  roughnessMap: new THREE.Texture( <Image> ),
+ *
+ *  reflectivityMap: new THREE.Texture( <Image> ),
+ *
+ *  metalnessMap: new THREE.Texture( <Image> ),
+ *
+ *  alphaMap: new THREE.Texture( <Image> ),
+ *
+ *  envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
+ *  refractionRatio: <float>,
+ *
+ *  shading: THREE.SmoothShading,
+ *  blending: THREE.NormalBlending,
+ *  depthTest: <bool>,
+ *  depthWrite: <bool>,
+ *
+ *  wireframe: <boolean>,
+ *  wireframeLinewidth: <float>,
+ *
+ *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
+ *
+ *  skinning: <bool>,
+ *  morphTargets: <bool>,
+ *  morphNormals: <bool>,
+ *
+ *	fog: <bool>
+ * }
+ */
+
+THREE.MeshStandardMaterial = function ( parameters ) {
+
+	THREE.Material.call( this );
+
+	this.type = 'MeshStandardMaterial';
+
+	this.color = new THREE.Color( 0xffffff ); // diffuse
+	this.roughness = 0.5;
+	this.reflectivity = 1;
+	this.metalness = 0;
+
+	this.emissive = new THREE.Color( 0x000000 );
+
+	this.map = null;
+
+	this.lightMap = null;
+	this.lightMapIntensity = 1.0;
+
+	this.aoMap = null;
+	this.aoMapIntensity = 1.0;
+
+	this.emissiveMap = null;
+
+	this.bumpMap = null;
+	this.bumpScale = 1;
+
+	this.normalMap = null;
+	this.normalScale = new THREE.Vector2( 1, 1 );
+
+	this.displacementMap = null;
+	this.displacementScale = 1;
+	this.displacementBias = 0;
+
+	this.roughnessMap = null;
+
+	this.reflectivityMap = null;
+
+	this.metalnessMap = null;
+
+	this.alphaMap = null;
+
+	this.envMap = null;
+	this.envMapIntensity = 1.0;
+
+	this.refractionRatio = 0.98;
+
+	this.fog = true;
+
+	this.shading = THREE.SmoothShading;
+
+	this.wireframe = false;
+	this.wireframeLinewidth = 1;
+	this.wireframeLinecap = 'round';
+	this.wireframeLinejoin = 'round';
+
+	this.vertexColors = THREE.NoColors;
+
+	this.skinning = false;
+	this.morphTargets = false;
+	this.morphNormals = false;
+
+	this.setValues( parameters );
+
+};
+
+THREE.MeshStandardMaterial.prototype = Object.create( THREE.Material.prototype );
+THREE.MeshStandardMaterial.prototype.constructor = THREE.MeshStandardMaterial;
+
+THREE.MeshStandardMaterial.prototype.copy = function ( source ) {
+
+	THREE.Material.prototype.copy.call( this, source );
+
+	this.color.copy( source.color );
+	this.roughness = source.roughness;
+	this.reflectivity = source.reflectivity;
+	this.metalness = source.metalness;
+
+	this.emissive.copy( source.emissive );
+
+	this.map = source.map;
+
+	this.lightMap = source.lightMap;
+	this.lightMapIntensity = source.lightMapIntensity;
+
+	this.aoMap = source.aoMap;
+	this.aoMapIntensity = source.aoMapIntensity;
+
+	this.emissiveMap = source.emissiveMap;
+
+	this.bumpMap = source.bumpMap;
+	this.bumpScale = source.bumpScale;
+
+	this.normalMap = source.normalMap;
+	this.normalScale.copy( source.normalScale );
+
+	this.displacementMap = source.displacementMap;
+	this.displacementScale = source.displacementScale;
+	this.displacementBias = source.displacementBias;
+
+	this.roughnessMap = source.roughnessMap;
+
+	this.reflectivityMap = source.reflectivityMap;
+
+	this.metalnessMap = source.metalnessMap;
+
+	this.alphaMap = source.alphaMap;
+
+	this.envMap = source.envMap;
+	this.envMapIntensity = source.envMapIntensity;
+
+	this.refractionRatio = source.refractionRatio;
+
+	this.fog = source.fog;
+
+	this.shading = source.shading;
+
+	this.wireframe = source.wireframe;
+	this.wireframeLinewidth = source.wireframeLinewidth;
+	this.wireframeLinecap = source.wireframeLinecap;
+	this.wireframeLinejoin = source.wireframeLinejoin;
+
+	this.vertexColors = source.vertexColors;
+
+	this.skinning = source.skinning;
+	this.morphTargets = source.morphTargets;
+	this.morphNormals = source.morphNormals;
+
+	return this;
+
+};

+ 63 - 0
src/renderers/shaders/ShaderChunk/envmap_standard_fragment.glsl

@@ -0,0 +1,63 @@
+#ifdef USE_ENVMAP
+
+	float reflectivityFactor = reflectivity; // fix add map - replace specular strength?
+
+	vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );
+
+	// Transforming Normal Vectors with the Inverse Transformation
+	vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
+
+	#ifdef ENVMAP_MODE_REFLECTION
+
+		vec3 reflectVec = reflect( cameraToVertex, worldNormal );
+
+	#else
+
+		vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );
+
+	#endif
+
+	#ifdef DOUBLE_SIDED
+
+		float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );
+
+	#else
+
+		float flipNormal = 1.0;
+
+	#endif
+
+	#ifdef ENVMAP_TYPE_CUBE
+
+		#if defined( TEXTURE_CUBE_LOD_EXT )
+
+			float bias = pow( roughness, 0.5 ) * 7.0; // from bhouston - there are other models for this calculation (roughness; not roughnesFactor)
+
+			vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias );
+
+		#else
+
+			vec4 envMapColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
+
+		#endif
+
+	#elif defined( ENVMAP_TYPE_EQUIREC )
+
+		vec2 sampleUV;
+		sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );
+		sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
+		vec4 envMapColor = texture2D( envMap, sampleUV );
+
+	#elif defined( ENVMAP_TYPE_SPHERE )
+
+		vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));
+		vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
+
+	#endif
+
+	envMapColor.rgb = inputToLinear( envMapColor.rgb );
+
+    outgoingLight += envBRDFApprox( specularColor, roughnessFactor, normal, viewDir  ) * envMapColor.rgb * envMapIntensity * reflectivityFactor;
+
+#endif
+

+ 112 - 0
src/renderers/shaders/ShaderChunk/lights_standard_fragment.glsl

@@ -0,0 +1,112 @@
+vec3 viewDir = normalize( vViewPosition );
+
+vec3 totalDiffuseLight = vec3( 0.0 );
+vec3 totalSpecularLight = vec3( 0.0 );
+
+
+// roughness linear remapping
+
+roughnessFactor = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ]
+
+
+// metalness effect on color
+
+vec3 specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );
+
+diffuseColor.rgb *= ( 1.0 - metalnessFactor );
+
+
+#if MAX_POINT_LIGHTS > 0
+
+	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
+
+		vec3 lightColor = pointLightColor[ i ];
+
+		vec3 lightPosition = pointLightPosition[ i ];
+		vec3 lVector = lightPosition + vViewPosition.xyz;
+		vec3 lightDir = normalize( lVector );
+
+		// attenuation
+
+		float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );
+
+		// diffuse
+
+		float cosineTerm = saturate( dot( normal, lightDir ) );
+
+		totalDiffuseLight += lightColor * attenuation * cosineTerm;
+
+		// specular
+
+    	vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
+
+		totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
+
+
+	}
+
+#endif
+
+#if MAX_SPOT_LIGHTS > 0
+
+	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
+
+		vec3 lightColor = spotLightColor[ i ];
+
+		vec3 lightPosition = spotLightPosition[ i ];
+		vec3 lVector = lightPosition + vViewPosition.xyz;
+		vec3 lightDir = normalize( lVector );
+
+		float spotEffect = dot( spotLightDirection[ i ], lightDir );
+
+		if ( spotEffect > spotLightAngleCos[ i ] ) {
+
+			spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );
+
+			// attenuation
+
+			float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );
+
+			attenuation *= spotEffect;
+
+			// diffuse
+
+			float cosineTerm = saturate( dot( normal, lightDir ) );
+
+			totalDiffuseLight += lightColor * attenuation * cosineTerm;
+
+			// specular
+
+    		vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
+
+			totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
+
+		}
+
+	}
+
+#endif
+
+#if MAX_DIR_LIGHTS > 0
+
+	for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
+
+		vec3 lightColor = directionalLightColor[ i ];
+
+		vec3 lightDir = directionalLightDirection[ i ];
+
+		// diffuse
+
+		float cosineTerm = saturate( dot( normal, lightDir ) );
+
+		totalDiffuseLight += lightColor * cosineTerm;
+
+		// specular
+
+    	vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
+
+		totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm;
+
+	}
+
+#endif

+ 8 - 0
src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl

@@ -0,0 +1,8 @@
+float metalnessFactor = metalness;
+
+#ifdef USE_METALNESSMAP
+
+	vec4 texelMetalness = texture2D( metalnessMap, vUv );
+	metalnessFactor = texelMetalness.r; // note equality, not *=
+
+#endif

+ 5 - 0
src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl

@@ -0,0 +1,5 @@
+#ifdef USE_METALNESSMAP
+
+	uniform sampler2D metalnessMap;
+
+#endif

+ 8 - 0
src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl

@@ -0,0 +1,8 @@
+float roughnessFactor = roughness;
+
+#ifdef USE_ROUGHNESSMAP
+
+	vec4 texelRoughness = texture2D( roughnessMap, vUv );
+	roughnessFactor *= texelRoughness.r;
+
+#endif

+ 5 - 0
src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl

@@ -0,0 +1,5 @@
+#ifdef USE_ROUGHNESSMAP
+
+	uniform sampler2D roughnessMap;
+
+#endif