imageProcessingBlock.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { NodeMaterialBlock } from '../../nodeMaterialBlock';
  2. import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
  3. import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
  4. import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
  5. import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
  6. import { AbstractMesh } from '../../../../Meshes/abstractMesh';
  7. import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
  8. import { Effect } from '../../../effect';
  9. import { Mesh } from '../../../../Meshes/mesh';
  10. import { _TypeStore } from '../../../../Misc/typeStore';
  11. /**
  12. * Block used to add image processing support to fragment shader
  13. */
  14. export class ImageProcessingBlock extends NodeMaterialBlock {
  15. /**
  16. * Create a new ImageProcessingBlock
  17. * @param name defines the block name
  18. */
  19. public constructor(name: string) {
  20. super(name, NodeMaterialBlockTargets.Fragment);
  21. this.registerInput("color", NodeMaterialBlockConnectionPointTypes.Color4);
  22. this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Color4);
  23. this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
  24. }
  25. /**
  26. * Gets the current class name
  27. * @returns the class name
  28. */
  29. public getClassName() {
  30. return "ImageProcessingBlock";
  31. }
  32. /**
  33. * Gets the color input component
  34. */
  35. public get color(): NodeMaterialConnectionPoint {
  36. return this._inputs[0];
  37. }
  38. /**
  39. * Gets the output component
  40. */
  41. public get output(): NodeMaterialConnectionPoint {
  42. return this._outputs[0];
  43. }
  44. /**
  45. * Initialize the block and prepare the context for build
  46. * @param state defines the state that will be used for the build
  47. */
  48. public initialize(state: NodeMaterialBuildState) {
  49. state._excludeVariableName("exposureLinear");
  50. state._excludeVariableName("contrast");
  51. state._excludeVariableName("vInverseScreenSize");
  52. state._excludeVariableName("vignetteSettings1");
  53. state._excludeVariableName("vignetteSettings2");
  54. state._excludeVariableName("vCameraColorCurveNegative");
  55. state._excludeVariableName("vCameraColorCurveNeutral");
  56. state._excludeVariableName("vCameraColorCurvePositive");
  57. state._excludeVariableName("txColorTransform");
  58. state._excludeVariableName("colorTransformSettings");
  59. }
  60. public isReady(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
  61. if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {
  62. if (!nodeMaterial.imageProcessingConfiguration.isReady()) {
  63. return false;
  64. }
  65. }
  66. return true;
  67. }
  68. public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
  69. if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {
  70. nodeMaterial.imageProcessingConfiguration.prepareDefines(defines);
  71. }
  72. }
  73. public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
  74. if (!mesh) {
  75. return;
  76. }
  77. if (!nodeMaterial.imageProcessingConfiguration) {
  78. return;
  79. }
  80. nodeMaterial.imageProcessingConfiguration.bind(effect);
  81. }
  82. protected _buildBlock(state: NodeMaterialBuildState) {
  83. super._buildBlock(state);
  84. // Register for defines
  85. state.sharedData.blocksWithDefines.push(this);
  86. // Register for blocking
  87. state.sharedData.blockingBlocks.push(this);
  88. // Register for binding
  89. state.sharedData.bindableBlocks.push(this);
  90. // Uniforms
  91. state.uniforms.push("exposureLinear");
  92. state.uniforms.push("contrast");
  93. state.uniforms.push("vInverseScreenSize");
  94. state.uniforms.push("vignetteSettings1");
  95. state.uniforms.push("vignetteSettings2");
  96. state.uniforms.push("vCameraColorCurveNegative");
  97. state.uniforms.push("vCameraColorCurveNeutral");
  98. state.uniforms.push("vCameraColorCurvePositive");
  99. state.uniforms.push("txColorTransform");
  100. state.uniforms.push("colorTransformSettings");
  101. // Emit code
  102. let color = this.color;
  103. let output = this._outputs[0];
  104. let comments = `//${this.name}`;
  105. state._emitFunctionFromInclude("helperFunctions", comments);
  106. state._emitFunctionFromInclude("imageProcessingDeclaration", comments);
  107. state._emitFunctionFromInclude("imageProcessingFunctions", comments);
  108. if (color.connectedPoint!.type === NodeMaterialBlockConnectionPointTypes.Color4) {
  109. state.compilationString += `${this._declareOutput(output, state)} = ${color.associatedVariableName};\r\n`;
  110. } else {
  111. state.compilationString += `${this._declareOutput(output, state)} = vec4(${color.associatedVariableName}, 1.0);\r\n`;
  112. }
  113. state.compilationString += `#ifdef IMAGEPROCESSINGPOSTPROCESS\r\n`;
  114. state.compilationString += `${output.associatedVariableName}.rgb = toLinearSpace(${color.associatedVariableName}.rgb);\r\n`;
  115. state.compilationString += `#else\r\n`;
  116. state.compilationString += `#ifdef IMAGEPROCESSING\r\n`;
  117. state.compilationString += `${output.associatedVariableName}.rgb = toLinearSpace(${color.associatedVariableName}.rgb);\r\n`;
  118. state.compilationString += `${output.associatedVariableName} = applyImageProcessing(${output.associatedVariableName});\r\n`;
  119. state.compilationString += `#endif\r\n`;
  120. state.compilationString += `#endif\r\n`;
  121. return this;
  122. }
  123. }
  124. _TypeStore.RegisteredTypes["BABYLON.ImageProcessingBlock"] = ImageProcessingBlock;