LDrawConditionalLineNodeMaterial.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { Color } from 'three';
  2. import { attribute, cameraProjectionMatrix, dot, float, Fn, modelViewMatrix, modelViewProjection, NodeMaterial, normalize, positionGeometry, sign, uniform, varyingProperty, vec2, vec4 } from 'three/tsl';
  3. class LDrawConditionalLineMaterial extends NodeMaterial {
  4. static get type() {
  5. return 'LDrawConditionalLineMaterial';
  6. }
  7. constructor( parameters ) {
  8. super();
  9. const vertexNode = /*@__PURE__*/ Fn( () => {
  10. const control0 = attribute( 'control0', 'vec3' );
  11. const control1 = attribute( 'control1', 'vec3' );
  12. const direction = attribute( 'direction', 'vec3' );
  13. const mvp = cameraProjectionMatrix.mul( modelViewMatrix );
  14. // Transform the line segment ends and control points into camera clip space
  15. const c0 = mvp.mul( vec4( control0, 1 ) ).toVar();
  16. const c1 = mvp.mul( vec4( control1, 1 ) ).toVar();
  17. const p0 = mvp.mul( vec4( positionGeometry, 1 ) ).toVar();
  18. const p1 = mvp.mul( vec4( positionGeometry.add( direction ), 1 ) ).toVar();
  19. c0.xy.divAssign( c0.w );
  20. c1.xy.divAssign( c1.w );
  21. p0.xy.divAssign( p0.w );
  22. p1.xy.divAssign( p1.w );
  23. // Get the direction of the segment and an orthogonal vector
  24. const dir = p1.xy.sub( p0.xy ).toVar();
  25. const norm = vec2( dir.y.negate(), dir.x ).toVar();
  26. // Get control point directions from the line
  27. const c0dir = c0.xy.sub( p1.xy ).toVar();
  28. const c1dir = c1.xy.sub( p1.xy ).toVar();
  29. // If the vectors to the controls points are pointed in different directions away
  30. // from the line segment then the line should not be drawn.
  31. const d0 = dot( normalize( norm ), normalize( c0dir ) ).toVar();
  32. const d1 = dot( normalize( norm ), normalize( c1dir ) ).toVar();
  33. const discardFlag = sign( d0 ).notEqual( sign( d1 ) ).select( float( 1 ), float( 0 ) );
  34. varyingProperty( 'float', 'discardFlag' ).assign( discardFlag );
  35. return modelViewProjection();
  36. } )();
  37. const fragmentNode = /*@__PURE__*/ Fn( () => {
  38. const discardFlag = varyingProperty( 'float', 'discardFlag' );
  39. discardFlag.greaterThan( float( 0.5 ) ).discard();
  40. return vec4( this._diffuseUniform, this._opacityUniform );
  41. } )();
  42. this.vertexNode = vertexNode;
  43. this.fragmentNode = fragmentNode;
  44. this._diffuseUniform = uniform( new Color() );
  45. this._opacityUniform = uniform( 1 );
  46. //
  47. Object.defineProperties( this, {
  48. opacity: {
  49. get: function () {
  50. return this._opacityUniform.value;
  51. },
  52. set: function ( value ) {
  53. this._opacityUniform.value = value;
  54. }
  55. },
  56. color: {
  57. get: function () {
  58. return this._diffuseUniform.value;
  59. },
  60. set: function ( value ) {
  61. this._diffuseUniform.value.copy( value );
  62. }
  63. }
  64. } );
  65. this.setValues( parameters );
  66. this.isLDrawConditionalLineMaterial = true;
  67. }
  68. }
  69. export { LDrawConditionalLineMaterial };
粤ICP备19079148号