imageProcessingBlock.ts 5.6 KB

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