mx_hsv.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Three.js Transpiler
  2. // https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/genglsl/lib/mx_hsv.glsl
  3. import { int, float, vec3, If, tslFn } from '../../shadernode/ShaderNode.js';
  4. import { add, sub, mul } from '../../math/OperatorNode.js';
  5. import { floor, trunc, max, min } from '../../math/MathNode.js';
  6. const mx_hsvtorgb = tslFn( ( [ hsv_immutable ] ) => {
  7. const hsv = vec3( hsv_immutable ).toVar();
  8. const h = float( hsv.x ).toVar();
  9. const s = float( hsv.y ).toVar();
  10. const v = float( hsv.z ).toVar();
  11. If( s.lessThan( 0.0001 ), () => {
  12. return vec3( v, v, v );
  13. } ).else( () => {
  14. h.assign( mul( 6.0, h.sub( floor( h ) ) ) );
  15. const hi = int( trunc( h ) ).toVar();
  16. const f = float( h.sub( float( hi ) ) ).toVar();
  17. const p = float( v.mul( sub( 1.0, s ) ) ).toVar();
  18. const q = float( v.mul( sub( 1.0, s.mul( f ) ) ) ).toVar();
  19. const t = float( v.mul( sub( 1.0, s.mul( sub( 1.0, f ) ) ) ) ).toVar();
  20. If( hi.equal( int( 0 ) ), () => {
  21. return vec3( v, t, p );
  22. } ).elseif( hi.equal( int( 1 ) ), () => {
  23. return vec3( q, v, p );
  24. } ).elseif( hi.equal( int( 2 ) ), () => {
  25. return vec3( p, v, t );
  26. } ).elseif( hi.equal( int( 3 ) ), () => {
  27. return vec3( p, q, v );
  28. } ).elseif( hi.equal( int( 4 ) ), () => {
  29. return vec3( t, p, v );
  30. } );
  31. return vec3( v, p, q );
  32. } );
  33. } );
  34. const mx_rgbtohsv = tslFn( ( [ c_immutable ] ) => {
  35. const c = vec3( c_immutable ).toVar();
  36. const r = float( c.x ).toVar();
  37. const g = float( c.y ).toVar();
  38. const b = float( c.z ).toVar();
  39. const mincomp = float( min( r, min( g, b ) ) ).toVar();
  40. const maxcomp = float( max( r, max( g, b ) ) ).toVar();
  41. const delta = float( maxcomp.sub( mincomp ) ).toVar();
  42. const h = float().toVar(), s = float().toVar(), v = float().toVar();
  43. v.assign( maxcomp );
  44. If( maxcomp.greaterThan( 0.0 ), () => {
  45. s.assign( delta.div( maxcomp ) );
  46. } ).else( () => {
  47. s.assign( 0.0 );
  48. } );
  49. If( s.lessThanEqual( 0.0 ), () => {
  50. h.assign( 0.0 );
  51. } ).else( () => {
  52. If( r.greaterThanEqual( maxcomp ), () => {
  53. h.assign( g.sub( b ).div( delta ) );
  54. } ).elseif( g.greaterThanEqual( maxcomp ), () => {
  55. h.assign( add( 2.0, b.sub( r ).div( delta ) ) );
  56. } ).else( () => {
  57. h.assign( add( 4.0, r.sub( g ).div( delta ) ) );
  58. } );
  59. h.mulAssign( 1.0 / 6.0 );
  60. If( h.lessThan( 0.0 ), () => {
  61. h.addAssign( 1.0 );
  62. } );
  63. } );
  64. return vec3( h, s, v );
  65. } );
  66. // layouts
  67. mx_hsvtorgb.setLayout( {
  68. name: 'mx_hsvtorgb',
  69. type: 'vec3',
  70. inputs: [
  71. { name: 'hsv', type: 'vec3' }
  72. ]
  73. } );
  74. mx_rgbtohsv.setLayout( {
  75. name: 'mx_rgbtohsv',
  76. type: 'vec3',
  77. inputs: [
  78. { name: 'c', type: 'vec3' }
  79. ]
  80. } );
  81. export { mx_hsvtorgb, mx_rgbtohsv };