LDrawConditionalLineMaterial.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import {
  2. Color,
  3. ShaderMaterial,
  4. UniformsLib,
  5. UniformsUtils,
  6. } from 'three';
  7. /**
  8. * A special line material for meshes loaded via {@link LDrawLoader}.
  9. *
  10. * This module can only be used with {@link WebGLRenderer}. When using {@link WebGPURenderer},
  11. * import the class from `LDrawConditionalLineNodeMaterial.js`.
  12. *
  13. * @augments ShaderMaterial
  14. * @three_import import { LDrawConditionalLineMaterial } from 'three/addons/materials/LDrawConditionalLineMaterial.js';
  15. */
  16. class LDrawConditionalLineMaterial extends ShaderMaterial {
  17. static get type() {
  18. return 'LDrawConditionalLineMaterial';
  19. }
  20. /**
  21. * Constructs a new conditional line material.
  22. *
  23. * @param {Object} [parameters] - An object with one or more properties
  24. * defining the material's appearance. Any property of the material
  25. * (including any property from inherited materials) can be passed
  26. * in here. Color values can be passed any type of value accepted
  27. * by {@link Color#set}.
  28. */
  29. constructor( parameters ) {
  30. super( {
  31. uniforms: UniformsUtils.merge( [
  32. UniformsLib.fog,
  33. {
  34. diffuse: {
  35. value: new Color()
  36. },
  37. opacity: {
  38. value: 1.0
  39. }
  40. }
  41. ] ),
  42. vertexShader: /* glsl */`
  43. attribute vec3 control0;
  44. attribute vec3 control1;
  45. attribute vec3 direction;
  46. varying float discardFlag;
  47. #include <common>
  48. #include <color_pars_vertex>
  49. #include <fog_pars_vertex>
  50. #include <logdepthbuf_pars_vertex>
  51. #include <clipping_planes_pars_vertex>
  52. void main() {
  53. #include <color_vertex>
  54. vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
  55. gl_Position = projectionMatrix * mvPosition;
  56. // Transform the line segment ends and control points into camera clip space
  57. vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
  58. vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
  59. vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  60. vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
  61. c0.xy /= c0.w;
  62. c1.xy /= c1.w;
  63. p0.xy /= p0.w;
  64. p1.xy /= p1.w;
  65. // Get the direction of the segment and an orthogonal vector
  66. vec2 dir = p1.xy - p0.xy;
  67. vec2 norm = vec2( -dir.y, dir.x );
  68. // Get control point directions from the line
  69. vec2 c0dir = c0.xy - p1.xy;
  70. vec2 c1dir = c1.xy - p1.xy;
  71. // If the vectors to the controls points are pointed in different directions away
  72. // from the line segment then the line should not be drawn.
  73. float d0 = dot( normalize( norm ), normalize( c0dir ) );
  74. float d1 = dot( normalize( norm ), normalize( c1dir ) );
  75. discardFlag = float( sign( d0 ) != sign( d1 ) );
  76. #include <logdepthbuf_vertex>
  77. #include <clipping_planes_vertex>
  78. #include <fog_vertex>
  79. }
  80. `,
  81. fragmentShader: /* glsl */`
  82. uniform vec3 diffuse;
  83. uniform float opacity;
  84. varying float discardFlag;
  85. #include <common>
  86. #include <color_pars_fragment>
  87. #include <fog_pars_fragment>
  88. #include <logdepthbuf_pars_fragment>
  89. #include <clipping_planes_pars_fragment>
  90. void main() {
  91. if ( discardFlag > 0.5 ) discard;
  92. #include <clipping_planes_fragment>
  93. vec3 outgoingLight = vec3( 0.0 );
  94. vec4 diffuseColor = vec4( diffuse, opacity );
  95. #include <logdepthbuf_fragment>
  96. #include <color_fragment>
  97. outgoingLight = diffuseColor.rgb; // simple shader
  98. gl_FragColor = vec4( outgoingLight, diffuseColor.a );
  99. #include <tonemapping_fragment>
  100. #include <colorspace_fragment>
  101. #include <fog_fragment>
  102. #include <premultiplied_alpha_fragment>
  103. }
  104. `,
  105. } );
  106. Object.defineProperties( this, {
  107. /**
  108. * The material's opacity.
  109. *
  110. * @name LDrawConditionalLineMaterial#opacity
  111. * @type {number}
  112. * @default 1
  113. */
  114. opacity: {
  115. get: function () {
  116. return this.uniforms.opacity.value;
  117. },
  118. set: function ( value ) {
  119. this.uniforms.opacity.value = value;
  120. }
  121. },
  122. /**
  123. * The material's color.
  124. *
  125. * @name LDrawConditionalLineMaterial#color
  126. * @type {Color}
  127. * @default (1,1,1)
  128. */
  129. color: {
  130. get: function () {
  131. return this.uniforms.diffuse.value;
  132. }
  133. }
  134. } );
  135. this.setValues( parameters );
  136. /**
  137. * This flag can be used for type testing.
  138. *
  139. * @type {boolean}
  140. * @readonly
  141. * @default true
  142. */
  143. this.isLDrawConditionalLineMaterial = true;
  144. }
  145. }
  146. export { LDrawConditionalLineMaterial };