CameraNode.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /**
  2. * @author sunag / http://www.sunag.com.br/
  3. */
  4. import { TempNode } from '../core/TempNode.js';
  5. import { FunctionNode } from '../core/FunctionNode.js';
  6. import { FloatNode } from '../inputs/FloatNode.js';
  7. import { PositionNode } from '../accessors/PositionNode.js';
  8. function CameraNode( scope, camera ) {
  9. TempNode.call( this, 'v3' );
  10. this.setScope( scope || CameraNode.POSITION );
  11. this.setCamera( camera );
  12. };
  13. CameraNode.Nodes = (function() {
  14. var depthColor = new FunctionNode( [
  15. "float depthColor( float mNear, float mFar ) {",
  16. " #ifdef USE_LOGDEPTHBUF_EXT",
  17. " float depth = gl_FragDepthEXT / gl_FragCoord.w;",
  18. " #else",
  19. " float depth = gl_FragCoord.z / gl_FragCoord.w;",
  20. " #endif",
  21. " return 1.0 - smoothstep( mNear, mFar, depth );",
  22. "}"
  23. ].join( "\n" ) );
  24. return {
  25. depthColor: depthColor
  26. };
  27. })();
  28. CameraNode.POSITION = 'position';
  29. CameraNode.DEPTH = 'depth';
  30. CameraNode.TO_VERTEX = 'toVertex';
  31. CameraNode.prototype = Object.create( TempNode.prototype );
  32. CameraNode.prototype.constructor = CameraNode;
  33. CameraNode.prototype.nodeType = "Camera";
  34. CameraNode.prototype.setCamera = function ( camera ) {
  35. this.camera = camera;
  36. this.updateFrame = camera !== undefined ? this.onUpdateFrame : undefined;
  37. };
  38. CameraNode.prototype.setScope = function ( scope ) {
  39. switch ( this.scope ) {
  40. case CameraNode.DEPTH:
  41. delete this.near;
  42. delete this.far;
  43. break;
  44. }
  45. this.scope = scope;
  46. switch ( scope ) {
  47. case CameraNode.DEPTH:
  48. var camera = this.camera;
  49. this.near = new FloatNode( camera ? camera.near : 1 );
  50. this.far = new FloatNode( camera ? camera.far : 1200 );
  51. break;
  52. }
  53. };
  54. CameraNode.prototype.getType = function ( builder ) {
  55. switch ( this.scope ) {
  56. case CameraNode.DEPTH:
  57. return 'fv1';
  58. }
  59. return this.type;
  60. };
  61. CameraNode.prototype.isUnique = function ( builder ) {
  62. switch ( this.scope ) {
  63. case CameraNode.DEPTH:
  64. case CameraNode.TO_VERTEX:
  65. return true;
  66. }
  67. return false;
  68. };
  69. CameraNode.prototype.isShared = function ( builder ) {
  70. switch ( this.scope ) {
  71. case CameraNode.POSITION:
  72. return false;
  73. }
  74. return true;
  75. };
  76. CameraNode.prototype.generate = function ( builder, output ) {
  77. var result;
  78. switch ( this.scope ) {
  79. case CameraNode.POSITION:
  80. result = 'cameraPosition';
  81. break;
  82. case CameraNode.DEPTH:
  83. var depthColor = builder.include( CameraNode.Nodes.depthColor );
  84. result = depthColor + '( ' + this.near.build( builder, 'fv1' ) + ', ' + this.far.build( builder, 'fv1' ) + ' )';
  85. break;
  86. case CameraNode.TO_VERTEX:
  87. result = 'normalize( ' + new PositionNode( PositionNode.WORLD ).build( builder, 'v3' ) + ' - cameraPosition )';
  88. break;
  89. }
  90. return builder.format( result, this.getType( builder ), output );
  91. };
  92. CameraNode.prototype.onUpdateFrame = function ( frame ) {
  93. switch ( this.scope ) {
  94. case CameraNode.DEPTH:
  95. var camera = this.camera;
  96. this.near.value = camera.near;
  97. this.far.value = camera.far;
  98. break;
  99. }
  100. };
  101. CameraNode.prototype.copy = function ( source ) {
  102. TempNode.prototype.copy.call( this, source );
  103. this.setScope( source.scope );
  104. if ( source.camera ) {
  105. this.setCamera( source.camera );
  106. }
  107. switch ( source.scope ) {
  108. case CameraNode.DEPTH:
  109. this.near.number = source.near;
  110. this.far.number = source.far;
  111. break;
  112. }
  113. };
  114. CameraNode.prototype.toJSON = function ( meta ) {
  115. var data = this.getJSONNode( meta );
  116. if ( ! data ) {
  117. data = this.createJSONNode( meta );
  118. data.scope = this.scope;
  119. if ( this.camera ) data.camera = this.camera.uuid;
  120. switch ( this.scope ) {
  121. case CameraNode.DEPTH:
  122. data.near = this.near.value;
  123. data.far = this.far.value;
  124. break;
  125. }
  126. }
  127. return data;
  128. };
  129. export { CameraNode };