Browse Source

LDrawLoader: Wrap Conditonal Line Material, remove "canHaveEnvMap" field (#22183)

* Wrap conditonal line shader

* Remove unnecessary 'canHaveEnvMap' field
Garrett Johnson 4 years ago
parent
commit
a05675327f
1 changed files with 136 additions and 97 deletions
  1. 136 97
      examples/jsm/loaders/LDrawLoader.js

+ 136 - 97
examples/jsm/loaders/LDrawLoader.js

@@ -37,85 +37,139 @@ const FILE_LOCATION_TRY_RELATIVE = 4;
 const FILE_LOCATION_TRY_ABSOLUTE = 5;
 const FILE_LOCATION_NOT_FOUND = 6;
 
-const conditionalLineVertShader = /* glsl */`
-	attribute vec3 control0;
-	attribute vec3 control1;
-	attribute vec3 direction;
-	varying float discardFlag;
-
-	#include <common>
-	#include <color_pars_vertex>
-	#include <fog_pars_vertex>
-	#include <logdepthbuf_pars_vertex>
-	#include <clipping_planes_pars_vertex>
-	void main() {
-		#include <color_vertex>
-
-		vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
-		gl_Position = projectionMatrix * mvPosition;
-
-		// Transform the line segment ends and control points into camera clip space
-		vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
-		vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
-		vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-		vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
-
-		c0.xy /= c0.w;
-		c1.xy /= c1.w;
-		p0.xy /= p0.w;
-		p1.xy /= p1.w;
-
-		// Get the direction of the segment and an orthogonal vector
-		vec2 dir = p1.xy - p0.xy;
-		vec2 norm = vec2( -dir.y, dir.x );
-
-		// Get control point directions from the line
-		vec2 c0dir = c0.xy - p1.xy;
-		vec2 c1dir = c1.xy - p1.xy;
-
-		// If the vectors to the controls points are pointed in different directions away
-		// from the line segment then the line should not be drawn.
-		float d0 = dot( normalize( norm ), normalize( c0dir ) );
-		float d1 = dot( normalize( norm ), normalize( c1dir ) );
-		discardFlag = float( sign( d0 ) != sign( d1 ) );
-
-		#include <logdepthbuf_vertex>
-		#include <clipping_planes_vertex>
-		#include <fog_vertex>
-	}
-	`;
-
-const conditionalLineFragShader = /* glsl */`
-	uniform vec3 diffuse;
-	uniform float opacity;
-	varying float discardFlag;
-
-	#include <common>
-	#include <color_pars_fragment>
-	#include <fog_pars_fragment>
-	#include <logdepthbuf_pars_fragment>
-	#include <clipping_planes_pars_fragment>
-	void main() {
-
-		if ( discardFlag > 0.5 ) discard;
-
-		#include <clipping_planes_fragment>
-		vec3 outgoingLight = vec3( 0.0 );
-		vec4 diffuseColor = vec4( diffuse, opacity );
-		#include <logdepthbuf_fragment>
-		#include <color_fragment>
-		outgoingLight = diffuseColor.rgb; // simple shader
-		gl_FragColor = vec4( outgoingLight, diffuseColor.a );
-		#include <tonemapping_fragment>
-		#include <encodings_fragment>
-		#include <fog_fragment>
-		#include <premultiplied_alpha_fragment>
-	}
-	`;
-
 const _tempVec0 = new Vector3();
 const _tempVec1 = new Vector3();
 
+class LDrawConditionalLineMaterial extends ShaderMaterial {
+
+	constructor( parameters ) {
+
+		super( {
+
+			uniforms: UniformsUtils.merge( [
+				UniformsLib.fog,
+				{
+					diffuse: {
+						value: new Color()
+					},
+					opacity: {
+						value: 1.0
+					}
+				}
+			] ),
+
+			vertexShader: /* glsl */`
+				attribute vec3 control0;
+				attribute vec3 control1;
+				attribute vec3 direction;
+				varying float discardFlag;
+
+				#include <common>
+				#include <color_pars_vertex>
+				#include <fog_pars_vertex>
+				#include <logdepthbuf_pars_vertex>
+				#include <clipping_planes_pars_vertex>
+				void main() {
+					#include <color_vertex>
+
+					vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+					gl_Position = projectionMatrix * mvPosition;
+
+					// Transform the line segment ends and control points into camera clip space
+					vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
+					vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
+					vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+					vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
+
+					c0.xy /= c0.w;
+					c1.xy /= c1.w;
+					p0.xy /= p0.w;
+					p1.xy /= p1.w;
+
+					// Get the direction of the segment and an orthogonal vector
+					vec2 dir = p1.xy - p0.xy;
+					vec2 norm = vec2( -dir.y, dir.x );
+
+					// Get control point directions from the line
+					vec2 c0dir = c0.xy - p1.xy;
+					vec2 c1dir = c1.xy - p1.xy;
+
+					// If the vectors to the controls points are pointed in different directions away
+					// from the line segment then the line should not be drawn.
+					float d0 = dot( normalize( norm ), normalize( c0dir ) );
+					float d1 = dot( normalize( norm ), normalize( c1dir ) );
+					discardFlag = float( sign( d0 ) != sign( d1 ) );
+
+					#include <logdepthbuf_vertex>
+					#include <clipping_planes_vertex>
+					#include <fog_vertex>
+				}
+			`,
+
+			fragmentShader: /* glsl */`
+			uniform vec3 diffuse;
+			uniform float opacity;
+			varying float discardFlag;
+
+			#include <common>
+			#include <color_pars_fragment>
+			#include <fog_pars_fragment>
+			#include <logdepthbuf_pars_fragment>
+			#include <clipping_planes_pars_fragment>
+			void main() {
+
+				if ( discardFlag > 0.5 ) discard;
+
+				#include <clipping_planes_fragment>
+				vec3 outgoingLight = vec3( 0.0 );
+				vec4 diffuseColor = vec4( diffuse, opacity );
+				#include <logdepthbuf_fragment>
+				#include <color_fragment>
+				outgoingLight = diffuseColor.rgb; // simple shader
+				gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+				#include <tonemapping_fragment>
+				#include <encodings_fragment>
+				#include <fog_fragment>
+				#include <premultiplied_alpha_fragment>
+			}
+			`,
+
+		} );
+
+		Object.defineProperties( this, {
+
+			opacity: {
+				get: function () {
+
+					return this.uniforms.opacity.value;
+
+				},
+
+				set: function ( value ) {
+
+					this.uniforms.opacity.value = value;
+
+				}
+			},
+
+			color: {
+				get: function () {
+
+					return this.uniforms.diffuse.value;
+
+				}
+			}
+
+		} );
+
+
+		this.setValues( parameters );
+
+	}
+
+
+}
+
 function smoothNormals( triangles, lineSegments ) {
 
 	function hashVertex( v ) {
@@ -789,7 +843,6 @@ class LDrawLoader extends Loader {
 		let luminance = 0;
 
 		let finishType = FINISH_TYPE_DEFAULT;
-		let canHaveEnvMap = true;
 
 		let edgeMaterial = null;
 
@@ -956,7 +1009,6 @@ class LDrawLoader extends Loader {
 
 				// Rubber finish
 				material = new MeshStandardMaterial( { color: colour, roughness: 0.9, metalness: 0 } );
-				canHaveEnvMap = false;
 				break;
 
 			case FINISH_TYPE_MATTE_METALLIC:
@@ -985,8 +1037,6 @@ class LDrawLoader extends Loader {
 		material.polygonOffset = true;
 		material.polygonOffsetFactor = 1;
 
-		material.userData.canHaveEnvMap = canHaveEnvMap;
-
 		if ( luminance !== 0 ) {
 
 			material.emissive.set( material.color ).multiplyScalar( luminance );
@@ -1004,28 +1054,17 @@ class LDrawLoader extends Loader {
 			} );
 			edgeMaterial.userData.code = code;
 			edgeMaterial.name = name + ' - Edge';
-			edgeMaterial.userData.canHaveEnvMap = false;
 
 			// This is the material used for conditional edges
-			edgeMaterial.userData.conditionalEdgeMaterial = new ShaderMaterial( {
-				vertexShader: conditionalLineVertShader,
-				fragmentShader: conditionalLineFragShader,
-				uniforms: UniformsUtils.merge( [
-					UniformsLib.fog,
-					{
-						diffuse: {
-							value: new Color( edgeColour )
-						},
-						opacity: {
-							value: alpha
-						}
-					}
-				] ),
+			edgeMaterial.userData.conditionalEdgeMaterial = new LDrawConditionalLineMaterial( {
+
 				fog: true,
 				transparent: isTransparent,
-				depthWrite: ! isTransparent
+				depthWrite: ! isTransparent,
+				color: edgeColour,
+				opacity: alpha,
+
 			} );
-			edgeMaterial.userData.conditionalEdgeMaterial.userData.canHaveEnvMap = false;
 
 		}