reflectivityBlock.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { NodeMaterial, NodeMaterialDefines } from '../../../nodeMaterial';
  2. import { NodeMaterialBuildState } from '../../../nodeMaterialBuildState';
  3. import { NodeMaterialBlock } from '../../../nodeMaterialBlock';
  4. import { _TypeStore } from '../../../../../Misc/typeStore';
  5. import { editableInPropertyPage, PropertyTypeForEdition } from "../../../nodeMaterialDecorator";
  6. import { AbstractMesh } from '../../../../../Meshes/abstractMesh';
  7. import { NodeMaterialBlockConnectionPointTypes } from '../../../Enums/nodeMaterialBlockConnectionPointTypes';
  8. import { NodeMaterialBlockTargets } from '../../../Enums/nodeMaterialBlockTargets';
  9. import { NodeMaterialConnectionPointCustomObject } from "../../../nodeMaterialConnectionPointCustomObject";
  10. import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from '../../../nodeMaterialBlockConnectionPoint';
  11. import { Scene } from '../../../../../scene';
  12. export class ReflectivityBlock extends NodeMaterialBlock {
  13. @editableInPropertyPage("AO from red channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
  14. public useAmbientOcclusionFromMetallicTextureRed: boolean = false;
  15. @editableInPropertyPage("Metallness from blue channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
  16. public useMetallnessFromMetallicTextureBlue: boolean = true;
  17. @editableInPropertyPage("Roughness from alpha channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
  18. public useRoughnessFromMetallicTextureAlpha: boolean = false;
  19. @editableInPropertyPage("Roughness from green channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
  20. public useRoughnessFromMetallicTextureGreen: boolean = true;
  21. @editableInPropertyPage("Metallic F0 from alpha channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
  22. public useMetallicF0FactorFromMetallicTexture: boolean = false;
  23. /**
  24. * Create a new ReflectivityBlock
  25. * @param name defines the block name
  26. */
  27. public constructor(name: string) {
  28. super(name, NodeMaterialBlockTargets.Fragment);
  29. this._isUnique = true;
  30. this.registerInput("metallic", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
  31. this.registerInput("roughness", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
  32. this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
  33. this.registerOutput("reflectivity", NodeMaterialBlockConnectionPointTypes.Object, NodeMaterialBlockTargets.Fragment, new NodeMaterialConnectionPointCustomObject("reflectivity", this, NodeMaterialConnectionPointDirection.Output, ReflectivityBlock, "ReflectivityBlock"));
  34. }
  35. /**
  36. * Initialize the block and prepare the context for build
  37. * @param state defines the state that will be used for the build
  38. */
  39. public initialize(state: NodeMaterialBuildState) {
  40. state._excludeVariableName("baseColor");
  41. state._excludeVariableName("reflectivityOut");
  42. state._excludeVariableName("microSurface");
  43. state._excludeVariableName("roughness");
  44. }
  45. /**
  46. * Gets the current class name
  47. * @returns the class name
  48. */
  49. public getClassName() {
  50. return "ReflectivityBlock";
  51. }
  52. public get metallic(): NodeMaterialConnectionPoint {
  53. return this._inputs[0];
  54. }
  55. public get roughness(): NodeMaterialConnectionPoint {
  56. return this._inputs[1];
  57. }
  58. public get texture(): NodeMaterialConnectionPoint {
  59. return this._inputs[2];
  60. }
  61. /**
  62. * Gets the reflectivity output component
  63. */
  64. public get reflectivity(): NodeMaterialConnectionPoint {
  65. return this._outputs[0];
  66. }
  67. public getCode(aoIntensityVarName: string): string {
  68. const metalRoughTexture = this.texture.isConnected ? this.texture.connectedPoint?.associatedVariableName : null;
  69. let code = `vec3 baseColor = surfaceAlbedo;\r\nreflectivityOutParams reflectivityOut;\r\n`;
  70. code += `reflectivityBlock(
  71. vec4(${this.metallic.associatedVariableName}, ${this.roughness.associatedVariableName}, 0., 0.04),
  72. #ifdef METALLICWORKFLOW
  73. surfaceAlbedo,
  74. #endif
  75. #ifdef REFLECTIVITY
  76. vec3(0., 0., ${aoIntensityVarName}),
  77. ${metalRoughTexture},
  78. #endif
  79. #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)
  80. aoOut.ambientOcclusionColor,
  81. #endif
  82. #ifdef MICROSURFACEMAP
  83. microSurfaceTexel, <== not handled!
  84. #endif
  85. reflectivityOut
  86. );
  87. float microSurface = reflectivityOut.microSurface;
  88. float roughness = reflectivityOut.roughness;
  89. #ifdef METALLICWORKFLOW
  90. surfaceAlbedo = reflectivityOut.surfaceAlbedo;
  91. #endif
  92. #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)
  93. aoOut.ambientOcclusionColor = reflectivityOut.ambientOcclusionColor;
  94. #endif\r\n`;
  95. return code;
  96. }
  97. public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
  98. super.prepareDefines(mesh, nodeMaterial, defines);
  99. defines.setValue("REFLECTIVITY", this.texture.isConnected);
  100. defines.setValue("AOSTOREINMETALMAPRED", this.useAmbientOcclusionFromMetallicTextureRed);
  101. defines.setValue("METALLNESSSTOREINMETALMAPBLUE", this.useMetallnessFromMetallicTextureBlue);
  102. defines.setValue("ROUGHNESSSTOREINMETALMAPALPHA", this.useRoughnessFromMetallicTextureAlpha);
  103. defines.setValue("ROUGHNESSSTOREINMETALMAPGREEN", !this.useRoughnessFromMetallicTextureAlpha && this.useRoughnessFromMetallicTextureGreen);
  104. defines.setValue("METALLICF0FACTORFROMMETALLICMAP", this.useMetallicF0FactorFromMetallicTexture);
  105. }
  106. protected _buildBlock(state: NodeMaterialBuildState) {
  107. if (state.target === NodeMaterialBlockTargets.Fragment) {
  108. state.sharedData.blocksWithDefines.push(this);
  109. }
  110. return this;
  111. }
  112. public serialize(): any {
  113. let serializationObject = super.serialize();
  114. serializationObject.useAmbientOcclusionFromMetallicTextureRed = this.useAmbientOcclusionFromMetallicTextureRed;
  115. serializationObject.useMetallnessFromMetallicTextureBlue = this.useMetallnessFromMetallicTextureBlue;
  116. serializationObject.useRoughnessFromMetallicTextureAlpha = this.useRoughnessFromMetallicTextureAlpha;
  117. serializationObject.useRoughnessFromMetallicTextureGreen = this.useRoughnessFromMetallicTextureGreen;
  118. serializationObject.useMetallicF0FactorFromMetallicTexture = this.useMetallicF0FactorFromMetallicTexture;
  119. return serializationObject;
  120. }
  121. public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
  122. super._deserialize(serializationObject, scene, rootUrl);
  123. this.useAmbientOcclusionFromMetallicTextureRed = serializationObject.useAmbientOcclusionFromMetallicTextureRed;
  124. this.useMetallnessFromMetallicTextureBlue = serializationObject.useMetallnessFromMetallicTextureBlue;
  125. this.useRoughnessFromMetallicTextureAlpha = serializationObject.useRoughnessFromMetallicTextureAlpha;
  126. this.useRoughnessFromMetallicTextureGreen = serializationObject.useRoughnessFromMetallicTextureGreen;
  127. this.useMetallicF0FactorFromMetallicTexture = serializationObject.useMetallicF0FactorFromMetallicTexture;
  128. }
  129. }
  130. _TypeStore.RegisteredTypes["BABYLON.ReflectivityBlock"] = ReflectivityBlock;