Sidebar.Project.Renderer.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import * as THREE from 'three';
  2. import { WebGPURenderer } from 'three/webgpu';
  3. import { UINumber, UIPanel, UIRow, UISelect, UIText } from './libs/ui.js';
  4. import { UIBoolean } from './libs/ui.three.js';
  5. function SidebarProjectRenderer( editor ) {
  6. const config = editor.config;
  7. const signals = editor.signals;
  8. const strings = editor.strings;
  9. let currentRenderer = null;
  10. const container = new UIPanel();
  11. container.setBorderTop( '0px' );
  12. // Camera
  13. const cameraRow = new UIRow();
  14. container.add( cameraRow );
  15. cameraRow.add( new UIText( strings.getKey( 'sidebar/project/camera' ) ).setClass( 'Label' ) );
  16. const cameraTypeSelect = new UISelect().setOptions( {
  17. 'perspective': 'Perspective',
  18. 'orthographic': 'Orthographic'
  19. } ).setWidth( '150px' ).onChange( function () {
  20. editor.setCameraType( this.getValue() );
  21. } );
  22. cameraTypeSelect.setValue( config.getKey( 'project/camera' ) );
  23. cameraRow.add( cameraTypeSelect );
  24. if ( config.getKey( 'project/camera' ) === 'orthographic' ) {
  25. editor.setCameraType( 'orthographic' );
  26. }
  27. // Renderer
  28. const rendererRow = new UIRow();
  29. container.add( rendererRow );
  30. rendererRow.add( new UIText( strings.getKey( 'sidebar/project/renderer' ) ).setClass( 'Label' ) );
  31. const rendererTypeSelect = new UISelect().setOptions( {
  32. 'WebGLRenderer': 'WebGL',
  33. 'WebGPURenderer': 'WebGPU'
  34. } ).setWidth( '150px' ).onChange( createRenderer );
  35. rendererTypeSelect.setValue( config.getKey( 'project/renderer/type' ) );
  36. rendererRow.add( rendererTypeSelect );
  37. // Antialias
  38. const antialiasRow = new UIRow();
  39. container.add( antialiasRow );
  40. antialiasRow.add( new UIText( strings.getKey( 'sidebar/project/antialias' ) ).setClass( 'Label' ) );
  41. const antialiasBoolean = new UIBoolean( config.getKey( 'project/renderer/antialias' ) ).onChange( createRenderer );
  42. antialiasRow.add( antialiasBoolean );
  43. // Shadows
  44. const shadowsRow = new UIRow();
  45. container.add( shadowsRow );
  46. shadowsRow.add( new UIText( strings.getKey( 'sidebar/project/shadows' ) ).setClass( 'Label' ) );
  47. const shadowsBoolean = new UIBoolean( config.getKey( 'project/renderer/shadows' ) ).onChange( updateShadows );
  48. shadowsRow.add( shadowsBoolean );
  49. const shadowTypeSelect = new UISelect().setOptions( {
  50. 0: 'Basic',
  51. 1: 'PCF',
  52. 3: 'VSM'
  53. } ).setWidth( '125px' ).onChange( updateShadows );
  54. shadowTypeSelect.setValue( config.getKey( 'project/renderer/shadowType' ) );
  55. shadowsRow.add( shadowTypeSelect );
  56. function updateShadows() {
  57. currentRenderer.shadowMap.enabled = shadowsBoolean.getValue();
  58. currentRenderer.shadowMap.type = parseFloat( shadowTypeSelect.getValue() );
  59. signals.rendererUpdated.dispatch();
  60. }
  61. // Tonemapping
  62. const toneMappingRow = new UIRow();
  63. container.add( toneMappingRow );
  64. toneMappingRow.add( new UIText( strings.getKey( 'sidebar/project/toneMapping' ) ).setClass( 'Label' ) );
  65. const toneMappingSelect = new UISelect().setOptions( {
  66. 0: 'No',
  67. 1: 'Linear',
  68. 2: 'Reinhard',
  69. 3: 'Cineon',
  70. 4: 'ACESFilmic',
  71. 6: 'AgX',
  72. 7: 'Neutral'
  73. } ).setWidth( '120px' ).onChange( updateToneMapping );
  74. toneMappingSelect.setValue( config.getKey( 'project/renderer/toneMapping' ) );
  75. toneMappingRow.add( toneMappingSelect );
  76. const toneMappingExposure = new UINumber( config.getKey( 'project/renderer/toneMappingExposure' ) );
  77. toneMappingExposure.setDisplay( toneMappingSelect.getValue() === '0' ? 'none' : '' );
  78. toneMappingExposure.setWidth( '30px' ).setMarginLeft( '10px' );
  79. toneMappingExposure.setRange( 0, 10 );
  80. toneMappingExposure.onChange( updateToneMapping );
  81. toneMappingRow.add( toneMappingExposure );
  82. function updateToneMapping() {
  83. toneMappingExposure.setDisplay( toneMappingSelect.getValue() === '0' ? 'none' : '' );
  84. currentRenderer.toneMapping = parseFloat( toneMappingSelect.getValue() );
  85. currentRenderer.toneMappingExposure = toneMappingExposure.getValue();
  86. signals.rendererUpdated.dispatch();
  87. }
  88. //
  89. async function createRenderer() {
  90. const rendererType = rendererTypeSelect.getValue();
  91. const antialias = antialiasBoolean.getValue();
  92. if ( rendererType === 'WebGPURenderer' ) {
  93. currentRenderer = new WebGPURenderer( { antialias: antialias, reversedDepthBuffer: true } );
  94. await currentRenderer.init();
  95. } else {
  96. currentRenderer = new THREE.WebGLRenderer( { antialias: antialias, reversedDepthBuffer: true } );
  97. }
  98. currentRenderer.shadowMap.enabled = shadowsBoolean.getValue();
  99. currentRenderer.shadowMap.type = parseFloat( shadowTypeSelect.getValue() );
  100. currentRenderer.toneMapping = parseFloat( toneMappingSelect.getValue() );
  101. currentRenderer.toneMappingExposure = toneMappingExposure.getValue();
  102. signals.rendererCreated.dispatch( currentRenderer );
  103. signals.rendererUpdated.dispatch();
  104. }
  105. createRenderer();
  106. // Signals
  107. signals.cameraResetted.add( function () {
  108. const type = editor.camera.isOrthographicCamera ? 'orthographic' : 'perspective';
  109. cameraTypeSelect.setValue( type );
  110. config.setKey( 'project/camera', type );
  111. } );
  112. signals.editorCleared.add( function () {
  113. currentRenderer.shadowMap.enabled = true;
  114. currentRenderer.shadowMap.type = THREE.PCFShadowMap;
  115. currentRenderer.toneMapping = THREE.NeutralToneMapping;
  116. currentRenderer.toneMappingExposure = 1;
  117. shadowsBoolean.setValue( currentRenderer.shadowMap.enabled );
  118. shadowTypeSelect.setValue( currentRenderer.shadowMap.type );
  119. toneMappingSelect.setValue( currentRenderer.toneMapping );
  120. toneMappingExposure.setValue( currentRenderer.toneMappingExposure );
  121. toneMappingExposure.setDisplay( currentRenderer.toneMapping === 0 ? 'none' : '' );
  122. signals.rendererUpdated.dispatch();
  123. } );
  124. signals.rendererUpdated.add( function () {
  125. config.setKey(
  126. 'project/renderer/type', rendererTypeSelect.getValue(),
  127. 'project/renderer/antialias', antialiasBoolean.getValue(),
  128. 'project/renderer/shadows', shadowsBoolean.getValue(),
  129. 'project/renderer/shadowType', parseFloat( shadowTypeSelect.getValue() ),
  130. 'project/renderer/toneMapping', parseFloat( toneMappingSelect.getValue() ),
  131. 'project/renderer/toneMappingExposure', toneMappingExposure.getValue()
  132. );
  133. } );
  134. return container;
  135. }
  136. export { SidebarProjectRenderer };
粤ICP备19079148号