MathNode.js 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. import TempNode from '../core/TempNode.js';
  2. import { sub, mul, div } from './OperatorNode.js';
  3. import { addMethodChaining, nodeObject, nodeProxy, float, vec2, vec3, vec4, Fn } from '../tsl/TSLCore.js';
  4. import { WebGLCoordinateSystem, WebGPUCoordinateSystem } from '../../constants.js';
  5. /** @module MathNode **/
  6. /**
  7. * This node represents a variety of mathematical methods available in shaders.
  8. * They are divided into three categories:
  9. *
  10. * - Methods with one input like `sin`, `cos` or `normalize`.
  11. * - Methods with two inputs like `dot`, `cross` or `pow`.
  12. * - Methods with three inputs like `mix`, `clamp` or `smoothstep`.
  13. *
  14. * @augments TempNode
  15. */
  16. class MathNode extends TempNode {
  17. static get type() {
  18. return 'MathNode';
  19. }
  20. /**
  21. * Constructs a new math node.
  22. *
  23. * @param {String} method - The method name.
  24. * @param {Node} aNode - The first input.
  25. * @param {Node?} [bNode=null] - The second input.
  26. * @param {Node?} [cNode=null] - The third input.
  27. */
  28. constructor( method, aNode, bNode = null, cNode = null ) {
  29. super();
  30. /**
  31. * The method name.
  32. *
  33. * @type {String}
  34. */
  35. this.method = method;
  36. /**
  37. * The first input.
  38. *
  39. * @type {Node}
  40. */
  41. this.aNode = aNode;
  42. /**
  43. * The second input.
  44. *
  45. * @type {Node?}
  46. * @default null
  47. */
  48. this.bNode = bNode;
  49. /**
  50. * The third input.
  51. *
  52. * @type {Node?}
  53. * @default null
  54. */
  55. this.cNode = cNode;
  56. /**
  57. * This flag can be used for type testing.
  58. *
  59. * @type {Boolean}
  60. * @readonly
  61. * @default true
  62. */
  63. this.isMathNode = true;
  64. }
  65. /**
  66. * The input type is inferred from the node types of the input nodes.
  67. *
  68. * @param {NodeBuilder} builder - The current node builder.
  69. * @return {String} The input type.
  70. */
  71. getInputType( builder ) {
  72. const aType = this.aNode.getNodeType( builder );
  73. const bType = this.bNode ? this.bNode.getNodeType( builder ) : null;
  74. const cType = this.cNode ? this.cNode.getNodeType( builder ) : null;
  75. const aLen = builder.isMatrix( aType ) ? 0 : builder.getTypeLength( aType );
  76. const bLen = builder.isMatrix( bType ) ? 0 : builder.getTypeLength( bType );
  77. const cLen = builder.isMatrix( cType ) ? 0 : builder.getTypeLength( cType );
  78. if ( aLen > bLen && aLen > cLen ) {
  79. return aType;
  80. } else if ( bLen > cLen ) {
  81. return bType;
  82. } else if ( cLen > aLen ) {
  83. return cType;
  84. }
  85. return aType;
  86. }
  87. /**
  88. * The selected method as well as the input type determine the node type of this node.
  89. *
  90. * @param {NodeBuilder} builder - The current node builder.
  91. * @return {String} The node type.
  92. */
  93. getNodeType( builder ) {
  94. const method = this.method;
  95. if ( method === MathNode.LENGTH || method === MathNode.DISTANCE || method === MathNode.DOT ) {
  96. return 'float';
  97. } else if ( method === MathNode.CROSS ) {
  98. return 'vec3';
  99. } else if ( method === MathNode.ALL ) {
  100. return 'bool';
  101. } else if ( method === MathNode.EQUALS ) {
  102. return builder.changeComponentType( this.aNode.getNodeType( builder ), 'bool' );
  103. } else if ( method === MathNode.MOD ) {
  104. return this.aNode.getNodeType( builder );
  105. } else {
  106. return this.getInputType( builder );
  107. }
  108. }
  109. generate( builder, output ) {
  110. let method = this.method;
  111. const type = this.getNodeType( builder );
  112. const inputType = this.getInputType( builder );
  113. const a = this.aNode;
  114. const b = this.bNode;
  115. const c = this.cNode;
  116. const coordinateSystem = builder.renderer.coordinateSystem;
  117. if ( method === MathNode.TRANSFORM_DIRECTION ) {
  118. // dir can be either a direction vector or a normal vector
  119. // upper-left 3x3 of matrix is assumed to be orthogonal
  120. let tA = a;
  121. let tB = b;
  122. if ( builder.isMatrix( tA.getNodeType( builder ) ) ) {
  123. tB = vec4( vec3( tB ), 0.0 );
  124. } else {
  125. tA = vec4( vec3( tA ), 0.0 );
  126. }
  127. const mulNode = mul( tA, tB ).xyz;
  128. return normalize( mulNode ).build( builder, output );
  129. } else if ( method === MathNode.NEGATE ) {
  130. return builder.format( '( - ' + a.build( builder, inputType ) + ' )', type, output );
  131. } else if ( method === MathNode.ONE_MINUS ) {
  132. return sub( 1.0, a ).build( builder, output );
  133. } else if ( method === MathNode.RECIPROCAL ) {
  134. return div( 1.0, a ).build( builder, output );
  135. } else if ( method === MathNode.DIFFERENCE ) {
  136. return abs( sub( a, b ) ).build( builder, output );
  137. } else {
  138. const params = [];
  139. if ( method === MathNode.CROSS || method === MathNode.MOD ) {
  140. params.push(
  141. a.build( builder, type ),
  142. b.build( builder, type )
  143. );
  144. } else if ( coordinateSystem === WebGLCoordinateSystem && method === MathNode.STEP ) {
  145. params.push(
  146. a.build( builder, builder.getTypeLength( a.getNodeType( builder ) ) === 1 ? 'float' : inputType ),
  147. b.build( builder, inputType )
  148. );
  149. } else if ( ( coordinateSystem === WebGLCoordinateSystem && ( method === MathNode.MIN || method === MathNode.MAX ) ) || method === MathNode.MOD ) {
  150. params.push(
  151. a.build( builder, inputType ),
  152. b.build( builder, builder.getTypeLength( b.getNodeType( builder ) ) === 1 ? 'float' : inputType )
  153. );
  154. } else if ( method === MathNode.REFRACT ) {
  155. params.push(
  156. a.build( builder, inputType ),
  157. b.build( builder, inputType ),
  158. c.build( builder, 'float' )
  159. );
  160. } else if ( method === MathNode.MIX ) {
  161. params.push(
  162. a.build( builder, inputType ),
  163. b.build( builder, inputType ),
  164. c.build( builder, builder.getTypeLength( c.getNodeType( builder ) ) === 1 ? 'float' : inputType )
  165. );
  166. } else {
  167. if ( coordinateSystem === WebGPUCoordinateSystem && method === MathNode.ATAN && b !== null ) {
  168. method = 'atan2';
  169. }
  170. params.push( a.build( builder, inputType ) );
  171. if ( b !== null ) params.push( b.build( builder, inputType ) );
  172. if ( c !== null ) params.push( c.build( builder, inputType ) );
  173. }
  174. return builder.format( `${ builder.getMethod( method, type ) }( ${params.join( ', ' )} )`, type, output );
  175. }
  176. }
  177. serialize( data ) {
  178. super.serialize( data );
  179. data.method = this.method;
  180. }
  181. deserialize( data ) {
  182. super.deserialize( data );
  183. this.method = data.method;
  184. }
  185. }
  186. // 1 input
  187. MathNode.ALL = 'all';
  188. MathNode.ANY = 'any';
  189. MathNode.RADIANS = 'radians';
  190. MathNode.DEGREES = 'degrees';
  191. MathNode.EXP = 'exp';
  192. MathNode.EXP2 = 'exp2';
  193. MathNode.LOG = 'log';
  194. MathNode.LOG2 = 'log2';
  195. MathNode.SQRT = 'sqrt';
  196. MathNode.INVERSE_SQRT = 'inversesqrt';
  197. MathNode.FLOOR = 'floor';
  198. MathNode.CEIL = 'ceil';
  199. MathNode.NORMALIZE = 'normalize';
  200. MathNode.FRACT = 'fract';
  201. MathNode.SIN = 'sin';
  202. MathNode.COS = 'cos';
  203. MathNode.TAN = 'tan';
  204. MathNode.ASIN = 'asin';
  205. MathNode.ACOS = 'acos';
  206. MathNode.ATAN = 'atan';
  207. MathNode.ABS = 'abs';
  208. MathNode.SIGN = 'sign';
  209. MathNode.LENGTH = 'length';
  210. MathNode.NEGATE = 'negate';
  211. MathNode.ONE_MINUS = 'oneMinus';
  212. MathNode.DFDX = 'dFdx';
  213. MathNode.DFDY = 'dFdy';
  214. MathNode.ROUND = 'round';
  215. MathNode.RECIPROCAL = 'reciprocal';
  216. MathNode.TRUNC = 'trunc';
  217. MathNode.FWIDTH = 'fwidth';
  218. MathNode.TRANSPOSE = 'transpose';
  219. // 2 inputs
  220. MathNode.BITCAST = 'bitcast';
  221. MathNode.EQUALS = 'equals';
  222. MathNode.MIN = 'min';
  223. MathNode.MAX = 'max';
  224. MathNode.MOD = 'mod';
  225. MathNode.STEP = 'step';
  226. MathNode.REFLECT = 'reflect';
  227. MathNode.DISTANCE = 'distance';
  228. MathNode.DIFFERENCE = 'difference';
  229. MathNode.DOT = 'dot';
  230. MathNode.CROSS = 'cross';
  231. MathNode.POW = 'pow';
  232. MathNode.TRANSFORM_DIRECTION = 'transformDirection';
  233. // 3 inputs
  234. MathNode.MIX = 'mix';
  235. MathNode.CLAMP = 'clamp';
  236. MathNode.REFRACT = 'refract';
  237. MathNode.SMOOTHSTEP = 'smoothstep';
  238. MathNode.FACEFORWARD = 'faceforward';
  239. export default MathNode;
  240. // 1 inputs
  241. /**
  242. * A small value used to handle floating-point precision errors.
  243. *
  244. * @type {Node<float>}
  245. */
  246. export const EPSILON = /*@__PURE__*/ float( 1e-6 );
  247. /**
  248. * Represents infinity.
  249. *
  250. * @type {Node<float>}
  251. */
  252. export const INFINITY = /*@__PURE__*/ float( 1e6 );
  253. /**
  254. * Represents PI.
  255. *
  256. * @type {Node<float>}
  257. */
  258. export const PI = /*@__PURE__*/ float( Math.PI );
  259. /**
  260. * Represents PI * 2.
  261. *
  262. * @type {Node<float>}
  263. */
  264. export const PI2 = /*@__PURE__*/ float( Math.PI * 2 );
  265. /**
  266. * Returns `true` if all components of `x` are `true`.
  267. *
  268. * @function
  269. * @param {Node | Number} x - The parameter.
  270. * @returns {Node<bool>}
  271. */
  272. export const all = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ALL );
  273. /**
  274. * Returns `true` if any components of `x` are `true`.
  275. *
  276. * @function
  277. * @param {Node | Number} x - The parameter.
  278. * @returns {Node<bool>}
  279. */
  280. export const any = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ANY );
  281. /**
  282. * Converts a quantity in degrees to radians.
  283. *
  284. * @function
  285. * @param {Node | Number} x - The input in degrees.
  286. * @returns {Node}
  287. */
  288. export const radians = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RADIANS );
  289. /**
  290. * Convert a quantity in radians to degrees.
  291. *
  292. * @function
  293. * @param {Node | Number} x - The input in radians.
  294. * @returns {Node}
  295. */
  296. export const degrees = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DEGREES );
  297. /**
  298. * Returns the natural exponentiation of the parameter.
  299. *
  300. * @function
  301. * @param {Node | Number} x - The parameter.
  302. * @returns {Node}
  303. */
  304. export const exp = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP );
  305. /**
  306. * Returns 2 raised to the power of the parameter.
  307. *
  308. * @function
  309. * @param {Node | Number} x - The parameter.
  310. * @returns {Node}
  311. */
  312. export const exp2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP2 );
  313. /**
  314. * Returns the natural logarithm of the parameter.
  315. *
  316. * @function
  317. * @param {Node | Number} x - The parameter.
  318. * @returns {Node}
  319. */
  320. export const log = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG );
  321. /**
  322. * Returns the base 2 logarithm of the parameter.
  323. *
  324. * @function
  325. * @param {Node | Number} x - The parameter.
  326. * @returns {Node}
  327. */
  328. export const log2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG2 );
  329. /**
  330. * Returns the square root of the parameter.
  331. *
  332. * @function
  333. * @param {Node | Number} x - The parameter.
  334. * @returns {Node}
  335. */
  336. export const sqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SQRT );
  337. /**
  338. * Returns the inverse of the square root of the parameter.
  339. *
  340. * @function
  341. * @param {Node | Number} x - The parameter.
  342. * @returns {Node}
  343. */
  344. export const inverseSqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.INVERSE_SQRT );
  345. /**
  346. * Finds the nearest integer less than or equal to the parameter.
  347. *
  348. * @function
  349. * @param {Node | Number} x - The parameter.
  350. * @returns {Node}
  351. */
  352. export const floor = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FLOOR );
  353. /**
  354. * Finds the nearest integer that is greater than or equal to the parameter.
  355. *
  356. * @function
  357. * @param {Node | Number} x - The parameter.
  358. * @returns {Node}
  359. */
  360. export const ceil = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CEIL );
  361. /**
  362. * Calculates the unit vector in the same direction as the original vector.
  363. *
  364. * @function
  365. * @param {Node} x - The input vector.
  366. * @returns {Node}
  367. */
  368. export const normalize = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NORMALIZE );
  369. /**
  370. * Computes the fractional part of the parameter.
  371. *
  372. * @function
  373. * @param {Node | Number} x - The parameter.
  374. * @returns {Node}
  375. */
  376. export const fract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FRACT );
  377. /**
  378. * Returns the sine of the parameter.
  379. *
  380. * @function
  381. * @param {Node | Number} x - The parameter.
  382. * @returns {Node}
  383. */
  384. export const sin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIN );
  385. /**
  386. * Returns the cosine of the parameter.
  387. *
  388. * @function
  389. * @param {Node | Number} x - The parameter.
  390. * @returns {Node}
  391. */
  392. export const cos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.COS );
  393. /**
  394. * Returns the tangent of the parameter.
  395. *
  396. * @function
  397. * @param {Node | Number} x - The parameter.
  398. * @returns {Node}
  399. */
  400. export const tan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TAN );
  401. /**
  402. * Returns the arcsine of the parameter.
  403. *
  404. * @function
  405. * @param {Node | Number} x - The parameter.
  406. * @returns {Node}
  407. */
  408. export const asin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ASIN );
  409. /**
  410. * Returns the arccosine of the parameter.
  411. *
  412. * @function
  413. * @param {Node | Number} x - The parameter.
  414. * @returns {Node}
  415. */
  416. export const acos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ACOS );
  417. /**
  418. * Returns the arc-tangent of the parameter.
  419. * If two parameters are provided, the result is `atan2(y/x)`.
  420. *
  421. * @function
  422. * @param {Node | Number} y - The y parameter.
  423. * @param {(Node | Number)?} x - The x parameter.
  424. * @returns {Node}
  425. */
  426. export const atan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ATAN );
  427. /**
  428. * Returns the absolute value of the parameter.
  429. *
  430. * @function
  431. * @param {Node | Number} x - The parameter.
  432. * @returns {Node}
  433. */
  434. export const abs = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ABS );
  435. /**
  436. * Extracts the sign of the parameter.
  437. *
  438. * @function
  439. * @param {Node | Number} x - The parameter.
  440. * @returns {Node}
  441. */
  442. export const sign = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIGN );
  443. /**
  444. * Calculates the length of a vector.
  445. *
  446. * @function
  447. * @param {Node} x - The parameter.
  448. * @returns {Node<float>}
  449. */
  450. export const length = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LENGTH );
  451. /**
  452. * Negates the value of the parameter (-x).
  453. *
  454. * @function
  455. * @param {Node | Number} x - The parameter.
  456. * @returns {Node}
  457. */
  458. export const negate = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NEGATE );
  459. /**
  460. * Return `1` minus the parameter.
  461. *
  462. * @function
  463. * @param {Node | Number} x - The parameter.
  464. * @returns {Node}
  465. */
  466. export const oneMinus = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ONE_MINUS );
  467. /**
  468. * Returns the partial derivative of the parameter with respect to x.
  469. *
  470. * @function
  471. * @param {Node | Number} x - The parameter.
  472. * @returns {Node}
  473. */
  474. export const dFdx = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDX );
  475. /**
  476. * Returns the partial derivative of the parameter with respect to y.
  477. *
  478. * @function
  479. * @param {Node | Number} x - The parameter.
  480. * @returns {Node}
  481. */
  482. export const dFdy = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDY );
  483. /**
  484. * Rounds the parameter to the nearest integer.
  485. *
  486. * @function
  487. * @param {Node | Number} x - The parameter.
  488. * @returns {Node}
  489. */
  490. export const round = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ROUND );
  491. /**
  492. * Returns the reciprocal of the parameter `(1/x)`.
  493. *
  494. * @function
  495. * @param {Node | Number} x - The parameter.
  496. * @returns {Node}
  497. */
  498. export const reciprocal = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RECIPROCAL );
  499. /**
  500. * Truncates the parameter, removing the fractional part.
  501. *
  502. * @function
  503. * @param {Node | Number} x - The parameter.
  504. * @returns {Node}
  505. */
  506. export const trunc = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRUNC );
  507. /**
  508. * Returns the sum of the absolute derivatives in x and y.
  509. *
  510. * @function
  511. * @param {Node | Number} x - The parameter.
  512. * @returns {Node}
  513. */
  514. export const fwidth = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FWIDTH );
  515. /**
  516. * Returns the transpose of a matrix.
  517. *
  518. * @function
  519. * @param {Node<mat2|mat3|mat4>} x - The parameter.
  520. * @returns {Node}
  521. */
  522. export const transpose = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSPOSE );
  523. // 2 inputs
  524. /**
  525. * Reinterpret the bit representation of a value in one type as a value in another type.
  526. *
  527. * @function
  528. * @param {Node | Number} x - The parameter.
  529. * @param {String} y - The new type.
  530. * @returns {Node}
  531. */
  532. export const bitcast = /*@__PURE__*/ nodeProxy( MathNode, MathNode.BITCAST );
  533. /**
  534. * Returns `true` if `x` equals `y`.
  535. *
  536. * @function
  537. * @param {Node | Number} x - The first parameter.
  538. * @param {Node | Number} y - The second parameter.
  539. * @returns {Node<bool>}
  540. */
  541. export const equals = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EQUALS );
  542. /**
  543. * Returns the lesser of two values.
  544. *
  545. * @function
  546. * @param {Node | Number} x - The y parameter.
  547. * @param {Node | Number} y - The x parameter.
  548. * @returns {Node}
  549. */
  550. export const min = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIN );
  551. /**
  552. * Returns the greater of two values.
  553. *
  554. * @function
  555. * @param {Node | Number} x - The y parameter.
  556. * @param {Node | Number} y - The x parameter.
  557. * @returns {Node}
  558. */
  559. export const max = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MAX );
  560. /**
  561. * Computes the remainder of dividing the first node by the second one.
  562. *
  563. * @function
  564. * @param {Node | Number} x - The y parameter.
  565. * @param {Node | Number} y - The x parameter.
  566. * @returns {Node}
  567. */
  568. export const mod = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MOD );
  569. /**
  570. * Generate a step function by comparing two values.
  571. *
  572. * @function
  573. * @param {Node | Number} x - The y parameter.
  574. * @param {Node | Number} y - The x parameter.
  575. * @returns {Node}
  576. */
  577. export const step = /*@__PURE__*/ nodeProxy( MathNode, MathNode.STEP );
  578. /**
  579. * Calculates the reflection direction for an incident vector.
  580. *
  581. * @function
  582. * @param {Node<vec2|vec3|vec4>} I - The incident vector.
  583. * @param {Node<vec2|vec3|vec4>} N - The normal vector.
  584. * @returns {Node<vec2|vec3|vec4>}
  585. */
  586. export const reflect = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFLECT );
  587. /**
  588. * Calculates the distance between two points.
  589. *
  590. * @function
  591. * @param {Node<vec2|vec3|vec4>} x - The first point.
  592. * @param {Node<vec2|vec3|vec4>} y - The second point.
  593. * @returns {Node<float>}
  594. */
  595. export const distance = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DISTANCE );
  596. /**
  597. * Calculates the absolute difference between two values.
  598. *
  599. * @function
  600. * @param {Node | Number} x - The first parameter.
  601. * @param {Node | Number} y - The second parameter.
  602. * @returns {Node}
  603. */
  604. export const difference = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DIFFERENCE );
  605. /**
  606. * Calculates the dot product of two vectors.
  607. *
  608. * @function
  609. * @param {Node<vec2|vec3|vec4>} x - The first vector.
  610. * @param {Node<vec2|vec3|vec4>} y - The second vector.
  611. * @returns {Node<float>}
  612. */
  613. export const dot = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DOT );
  614. /**
  615. * Calculates the cross product of two vectors.
  616. *
  617. * @function
  618. * @param {Node<vec2|vec3|vec4>} x - The first vector.
  619. * @param {Node<vec2|vec3|vec4>} y - The second vector.
  620. * @returns {Node<vec2|vec3|vec4>}
  621. */
  622. export const cross = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CROSS );
  623. /**
  624. * Return the value of the first parameter raised to the power of the second one.
  625. *
  626. * @function
  627. * @param {Node | Number} x - The first parameter.
  628. * @param {Node | Number} y - The second parameter.
  629. * @returns {Node}
  630. */
  631. export const pow = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW );
  632. /**
  633. * Returns the square of the parameter.
  634. *
  635. * @function
  636. * @param {Node | Number} x - The first parameter.
  637. * @returns {Node}
  638. */
  639. export const pow2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 2 );
  640. /**
  641. * Returns the cube of the parameter.
  642. *
  643. * @function
  644. * @param {Node | Number} x - The first parameter.
  645. * @returns {Node}
  646. */
  647. export const pow3 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 3 );
  648. /**
  649. * Returns the fourth power of the parameter.
  650. *
  651. * @function
  652. * @param {Node | Number} x - The first parameter.
  653. * @returns {Node}
  654. */
  655. export const pow4 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 4 );
  656. /**
  657. * Transforms the direction of a vector by a matrix and then normalizes the result.
  658. *
  659. * @function
  660. * @param {Node<vec2|vec3|vec4>} direction - The direction vector.
  661. * @param {Node<mat2|mat3|mat4>} matrix - The transformation matrix.
  662. * @returns {Node}
  663. */
  664. export const transformDirection = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSFORM_DIRECTION );
  665. /**
  666. * Returns the cube root of a number.
  667. *
  668. * @function
  669. * @param {Node | Number} a - The first parameter.
  670. * @returns {Node}
  671. */
  672. export const cbrt = ( a ) => mul( sign( a ), pow( abs( a ), 1.0 / 3.0 ) );
  673. /**
  674. * Calculate the squared length of a vector.
  675. *
  676. * @function
  677. * @param {Node<vec2|vec3|vec4>} a - The vector.
  678. * @returns {Node<float>}
  679. */
  680. export const lengthSq = ( a ) => dot( a, a );
  681. /**
  682. * Linearly interpolates between two values.
  683. *
  684. * @function
  685. * @param {Node | Number} a - The first parameter.
  686. * @param {Node | Number} b - The second parameter.
  687. * @param {Node | Number} t - The interpolation value.
  688. * @returns {Node}
  689. */
  690. export const mix = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIX );
  691. /**
  692. * Constrains a value to lie between two further values.
  693. *
  694. * @function
  695. * @param {Node | Number} value - The value to constrain.
  696. * @param {Node | Number} [low=0] - The lower bound.
  697. * @param {Node | Number} [high=1] - The upper bound.
  698. * @returns {Node}
  699. */
  700. export const clamp = ( value, low = 0, high = 1 ) => nodeObject( new MathNode( MathNode.CLAMP, nodeObject( value ), nodeObject( low ), nodeObject( high ) ) );
  701. /**
  702. * Constrains a value between `0` and `1`.
  703. *
  704. * @function
  705. * @param {Node | Number} value - The value to constrain.
  706. * @returns {Node}
  707. */
  708. export const saturate = ( value ) => clamp( value );
  709. /**
  710. * Calculates the refraction direction for an incident vector.
  711. *
  712. * @function
  713. * @param {Node<vec2|vec3|vec4>} I - The incident vector.
  714. * @param {Node<vec2|vec3|vec4>} N - The normal vector.
  715. * @param {Node<float>} eta - The the ratio of indices of refraction.
  716. * @returns {Node<vec2|vec3|vec4>}
  717. */
  718. export const refract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFRACT );
  719. /**
  720. * Performs a Hermite interpolation between two values.
  721. *
  722. * @function
  723. * @param {Node | Number} low - The value of the lower edge of the Hermite function.
  724. * @param {Node | Number} high - The value of the upper edge of the Hermite function.
  725. * @param {Node | Number} x - The source value for interpolation.
  726. * @returns {Node}
  727. */
  728. export const smoothstep = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SMOOTHSTEP );
  729. /**
  730. * Returns a vector pointing in the same direction as another.
  731. *
  732. * @function
  733. * @param {Node<vec2|vec3|vec4>} N - The vector to orient.
  734. * @param {Node<vec2|vec3|vec4>} I - The incident vector.
  735. * @param {Node<vec2|vec3|vec4>} Nref - The reference vector.
  736. * @returns {Node<vec2|vec3|vec4>}
  737. */
  738. export const faceForward = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FACEFORWARD );
  739. /**
  740. * Returns a random value for the given uv.
  741. *
  742. * @function
  743. * @param {Node<vec2>} uv - The uv node.
  744. * @returns {Node<float>}
  745. */
  746. export const rand = /*@__PURE__*/ Fn( ( [ uv ] ) => {
  747. const a = 12.9898, b = 78.233, c = 43758.5453;
  748. const dt = dot( uv.xy, vec2( a, b ) ), sn = mod( dt, PI );
  749. return fract( sin( sn ).mul( c ) );
  750. } );
  751. /**
  752. * Alias for `mix()` with a different parameter order.
  753. *
  754. * @function
  755. * @param {Node | Number} t - The interpolation value.
  756. * @param {Node | Number} e1 - The first parameter.
  757. * @param {Node | Number} e2 - The second parameter.
  758. * @returns {Node}
  759. */
  760. export const mixElement = ( t, e1, e2 ) => mix( e1, e2, t );
  761. /**
  762. * Alias for `smoothstep()` with a different parameter order.
  763. *
  764. * @function
  765. * @param {Node | Number} x - The source value for interpolation.
  766. * @param {Node | Number} low - The value of the lower edge of the Hermite function.
  767. * @param {Node | Number} high - The value of the upper edge of the Hermite function.
  768. * @returns {Node}
  769. */
  770. export const smoothstepElement = ( x, low, high ) => smoothstep( low, high, x );
  771. /**
  772. * Returns the arc-tangent of the quotient of its parameters.
  773. *
  774. * @function
  775. * @param {Node | Number} y - The y parameter.
  776. * @param {Node | Number} x - The x parameter.
  777. * @returns {Node}
  778. */
  779. export const atan2 = ( y, x ) => { // @deprecated, r172
  780. console.warn( 'THREE.TSL: "atan2" is overloaded. Use "atan" instead.' );
  781. return atan( y, x );
  782. };
  783. // GLSL alias function
  784. export const faceforward = faceForward;
  785. export const inversesqrt = inverseSqrt;
  786. // Method chaining
  787. addMethodChaining( 'all', all );
  788. addMethodChaining( 'any', any );
  789. addMethodChaining( 'equals', equals );
  790. addMethodChaining( 'radians', radians );
  791. addMethodChaining( 'degrees', degrees );
  792. addMethodChaining( 'exp', exp );
  793. addMethodChaining( 'exp2', exp2 );
  794. addMethodChaining( 'log', log );
  795. addMethodChaining( 'log2', log2 );
  796. addMethodChaining( 'sqrt', sqrt );
  797. addMethodChaining( 'inverseSqrt', inverseSqrt );
  798. addMethodChaining( 'floor', floor );
  799. addMethodChaining( 'ceil', ceil );
  800. addMethodChaining( 'normalize', normalize );
  801. addMethodChaining( 'fract', fract );
  802. addMethodChaining( 'sin', sin );
  803. addMethodChaining( 'cos', cos );
  804. addMethodChaining( 'tan', tan );
  805. addMethodChaining( 'asin', asin );
  806. addMethodChaining( 'acos', acos );
  807. addMethodChaining( 'atan', atan );
  808. addMethodChaining( 'abs', abs );
  809. addMethodChaining( 'sign', sign );
  810. addMethodChaining( 'length', length );
  811. addMethodChaining( 'lengthSq', lengthSq );
  812. addMethodChaining( 'negate', negate );
  813. addMethodChaining( 'oneMinus', oneMinus );
  814. addMethodChaining( 'dFdx', dFdx );
  815. addMethodChaining( 'dFdy', dFdy );
  816. addMethodChaining( 'round', round );
  817. addMethodChaining( 'reciprocal', reciprocal );
  818. addMethodChaining( 'trunc', trunc );
  819. addMethodChaining( 'fwidth', fwidth );
  820. addMethodChaining( 'atan2', atan2 );
  821. addMethodChaining( 'min', min );
  822. addMethodChaining( 'max', max );
  823. addMethodChaining( 'mod', mod );
  824. addMethodChaining( 'step', step );
  825. addMethodChaining( 'reflect', reflect );
  826. addMethodChaining( 'distance', distance );
  827. addMethodChaining( 'dot', dot );
  828. addMethodChaining( 'cross', cross );
  829. addMethodChaining( 'pow', pow );
  830. addMethodChaining( 'pow2', pow2 );
  831. addMethodChaining( 'pow3', pow3 );
  832. addMethodChaining( 'pow4', pow4 );
  833. addMethodChaining( 'transformDirection', transformDirection );
  834. addMethodChaining( 'mix', mixElement );
  835. addMethodChaining( 'clamp', clamp );
  836. addMethodChaining( 'refract', refract );
  837. addMethodChaining( 'smoothstep', smoothstepElement );
  838. addMethodChaining( 'faceForward', faceForward );
  839. addMethodChaining( 'difference', difference );
  840. addMethodChaining( 'saturate', saturate );
  841. addMethodChaining( 'cbrt', cbrt );
  842. addMethodChaining( 'transpose', transpose );
  843. addMethodChaining( 'rand', rand );
粤ICP备19079148号