NodeLib.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @author sunag / http://www.sunag.com.br/
  3. */
  4. THREE.NodeLib = {
  5. nodes: {},
  6. keywords: {},
  7. add: function( node ) {
  8. this.nodes[ node.name ] = node;
  9. },
  10. addKeyword: function( name, callback, cache ) {
  11. cache = cache !== undefined ? cache : true;
  12. this.keywords[ name ] = { callback : callback, cache : cache };
  13. },
  14. remove: function( node ) {
  15. delete this.nodes[ node.name ];
  16. },
  17. removeKeyword: function( name ) {
  18. delete this.keywords[ node ];
  19. },
  20. get: function( name ) {
  21. return this.nodes[ name ];
  22. },
  23. getKeyword: function( name, material ) {
  24. return this.keywords[ name ].callback.call( this, material );
  25. },
  26. getKeywordData: function( name ) {
  27. return this.keywords[ name ];
  28. },
  29. contains: function( name ) {
  30. return this.nodes[ name ] != undefined;
  31. },
  32. containsKeyword: function( name ) {
  33. return this.keywords[ name ] != undefined;
  34. }
  35. };
  36. //
  37. // Keywords
  38. //
  39. THREE.NodeLib.addKeyword( 'uv', function() {
  40. return new THREE.UVNode();
  41. } );
  42. THREE.NodeLib.addKeyword( 'uv2', function() {
  43. return new THREE.UVNode( 1 );
  44. } );
  45. THREE.NodeLib.addKeyword( 'position', function() {
  46. return new THREE.PositionNode();
  47. } );
  48. THREE.NodeLib.addKeyword( 'worldPosition', function() {
  49. return new THREE.PositionNode( THREE.PositionNode.WORLD );
  50. } );
  51. THREE.NodeLib.addKeyword( 'normal', function() {
  52. return new THREE.NormalNode();
  53. } );
  54. THREE.NodeLib.addKeyword( 'worldNormal', function() {
  55. return new THREE.NormalNode( THREE.NormalNode.WORLD );
  56. } );
  57. THREE.NodeLib.addKeyword( 'viewPosition', function() {
  58. return new THREE.PositionNode( THREE.NormalNode.VIEW );
  59. } );
  60. THREE.NodeLib.addKeyword( 'viewNormal', function() {
  61. return new THREE.NormalNode( THREE.NormalNode.VIEW );
  62. } );
  63. THREE.NodeLib.addKeyword( 'time', function() {
  64. return new THREE.TimerNode();
  65. } );
  66. //
  67. // Luma
  68. //
  69. THREE.NodeLib.add( new THREE.ConstNode( "vec3 LUMA vec3(0.2125, 0.7154, 0.0721)" ) );
  70. //
  71. // NormalMap
  72. //
  73. THREE.NodeLib.add( new THREE.FunctionNode( [
  74. // Per-Pixel Tangent Space Normal Mapping
  75. // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
  76. "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 scale ) {",
  77. " vec3 q0 = dFdx( eye_pos );",
  78. " vec3 q1 = dFdy( eye_pos );",
  79. " vec2 st0 = dFdx( mUv.st );",
  80. " vec2 st1 = dFdy( mUv.st );",
  81. " vec3 S = normalize( q0 * st1.t - q1 * st0.t );",
  82. " vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
  83. " vec3 N = normalize( surf_norm );",
  84. " vec3 mapN = map * 2.0 - 1.0;",
  85. " mapN.xy = scale * mapN.xy;",
  86. " mat3 tsn = mat3( S, T, N );",
  87. " return normalize( tsn * mapN );",
  88. "}"
  89. ].join( "\n" ), null, { derivatives: true } ) );
  90. //
  91. // Noise
  92. //
  93. THREE.NodeLib.add( new THREE.FunctionNode( [
  94. "float snoise(vec2 co) {",
  95. " return fract( sin( dot(co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 );",
  96. "}"
  97. ].join( "\n" ) ) );
  98. //
  99. // Hue
  100. //
  101. THREE.NodeLib.add( new THREE.FunctionNode( [
  102. "vec3 hue_rgb(vec3 rgb, float adjustment) {",
  103. " const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);",
  104. " const mat3 YIQtoRGB = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.107, 1.7046);",
  105. " vec3 yiq = RGBtoYIQ * rgb;",
  106. " float hue = atan(yiq.z, yiq.y) + adjustment;",
  107. " float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);",
  108. " return YIQtoRGB * vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));",
  109. "}"
  110. ].join( "\n" ) ) );
  111. //
  112. // Saturation
  113. //
  114. THREE.NodeLib.add( new THREE.FunctionNode( [
  115. // Algorithm from Chapter 16 of OpenGL Shading Language
  116. "vec3 saturation_rgb(vec3 rgb, float adjustment) {",
  117. " vec3 intensity = vec3(dot(rgb, LUMA));",
  118. " return mix(intensity, rgb, adjustment);",
  119. "}"
  120. ].join( "\n" ) ) );
  121. //
  122. // Luminance
  123. //
  124. THREE.NodeLib.add( new THREE.FunctionNode( [
  125. // Algorithm from Chapter 10 of Graphics Shaders
  126. "float luminance_rgb(vec3 rgb) {",
  127. " return dot(rgb, LUMA);",
  128. "}"
  129. ].join( "\n" ) ) );
  130. //
  131. // Vibrance
  132. //
  133. THREE.NodeLib.add( new THREE.FunctionNode( [
  134. // Shader by Evan Wallace adapted by @lo-th
  135. "vec3 vibrance_rgb(vec3 rgb, float adjustment) {",
  136. " float average = (rgb.r + rgb.g + rgb.b) / 3.0;",
  137. " float mx = max(rgb.r, max(rgb.g, rgb.b));",
  138. " float amt = (mx - average) * (-3.0 * adjustment);",
  139. " return mix(rgb.rgb, vec3(mx), amt);",
  140. "}"
  141. ].join( "\n" ) ) );