NormalNode.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { TempNode } from '../core/TempNode.js';
  2. import { NodeLib } from '../core/NodeLib.js';
  3. class NormalNode extends TempNode {
  4. constructor( scope ) {
  5. super( 'v3' );
  6. this.scope = scope || NormalNode.VIEW;
  7. }
  8. getShared() {
  9. // if shared is false, TempNode will not create temp variable (for optimization)
  10. return this.scope === NormalNode.WORLD;
  11. }
  12. build( builder, output, uuid, ns ) {
  13. const contextNormal = builder.context[ this.scope + 'Normal' ];
  14. if ( contextNormal ) {
  15. return contextNormal.build( builder, output, uuid, ns );
  16. }
  17. return super.build( builder, output, uuid );
  18. }
  19. generate( builder, output ) {
  20. let result;
  21. switch ( this.scope ) {
  22. case NormalNode.VIEW:
  23. if ( builder.isShader( 'vertex' ) ) result = 'transformedNormal';
  24. else result = 'geometryNormal';
  25. break;
  26. case NormalNode.LOCAL:
  27. if ( builder.isShader( 'vertex' ) ) {
  28. result = 'objectNormal';
  29. } else {
  30. builder.requires.normal = true;
  31. result = 'vObjectNormal';
  32. }
  33. break;
  34. case NormalNode.WORLD:
  35. if ( builder.isShader( 'vertex' ) ) {
  36. result = 'inverseTransformDirection( transformedNormal, viewMatrix ).xyz';
  37. } else {
  38. builder.requires.worldNormal = true;
  39. result = 'vWNormal';
  40. }
  41. break;
  42. }
  43. return builder.format( result, this.getType( builder ), output );
  44. }
  45. copy( source ) {
  46. super.copy( source );
  47. this.scope = source.scope;
  48. return this;
  49. }
  50. toJSON( meta ) {
  51. let data = this.getJSONNode( meta );
  52. if ( ! data ) {
  53. data = this.createJSONNode( meta );
  54. data.scope = this.scope;
  55. }
  56. return data;
  57. }
  58. }
  59. NormalNode.LOCAL = 'local';
  60. NormalNode.WORLD = 'world';
  61. NormalNode.VIEW = 'view';
  62. NormalNode.prototype.nodeType = 'Normal';
  63. NodeLib.addKeyword( 'viewNormal', function () {
  64. return new NormalNode( NormalNode.VIEW );
  65. } );
  66. NodeLib.addKeyword( 'localNormal', function () {
  67. return new NormalNode( NormalNode.NORMAL );
  68. } );
  69. NodeLib.addKeyword( 'worldNormal', function () {
  70. return new NormalNode( NormalNode.WORLD );
  71. } );
  72. export { NormalNode };