babylon.pbrBaseMaterial.ts 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579
  1. module BABYLON {
  2. class PBRMaterialDefines extends MaterialDefines implements IImageProcessingConfigurationDefines {
  3. public PBR = true;
  4. public MAINUV1 = false;
  5. public MAINUV2 = false;
  6. public UV1 = false;
  7. public UV2 = false;
  8. public ALBEDO = false;
  9. public ALBEDODIRECTUV = 0;
  10. public VERTEXCOLOR = false;
  11. public AMBIENT = false;
  12. public AMBIENTDIRECTUV = 0;
  13. public AMBIENTINGRAYSCALE = false;
  14. public OPACITY = false;
  15. public VERTEXALPHA = false;
  16. public OPACITYDIRECTUV = 0;
  17. public OPACITYRGB = false;
  18. public ALPHATEST = false;
  19. public DEPTHPREPASS = false;
  20. public ALPHABLEND = false;
  21. public ALPHAFROMALBEDO = false;
  22. public ALPHATESTVALUE = 0.5;
  23. public SPECULAROVERALPHA = false;
  24. public RADIANCEOVERALPHA = false;
  25. public ALPHAFRESNEL = false;
  26. public LINEARALPHAFRESNEL = false;
  27. public PREMULTIPLYALPHA = false;
  28. public EMISSIVE = false;
  29. public EMISSIVEDIRECTUV = 0;
  30. public REFLECTIVITY = false;
  31. public REFLECTIVITYDIRECTUV = 0;
  32. public SPECULARTERM = false;
  33. public MICROSURFACEFROMREFLECTIVITYMAP = false;
  34. public MICROSURFACEAUTOMATIC = false;
  35. public LODBASEDMICROSFURACE = false;
  36. public MICROSURFACEMAP = false;
  37. public MICROSURFACEMAPDIRECTUV = 0;
  38. public METALLICWORKFLOW = false;
  39. public ROUGHNESSSTOREINMETALMAPALPHA = false;
  40. public ROUGHNESSSTOREINMETALMAPGREEN = false;
  41. public METALLNESSSTOREINMETALMAPBLUE = false;
  42. public AOSTOREINMETALMAPRED = false;
  43. public ENVIRONMENTBRDF = false;
  44. public NORMAL = false;
  45. public TANGENT = false;
  46. public BUMP = false;
  47. public BUMPDIRECTUV = 0;
  48. public OBJECTSPACE_NORMALMAP = false;
  49. public PARALLAX = false;
  50. public PARALLAXOCCLUSION = false;
  51. public NORMALXYSCALE = true;
  52. public LIGHTMAP = false;
  53. public LIGHTMAPDIRECTUV = 0;
  54. public USELIGHTMAPASSHADOWMAP = false;
  55. public REFLECTION = false;
  56. public REFLECTIONMAP_3D = false;
  57. public REFLECTIONMAP_SPHERICAL = false;
  58. public REFLECTIONMAP_PLANAR = false;
  59. public REFLECTIONMAP_CUBIC = false;
  60. public REFLECTIONMAP_PROJECTION = false;
  61. public REFLECTIONMAP_SKYBOX = false;
  62. public REFLECTIONMAP_EXPLICIT = false;
  63. public REFLECTIONMAP_EQUIRECTANGULAR = false;
  64. public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
  65. public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
  66. public INVERTCUBICMAP = false;
  67. public USESPHERICALFROMREFLECTIONMAP = false;
  68. public USESPHERICALINVERTEX = false;
  69. public REFLECTIONMAP_OPPOSITEZ = false;
  70. public LODINREFLECTIONALPHA = false;
  71. public GAMMAREFLECTION = false;
  72. public RADIANCEOCCLUSION = false;
  73. public HORIZONOCCLUSION = false;
  74. public REFRACTION = false;
  75. public REFRACTIONMAP_3D = false;
  76. public REFRACTIONMAP_OPPOSITEZ = false;
  77. public LODINREFRACTIONALPHA = false;
  78. public GAMMAREFRACTION = false;
  79. public LINKREFRACTIONTOTRANSPARENCY = false;
  80. public INSTANCES = false;
  81. public NUM_BONE_INFLUENCERS = 0;
  82. public BonesPerMesh = 0;
  83. public NONUNIFORMSCALING = false;
  84. public MORPHTARGETS = false;
  85. public MORPHTARGETS_NORMAL = false;
  86. public MORPHTARGETS_TANGENT = false;
  87. public NUM_MORPH_INFLUENCERS = 0;
  88. public IMAGEPROCESSING = false;
  89. public VIGNETTE = false;
  90. public VIGNETTEBLENDMODEMULTIPLY = false;
  91. public VIGNETTEBLENDMODEOPAQUE = false;
  92. public TONEMAPPING = false;
  93. public CONTRAST = false;
  94. public COLORCURVES = false;
  95. public COLORGRADING = false;
  96. public COLORGRADING3D = false;
  97. public SAMPLER3DGREENDEPTH = false;
  98. public SAMPLER3DBGRMAP = false;
  99. public IMAGEPROCESSINGPOSTPROCESS = false;
  100. public EXPOSURE = false;
  101. public USEPHYSICALLIGHTFALLOFF = false;
  102. public TWOSIDEDLIGHTING = false;
  103. public SHADOWFLOAT = false;
  104. public CLIPPLANE = false;
  105. public POINTSIZE = false;
  106. public FOG = false;
  107. public LOGARITHMICDEPTH = false;
  108. public FORCENORMALFORWARD = false;
  109. constructor() {
  110. super();
  111. this.rebuild();
  112. }
  113. public reset(): void {
  114. super.reset();
  115. this.ALPHATESTVALUE = 0.5;
  116. this.PBR = true;
  117. }
  118. }
  119. /**
  120. * The Physically based material base class of BJS.
  121. *
  122. * This offers the main features of a standard PBR material.
  123. * For more information, please refer to the documentation :
  124. * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
  125. */
  126. export abstract class PBRBaseMaterial extends PushMaterial {
  127. /**
  128. * Intensity of the direct lights e.g. the four lights available in your scene.
  129. * This impacts both the direct diffuse and specular highlights.
  130. */
  131. protected _directIntensity: number = 1.0;
  132. /**
  133. * Intensity of the emissive part of the material.
  134. * This helps controlling the emissive effect without modifying the emissive color.
  135. */
  136. protected _emissiveIntensity: number = 1.0;
  137. /**
  138. * Intensity of the environment e.g. how much the environment will light the object
  139. * either through harmonics for rough material or through the refelction for shiny ones.
  140. */
  141. protected _environmentIntensity: number = 1.0;
  142. /**
  143. * This is a special control allowing the reduction of the specular highlights coming from the
  144. * four lights of the scene. Those highlights may not be needed in full environment lighting.
  145. */
  146. protected _specularIntensity: number = 1.0;
  147. private _lightingInfos: Vector4 = new Vector4(this._directIntensity, this._emissiveIntensity, this._environmentIntensity, this._specularIntensity);
  148. /**
  149. * Debug Control allowing disabling the bump map on this material.
  150. */
  151. protected _disableBumpMap: boolean = false;
  152. /**
  153. * AKA Diffuse Texture in standard nomenclature.
  154. */
  155. protected _albedoTexture: BaseTexture;
  156. /**
  157. * AKA Occlusion Texture in other nomenclature.
  158. */
  159. protected _ambientTexture: BaseTexture;
  160. /**
  161. * AKA Occlusion Texture Intensity in other nomenclature.
  162. */
  163. protected _ambientTextureStrength: number = 1.0;
  164. protected _opacityTexture: BaseTexture;
  165. protected _reflectionTexture: BaseTexture;
  166. protected _refractionTexture: BaseTexture;
  167. protected _emissiveTexture: BaseTexture;
  168. /**
  169. * AKA Specular texture in other nomenclature.
  170. */
  171. protected _reflectivityTexture: BaseTexture;
  172. /**
  173. * Used to switch from specular/glossiness to metallic/roughness workflow.
  174. */
  175. protected _metallicTexture: BaseTexture;
  176. /**
  177. * Specifies the metallic scalar of the metallic/roughness workflow.
  178. * Can also be used to scale the metalness values of the metallic texture.
  179. */
  180. protected _metallic: number;
  181. /**
  182. * Specifies the roughness scalar of the metallic/roughness workflow.
  183. * Can also be used to scale the roughness values of the metallic texture.
  184. */
  185. protected _roughness: number;
  186. /**
  187. * Used to enable roughness/glossiness fetch from a separate chanel depending on the current mode.
  188. * Gray Scale represents roughness in metallic mode and glossiness in specular mode.
  189. */
  190. protected _microSurfaceTexture: BaseTexture;
  191. protected _bumpTexture: BaseTexture;
  192. protected _lightmapTexture: BaseTexture;
  193. protected _ambientColor = new Color3(0, 0, 0);
  194. /**
  195. * AKA Diffuse Color in other nomenclature.
  196. */
  197. protected _albedoColor = new Color3(1, 1, 1);
  198. /**
  199. * AKA Specular Color in other nomenclature.
  200. */
  201. protected _reflectivityColor = new Color3(1, 1, 1);
  202. protected _reflectionColor = new Color3(1, 1, 1);
  203. protected _emissiveColor = new Color3(0, 0, 0);
  204. /**
  205. * AKA Glossiness in other nomenclature.
  206. */
  207. protected _microSurface = 0.9;
  208. /**
  209. * source material index of refraction (IOR)' / 'destination material IOR.
  210. */
  211. protected _indexOfRefraction = 0.66;
  212. /**
  213. * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
  214. */
  215. protected _invertRefractionY = false;
  216. /**
  217. * This parameters will make the material used its opacity to control how much it is refracting aginst not.
  218. * Materials half opaque for instance using refraction could benefit from this control.
  219. */
  220. protected _linkRefractionWithTransparency = false;
  221. protected _useLightmapAsShadowmap = false;
  222. /**
  223. * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal
  224. * makes the reflect vector face the model (under horizon).
  225. */
  226. protected _useHorizonOcclusion = true;
  227. /**
  228. * This parameters will enable/disable radiance occlusion by preventing the radiance to lit
  229. * too much the area relying on ambient texture to define their ambient occlusion.
  230. */
  231. protected _useRadianceOcclusion = true;
  232. /**
  233. * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.
  234. */
  235. protected _useAlphaFromAlbedoTexture = false;
  236. /**
  237. * Specifies that the material will keeps the specular highlights over a transparent surface (only the most limunous ones).
  238. * A car glass is a good exemple of that. When sun reflects on it you can not see what is behind.
  239. */
  240. protected _useSpecularOverAlpha = true;
  241. /**
  242. * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.
  243. */
  244. protected _useMicroSurfaceFromReflectivityMapAlpha = false;
  245. /**
  246. * Specifies if the metallic texture contains the roughness information in its alpha channel.
  247. */
  248. protected _useRoughnessFromMetallicTextureAlpha = true;
  249. /**
  250. * Specifies if the metallic texture contains the roughness information in its green channel.
  251. */
  252. protected _useRoughnessFromMetallicTextureGreen = false;
  253. /**
  254. * Specifies if the metallic texture contains the metallness information in its blue channel.
  255. */
  256. protected _useMetallnessFromMetallicTextureBlue = false;
  257. /**
  258. * Specifies if the metallic texture contains the ambient occlusion information in its red channel.
  259. */
  260. protected _useAmbientOcclusionFromMetallicTextureRed = false;
  261. /**
  262. * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.
  263. */
  264. protected _useAmbientInGrayScale = false;
  265. /**
  266. * In case the reflectivity map does not contain the microsurface information in its alpha channel,
  267. * The material will try to infer what glossiness each pixel should be.
  268. */
  269. protected _useAutoMicroSurfaceFromReflectivityMap = false;
  270. /**
  271. * BJS is using an harcoded light falloff based on a manually sets up range.
  272. * In PBR, one way to represents the fallof is to use the inverse squared root algorythm.
  273. * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.
  274. */
  275. protected _usePhysicalLightFalloff = true;
  276. /**
  277. * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most limunous ones).
  278. * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind.
  279. */
  280. protected _useRadianceOverAlpha = true;
  281. /**
  282. * Allows using an object space normal map (instead of tangent space).
  283. */
  284. protected _useObjectSpaceNormalMap = false;
  285. /**
  286. * Allows using the bump map in parallax mode.
  287. */
  288. protected _useParallax = false;
  289. /**
  290. * Allows using the bump map in parallax occlusion mode.
  291. */
  292. protected _useParallaxOcclusion = false;
  293. /**
  294. * Controls the scale bias of the parallax mode.
  295. */
  296. protected _parallaxScaleBias = 0.05;
  297. /**
  298. * If sets to true, disables all the lights affecting the material.
  299. */
  300. protected _disableLighting = false;
  301. /**
  302. * Number of Simultaneous lights allowed on the material.
  303. */
  304. protected _maxSimultaneousLights = 4;
  305. /**
  306. * If sets to true, x component of normal map value will be inverted (x = 1.0 - x).
  307. */
  308. protected _invertNormalMapX = false;
  309. /**
  310. * If sets to true, y component of normal map value will be inverted (y = 1.0 - y).
  311. */
  312. protected _invertNormalMapY = false;
  313. /**
  314. * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
  315. */
  316. protected _twoSidedLighting = false;
  317. /**
  318. * Defines the alpha limits in alpha test mode.
  319. */
  320. protected _alphaCutOff = 0.4;
  321. /**
  322. * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
  323. */
  324. protected _forceAlphaTest = false;
  325. /**
  326. * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
  327. * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)
  328. */
  329. protected _useAlphaFresnel = false;
  330. /**
  331. * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
  332. * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)
  333. */
  334. protected _useLinearAlphaFresnel = false;
  335. /**
  336. * The transparency mode of the material.
  337. */
  338. protected _transparencyMode: Nullable<number> = null;
  339. /**
  340. * Specifies the environment BRDF texture used to comput the scale and offset roughness values
  341. * from cos thetav and roughness:
  342. * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
  343. */
  344. protected _environmentBRDFTexture: Nullable<BaseTexture> = null;
  345. /**
  346. * Force the shader to compute irradiance in the fragment shader in order to take bump in account.
  347. */
  348. protected _forceIrradianceInFragment = false;
  349. /**
  350. * Force normal to face away from face.
  351. */
  352. protected _forceNormalForward = false;
  353. /**
  354. * Default configuration related to image processing available in the PBR Material.
  355. */
  356. @serializeAsImageProcessingConfiguration()
  357. protected _imageProcessingConfiguration: ImageProcessingConfiguration;
  358. /**
  359. * Keep track of the image processing observer to allow dispose and replace.
  360. */
  361. private _imageProcessingObserver: Nullable<Observer<ImageProcessingConfiguration>>;
  362. /**
  363. * Attaches a new image processing configuration to the PBR Material.
  364. * @param configuration
  365. */
  366. protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void {
  367. if (configuration === this._imageProcessingConfiguration) {
  368. return;
  369. }
  370. // Detaches observer.
  371. if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
  372. this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
  373. }
  374. // Pick the scene configuration if needed.
  375. if (!configuration) {
  376. this._imageProcessingConfiguration = this.getScene().imageProcessingConfiguration;
  377. }
  378. else {
  379. this._imageProcessingConfiguration = configuration;
  380. }
  381. // Attaches observer.
  382. this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(conf => {
  383. this._markAllSubMeshesAsImageProcessingDirty();
  384. });
  385. }
  386. private _renderTargets = new SmartArray<RenderTargetTexture>(16);
  387. private _globalAmbientColor = new Color3(0, 0, 0);
  388. private _useLogarithmicDepth: boolean;
  389. /**
  390. * Instantiates a new PBRMaterial instance.
  391. *
  392. * @param name The material name
  393. * @param scene The scene the material will be use in.
  394. */
  395. constructor(name: string, scene: Scene) {
  396. super(name, scene);
  397. // Setup the default processing configuration to the scene.
  398. this._attachImageProcessingConfiguration(null);
  399. this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
  400. this._renderTargets.reset();
  401. if (StandardMaterial.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
  402. this._renderTargets.push(<RenderTargetTexture>this._reflectionTexture);
  403. }
  404. if (StandardMaterial.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
  405. this._renderTargets.push(<RenderTargetTexture>this._refractionTexture);
  406. }
  407. return this._renderTargets;
  408. }
  409. this._environmentBRDFTexture = TextureTools.GetEnvironmentBRDFTexture(scene);
  410. }
  411. public getClassName(): string {
  412. return "PBRBaseMaterial";
  413. }
  414. @serialize()
  415. public get useLogarithmicDepth(): boolean {
  416. return this._useLogarithmicDepth;
  417. }
  418. public set useLogarithmicDepth(value: boolean) {
  419. this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
  420. }
  421. /**
  422. * Gets the current transparency mode.
  423. */
  424. @serialize()
  425. public get transparencyMode(): Nullable<number> {
  426. return this._transparencyMode;
  427. }
  428. /**
  429. * Sets the transparency mode of the material.
  430. */
  431. public set transparencyMode(value: Nullable<number>) {
  432. if (this._transparencyMode === value) {
  433. return;
  434. }
  435. this._transparencyMode = value;
  436. this._forceAlphaTest = (value === PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
  437. this._markAllSubMeshesAsTexturesDirty();
  438. }
  439. /**
  440. * Returns true if alpha blending should be disabled.
  441. */
  442. private get _disableAlphaBlending(): boolean {
  443. return (this._linkRefractionWithTransparency ||
  444. this._transparencyMode === PBRMaterial.PBRMATERIAL_OPAQUE ||
  445. this._transparencyMode === PBRMaterial.PBRMATERIAL_ALPHATEST);
  446. }
  447. /**
  448. * Specifies whether or not this material should be rendered in alpha blend mode.
  449. */
  450. public needAlphaBlending(): boolean {
  451. if (this._disableAlphaBlending) {
  452. return false;
  453. }
  454. return (this.alpha < 1.0) || (this._opacityTexture != null) || this._shouldUseAlphaFromAlbedoTexture();
  455. }
  456. /**
  457. * Specifies whether or not this material should be rendered in alpha blend mode for the given mesh.
  458. */
  459. public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
  460. if (this._disableAlphaBlending) {
  461. return false;
  462. }
  463. return super.needAlphaBlendingForMesh(mesh);
  464. }
  465. /**
  466. * Specifies whether or not this material should be rendered in alpha test mode.
  467. */
  468. public needAlphaTesting(): boolean {
  469. if (this._forceAlphaTest) {
  470. return true;
  471. }
  472. if (this._linkRefractionWithTransparency) {
  473. return false;
  474. }
  475. return this._albedoTexture != null && this._albedoTexture.hasAlpha && (this._transparencyMode == null || this._transparencyMode === PBRMaterial.PBRMATERIAL_ALPHATEST);
  476. }
  477. /**
  478. * Specifies whether or not the alpha value of the albedo texture should be used for alpha blending.
  479. */
  480. protected _shouldUseAlphaFromAlbedoTexture(): boolean {
  481. return this._albedoTexture != null && this._albedoTexture.hasAlpha && this._useAlphaFromAlbedoTexture && this._transparencyMode !== PBRMaterial.PBRMATERIAL_OPAQUE;
  482. }
  483. public getAlphaTestTexture(): BaseTexture {
  484. return this._albedoTexture;
  485. }
  486. private static _scaledReflectivity = new Color3();
  487. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
  488. if (subMesh.effect && this.isFrozen) {
  489. if (this._wasPreviouslyReady) {
  490. return true;
  491. }
  492. }
  493. if (!subMesh._materialDefines) {
  494. subMesh._materialDefines = new PBRMaterialDefines();
  495. }
  496. var scene = this.getScene();
  497. var defines = <PBRMaterialDefines>subMesh._materialDefines;
  498. if (!this.checkReadyOnEveryCall && subMesh.effect) {
  499. if (defines._renderId === scene.getRenderId()) {
  500. return true;
  501. }
  502. }
  503. var engine = scene.getEngine();
  504. // Lights
  505. MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
  506. defines._needNormals = true;
  507. // Textures
  508. if (defines._areTexturesDirty) {
  509. defines._needUVs = false;
  510. if (scene.texturesEnabled) {
  511. if (scene.getEngine().getCaps().textureLOD) {
  512. defines.LODBASEDMICROSFURACE = true;
  513. }
  514. if (this._albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
  515. if (!this._albedoTexture.isReadyOrNotBlocking()) {
  516. return false;
  517. }
  518. MaterialHelper.PrepareDefinesForMergedUV(this._albedoTexture, defines, "ALBEDO");
  519. } else {
  520. defines.ALBEDO = false;
  521. }
  522. if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
  523. if (!this._ambientTexture.isReadyOrNotBlocking()) {
  524. return false;
  525. }
  526. MaterialHelper.PrepareDefinesForMergedUV(this._ambientTexture, defines, "AMBIENT");
  527. defines.AMBIENTINGRAYSCALE = this._useAmbientInGrayScale;
  528. } else {
  529. defines.AMBIENT = false;
  530. }
  531. if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
  532. if (!this._opacityTexture.isReadyOrNotBlocking()) {
  533. return false;
  534. }
  535. MaterialHelper.PrepareDefinesForMergedUV(this._opacityTexture, defines, "OPACITY");
  536. defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;
  537. } else {
  538. defines.OPACITY = false;
  539. }
  540. var reflectionTexture = this._getReflectionTexture();
  541. if (reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
  542. if (!reflectionTexture.isReadyOrNotBlocking()) {
  543. return false;
  544. }
  545. defines.REFLECTION = true;
  546. defines.GAMMAREFLECTION = reflectionTexture.gammaSpace;
  547. defines.REFLECTIONMAP_OPPOSITEZ = this.getScene().useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ;
  548. defines.LODINREFLECTIONALPHA = reflectionTexture.lodLevelInAlpha;
  549. if (reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE) {
  550. defines.INVERTCUBICMAP = true;
  551. }
  552. defines.REFLECTIONMAP_3D = reflectionTexture.isCube;
  553. switch (reflectionTexture.coordinatesMode) {
  554. case Texture.CUBIC_MODE:
  555. case Texture.INVCUBIC_MODE:
  556. defines.REFLECTIONMAP_CUBIC = true;
  557. break;
  558. case Texture.EXPLICIT_MODE:
  559. defines.REFLECTIONMAP_EXPLICIT = true;
  560. break;
  561. case Texture.PLANAR_MODE:
  562. defines.REFLECTIONMAP_PLANAR = true;
  563. break;
  564. case Texture.PROJECTION_MODE:
  565. defines.REFLECTIONMAP_PROJECTION = true;
  566. break;
  567. case Texture.SKYBOX_MODE:
  568. defines.REFLECTIONMAP_SKYBOX = true;
  569. break;
  570. case Texture.SPHERICAL_MODE:
  571. defines.REFLECTIONMAP_SPHERICAL = true;
  572. break;
  573. case Texture.EQUIRECTANGULAR_MODE:
  574. defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
  575. break;
  576. case Texture.FIXED_EQUIRECTANGULAR_MODE:
  577. defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
  578. break;
  579. case Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
  580. defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = true;
  581. break;
  582. }
  583. if (reflectionTexture.coordinatesMode !== BABYLON.Texture.SKYBOX_MODE) {
  584. if (reflectionTexture.sphericalPolynomial) {
  585. defines.USESPHERICALFROMREFLECTIONMAP = true;
  586. if (this._forceIrradianceInFragment || scene.getEngine().getCaps().maxVaryingVectors <= 8) {
  587. defines.USESPHERICALINVERTEX = false;
  588. }
  589. else {
  590. defines.USESPHERICALINVERTEX = true;
  591. }
  592. }
  593. }
  594. } else {
  595. defines.REFLECTION = false;
  596. defines.REFLECTIONMAP_3D = false;
  597. defines.REFLECTIONMAP_SPHERICAL = false;
  598. defines.REFLECTIONMAP_PLANAR = false;
  599. defines.REFLECTIONMAP_CUBIC = false;
  600. defines.REFLECTIONMAP_PROJECTION = false;
  601. defines.REFLECTIONMAP_SKYBOX = false;
  602. defines.REFLECTIONMAP_EXPLICIT = false;
  603. defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
  604. defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
  605. defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
  606. defines.INVERTCUBICMAP = false;
  607. defines.USESPHERICALFROMREFLECTIONMAP = false;
  608. defines.USESPHERICALINVERTEX = false;
  609. defines.REFLECTIONMAP_OPPOSITEZ = false;
  610. defines.LODINREFLECTIONALPHA = false;
  611. defines.GAMMAREFLECTION = false;
  612. }
  613. if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
  614. if (!this._lightmapTexture.isReadyOrNotBlocking()) {
  615. return false;
  616. }
  617. MaterialHelper.PrepareDefinesForMergedUV(this._lightmapTexture, defines, "LIGHTMAP");
  618. defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;
  619. } else {
  620. defines.LIGHTMAP = false;
  621. }
  622. if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
  623. if (!this._emissiveTexture.isReadyOrNotBlocking()) {
  624. return false;
  625. }
  626. MaterialHelper.PrepareDefinesForMergedUV(this._emissiveTexture, defines, "EMISSIVE");
  627. } else {
  628. defines.EMISSIVE = false;
  629. }
  630. if (StandardMaterial.SpecularTextureEnabled) {
  631. if (this._metallicTexture) {
  632. if (!this._metallicTexture.isReadyOrNotBlocking()) {
  633. return false;
  634. }
  635. MaterialHelper.PrepareDefinesForMergedUV(this._metallicTexture, defines, "REFLECTIVITY");
  636. defines.METALLICWORKFLOW = true;
  637. defines.ROUGHNESSSTOREINMETALMAPALPHA = this._useRoughnessFromMetallicTextureAlpha;
  638. defines.ROUGHNESSSTOREINMETALMAPGREEN = !this._useRoughnessFromMetallicTextureAlpha && this._useRoughnessFromMetallicTextureGreen;
  639. defines.METALLNESSSTOREINMETALMAPBLUE = this._useMetallnessFromMetallicTextureBlue;
  640. defines.AOSTOREINMETALMAPRED = this._useAmbientOcclusionFromMetallicTextureRed;
  641. }
  642. else if (this._reflectivityTexture) {
  643. if (!this._reflectivityTexture.isReadyOrNotBlocking()) {
  644. return false;
  645. }
  646. defines.METALLICWORKFLOW = false;
  647. MaterialHelper.PrepareDefinesForMergedUV(this._reflectivityTexture, defines, "REFLECTIVITY");
  648. defines.MICROSURFACEFROMREFLECTIVITYMAP = this._useMicroSurfaceFromReflectivityMapAlpha;
  649. defines.MICROSURFACEAUTOMATIC = this._useAutoMicroSurfaceFromReflectivityMap;
  650. } else {
  651. defines.METALLICWORKFLOW = false;
  652. defines.REFLECTIVITY = false;
  653. }
  654. if (this._microSurfaceTexture) {
  655. if (!this._microSurfaceTexture.isReadyOrNotBlocking()) {
  656. return false;
  657. }
  658. MaterialHelper.PrepareDefinesForMergedUV(this._microSurfaceTexture, defines, "MICROSURFACEMAP");
  659. } else {
  660. defines.MICROSURFACEMAP = false;
  661. }
  662. } else {
  663. defines.REFLECTIVITY = false;
  664. defines.MICROSURFACEMAP = false;
  665. }
  666. if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) {
  667. // Bump texure can not be none blocking.
  668. if (!this._bumpTexture.isReady()) {
  669. return false;
  670. }
  671. MaterialHelper.PrepareDefinesForMergedUV(this._bumpTexture, defines, "BUMP");
  672. if (this._useParallax && this._albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
  673. defines.PARALLAX = true;
  674. defines.PARALLAXOCCLUSION = !!this._useParallaxOcclusion;
  675. }
  676. else {
  677. defines.PARALLAX = false;
  678. }
  679. defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;
  680. } else {
  681. defines.BUMP = false;
  682. }
  683. var refractionTexture = this._getRefractionTexture();
  684. if (refractionTexture && StandardMaterial.RefractionTextureEnabled) {
  685. if (!refractionTexture.isReadyOrNotBlocking()) {
  686. return false;
  687. }
  688. defines.REFRACTION = true;
  689. defines.REFRACTIONMAP_3D = refractionTexture.isCube;
  690. defines.GAMMAREFRACTION = refractionTexture.gammaSpace;
  691. defines.REFRACTIONMAP_OPPOSITEZ = reflectionTexture.invertZ;
  692. defines.LODINREFRACTIONALPHA = reflectionTexture.lodLevelInAlpha;
  693. if (this._linkRefractionWithTransparency) {
  694. defines.LINKREFRACTIONTOTRANSPARENCY = true;
  695. }
  696. } else {
  697. defines.REFRACTION = false;
  698. }
  699. if (this._environmentBRDFTexture && StandardMaterial.ReflectionTextureEnabled) {
  700. // This is blocking.
  701. if (!this._environmentBRDFTexture.isReady()) {
  702. return false;
  703. }
  704. defines.ENVIRONMENTBRDF = true;
  705. } else {
  706. defines.ENVIRONMENTBRDF = false;
  707. }
  708. if (this._shouldUseAlphaFromAlbedoTexture()) {
  709. defines.ALPHAFROMALBEDO = true;
  710. } else {
  711. defines.ALPHAFROMALBEDO = false;
  712. }
  713. }
  714. defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
  715. defines.USEPHYSICALLIGHTFALLOFF = this._usePhysicalLightFalloff;
  716. defines.RADIANCEOVERALPHA = this._useRadianceOverAlpha;
  717. if ((this._metallic !== undefined && this._metallic !== null) || (this._roughness !== undefined && this._roughness !== null)) {
  718. defines.METALLICWORKFLOW = true;
  719. } else {
  720. defines.METALLICWORKFLOW = false;
  721. }
  722. if (!this.backFaceCulling && this._twoSidedLighting) {
  723. defines.TWOSIDEDLIGHTING = true;
  724. } else {
  725. defines.TWOSIDEDLIGHTING = false;
  726. }
  727. defines.ALPHATESTVALUE = this._alphaCutOff;
  728. defines.PREMULTIPLYALPHA = (this.alphaMode === Engine.ALPHA_PREMULTIPLIED || this.alphaMode === Engine.ALPHA_PREMULTIPLIED_PORTERDUFF);
  729. defines.ALPHABLEND = this.needAlphaBlendingForMesh(mesh);
  730. defines.ALPHAFRESNEL = this._useAlphaFresnel || this._useLinearAlphaFresnel;
  731. defines.LINEARALPHAFRESNEL = this._useLinearAlphaFresnel;
  732. }
  733. if (defines._areImageProcessingDirty) {
  734. if (!this._imageProcessingConfiguration.isReady()) {
  735. return false;
  736. }
  737. this._imageProcessingConfiguration.prepareDefines(defines);
  738. }
  739. defines.FORCENORMALFORWARD = this._forceNormalForward;
  740. defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
  741. defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
  742. // Misc.
  743. MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
  744. // Values that need to be evaluated on every frame
  745. MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._forceAlphaTest);
  746. // Attribs
  747. if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {
  748. let bufferMesh = null;
  749. if (mesh instanceof InstancedMesh) {
  750. bufferMesh = (mesh as InstancedMesh).sourceMesh;
  751. }
  752. else if (mesh instanceof Mesh) {
  753. bufferMesh = mesh as Mesh;
  754. }
  755. if (bufferMesh) {
  756. if (bufferMesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
  757. // If the first normal's components is the zero vector in one of the submeshes, we have invalid normals
  758. let normalVertexBuffer = bufferMesh.getVertexBuffer(VertexBuffer.NormalKind);
  759. let normals = normalVertexBuffer!.getData();
  760. let vertexBufferOffset = normalVertexBuffer!.getOffset();
  761. let strideSize = normalVertexBuffer!.getStrideSize();
  762. let offset = vertexBufferOffset + subMesh.indexStart * strideSize;
  763. if (normals![offset] === 0 && normals![offset + 1] === 0 && normals![offset + 2] === 0) {
  764. defines.NORMAL = false;
  765. }
  766. if (bufferMesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
  767. // If the first tangent's components is the zero vector in one of the submeshes, we have invalid tangents
  768. let tangentVertexBuffer = bufferMesh.getVertexBuffer(VertexBuffer.TangentKind);
  769. let tangents = tangentVertexBuffer!.getData();
  770. let vertexBufferOffset = tangentVertexBuffer!.getOffset();
  771. let strideSize = tangentVertexBuffer!.getStrideSize();
  772. let offset = vertexBufferOffset + subMesh.indexStart * strideSize;
  773. if (tangents![offset] === 0 && tangents![offset + 1] === 0 && tangents![offset + 2] === 0) {
  774. defines.TANGENT = false;
  775. }
  776. }
  777. }
  778. else {
  779. if (!scene.getEngine().getCaps().standardDerivatives) {
  780. bufferMesh.createNormals(true);
  781. Tools.Warn("PBRMaterial: Normals have been created for the mesh: " + bufferMesh.name);
  782. }
  783. }
  784. }
  785. }
  786. // Get correct effect
  787. if (defines.isDirty) {
  788. defines.markAsProcessed();
  789. scene.resetCachedMaterial();
  790. // Fallbacks
  791. var fallbacks = new EffectFallbacks();
  792. var fallbackRank = 0;
  793. if (defines.USESPHERICALINVERTEX) {
  794. fallbacks.addFallback(fallbackRank++, "USESPHERICALINVERTEX");
  795. }
  796. if (defines.FOG) {
  797. fallbacks.addFallback(fallbackRank, "FOG");
  798. }
  799. if (defines.POINTSIZE) {
  800. fallbacks.addFallback(fallbackRank, "POINTSIZE");
  801. }
  802. if (defines.LOGARITHMICDEPTH) {
  803. fallbacks.addFallback(fallbackRank, "LOGARITHMICDEPTH");
  804. }
  805. if (defines.PARALLAX) {
  806. fallbacks.addFallback(fallbackRank, "PARALLAX");
  807. }
  808. if (defines.PARALLAXOCCLUSION) {
  809. fallbacks.addFallback(fallbackRank++, "PARALLAXOCCLUSION");
  810. }
  811. if (defines.ENVIRONMENTBRDF) {
  812. fallbacks.addFallback(fallbackRank++, "ENVIRONMENTBRDF");
  813. }
  814. if (defines.TANGENT) {
  815. fallbacks.addFallback(fallbackRank++, "TANGENT");
  816. }
  817. if (defines.BUMP) {
  818. fallbacks.addFallback(fallbackRank++, "BUMP");
  819. }
  820. fallbackRank = MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank++);
  821. if (defines.SPECULARTERM) {
  822. fallbacks.addFallback(fallbackRank++, "SPECULARTERM");
  823. }
  824. if (defines.USESPHERICALFROMREFLECTIONMAP) {
  825. fallbacks.addFallback(fallbackRank++, "USESPHERICALFROMREFLECTIONMAP");
  826. }
  827. if (defines.LIGHTMAP) {
  828. fallbacks.addFallback(fallbackRank++, "LIGHTMAP");
  829. }
  830. if (defines.NORMAL) {
  831. fallbacks.addFallback(fallbackRank++, "NORMAL");
  832. }
  833. if (defines.AMBIENT) {
  834. fallbacks.addFallback(fallbackRank++, "AMBIENT");
  835. }
  836. if (defines.EMISSIVE) {
  837. fallbacks.addFallback(fallbackRank++, "EMISSIVE");
  838. }
  839. if (defines.VERTEXCOLOR) {
  840. fallbacks.addFallback(fallbackRank++, "VERTEXCOLOR");
  841. }
  842. if (defines.NUM_BONE_INFLUENCERS > 0) {
  843. fallbacks.addCPUSkinningFallback(fallbackRank++, mesh);
  844. }
  845. if (defines.MORPHTARGETS) {
  846. fallbacks.addFallback(fallbackRank++, "MORPHTARGETS");
  847. }
  848. //Attributes
  849. var attribs = [VertexBuffer.PositionKind];
  850. if (defines.NORMAL) {
  851. attribs.push(VertexBuffer.NormalKind);
  852. }
  853. if (defines.TANGENT) {
  854. attribs.push(VertexBuffer.TangentKind);
  855. }
  856. if (defines.UV1) {
  857. attribs.push(VertexBuffer.UVKind);
  858. }
  859. if (defines.UV2) {
  860. attribs.push(VertexBuffer.UV2Kind);
  861. }
  862. if (defines.VERTEXCOLOR) {
  863. attribs.push(VertexBuffer.ColorKind);
  864. }
  865. MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
  866. MaterialHelper.PrepareAttributesForInstances(attribs, defines);
  867. MaterialHelper.PrepareAttributesForMorphTargets(attribs, mesh, defines);
  868. var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vAlbedoColor", "vReflectivityColor", "vEmissiveColor", "vReflectionColor",
  869. "vFogInfos", "vFogColor", "pointSize",
  870. "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vReflectivityInfos", "vMicroSurfaceSamplerInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
  871. "mBones",
  872. "vClipPlane", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "normalMatrix", "microSurfaceSamplerMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
  873. "vLightingIntensity",
  874. "logarithmicDepthConstant",
  875. "vSphericalX", "vSphericalY", "vSphericalZ",
  876. "vSphericalXX", "vSphericalYY", "vSphericalZZ",
  877. "vSphericalXY", "vSphericalYZ", "vSphericalZX",
  878. "vReflectionMicrosurfaceInfos", "vRefractionMicrosurfaceInfos",
  879. "vTangentSpaceParams"
  880. ];
  881. var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
  882. "bumpSampler", "lightmapSampler", "opacitySampler",
  883. "refractionSampler", "refractionSamplerLow", "refractionSamplerHigh",
  884. "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh",
  885. "microSurfaceSampler", "environmentBrdfSampler"];
  886. var uniformBuffers = ["Material", "Scene"];
  887. ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
  888. ImageProcessingConfiguration.PrepareSamplers(samplers, defines);
  889. MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
  890. uniformsNames: uniforms,
  891. uniformBuffersNames: uniformBuffers,
  892. samplers: samplers,
  893. defines: defines,
  894. maxSimultaneousLights: this._maxSimultaneousLights
  895. });
  896. var onCompiled = (effect: Effect) => {
  897. if (this.onCompiled) {
  898. this.onCompiled(effect);
  899. }
  900. this.bindSceneUniformBuffer(effect, scene.getSceneUniformBuffer());
  901. };
  902. var join = defines.toString();
  903. subMesh.setEffect(scene.getEngine().createEffect("pbr", <EffectCreationOptions>{
  904. attributes: attribs,
  905. uniformsNames: uniforms,
  906. uniformBuffersNames: uniformBuffers,
  907. samplers: samplers,
  908. defines: join,
  909. fallbacks: fallbacks,
  910. onCompiled: onCompiled,
  911. onError: this.onError,
  912. indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS }
  913. }, engine), defines);
  914. this.buildUniformLayout();
  915. }
  916. if (!subMesh.effect || !subMesh.effect.isReady()) {
  917. return false;
  918. }
  919. defines._renderId = scene.getRenderId();
  920. this._wasPreviouslyReady = true;
  921. return true;
  922. }
  923. public buildUniformLayout(): void {
  924. // Order is important !
  925. this._uniformBuffer.addUniform("vAlbedoInfos", 2);
  926. this._uniformBuffer.addUniform("vAmbientInfos", 3);
  927. this._uniformBuffer.addUniform("vOpacityInfos", 2);
  928. this._uniformBuffer.addUniform("vEmissiveInfos", 2);
  929. this._uniformBuffer.addUniform("vLightmapInfos", 2);
  930. this._uniformBuffer.addUniform("vReflectivityInfos", 3);
  931. this._uniformBuffer.addUniform("vMicroSurfaceSamplerInfos", 2);
  932. this._uniformBuffer.addUniform("vRefractionInfos", 4);
  933. this._uniformBuffer.addUniform("vReflectionInfos", 2);
  934. this._uniformBuffer.addUniform("vBumpInfos", 3);
  935. this._uniformBuffer.addUniform("albedoMatrix", 16);
  936. this._uniformBuffer.addUniform("ambientMatrix", 16);
  937. this._uniformBuffer.addUniform("opacityMatrix", 16);
  938. this._uniformBuffer.addUniform("emissiveMatrix", 16);
  939. this._uniformBuffer.addUniform("lightmapMatrix", 16);
  940. this._uniformBuffer.addUniform("reflectivityMatrix", 16);
  941. this._uniformBuffer.addUniform("microSurfaceSamplerMatrix", 16);
  942. this._uniformBuffer.addUniform("bumpMatrix", 16);
  943. this._uniformBuffer.addUniform("vTangentSpaceParams", 2);
  944. this._uniformBuffer.addUniform("refractionMatrix", 16);
  945. this._uniformBuffer.addUniform("reflectionMatrix", 16);
  946. this._uniformBuffer.addUniform("vReflectionColor", 3);
  947. this._uniformBuffer.addUniform("vAlbedoColor", 4);
  948. this._uniformBuffer.addUniform("vLightingIntensity", 4);
  949. this._uniformBuffer.addUniform("vRefractionMicrosurfaceInfos", 3);
  950. this._uniformBuffer.addUniform("vReflectionMicrosurfaceInfos", 3);
  951. this._uniformBuffer.addUniform("vReflectivityColor", 4);
  952. this._uniformBuffer.addUniform("vEmissiveColor", 3);
  953. this._uniformBuffer.addUniform("pointSize", 1);
  954. this._uniformBuffer.create();
  955. }
  956. public unbind(): void {
  957. if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
  958. this._uniformBuffer.setTexture("reflectionSampler", null);
  959. }
  960. if (this._refractionTexture && this._refractionTexture.isRenderTarget) {
  961. this._uniformBuffer.setTexture("refractionSampler", null);
  962. }
  963. super.unbind();
  964. }
  965. public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
  966. var scene = this.getScene();
  967. var defines = <PBRMaterialDefines>subMesh._materialDefines;
  968. if (!defines) {
  969. return;
  970. }
  971. var effect = subMesh.effect;
  972. if (!effect) {
  973. return;
  974. }
  975. this._activeEffect = effect;
  976. // Matrices
  977. this.bindOnlyWorldMatrix(world);
  978. // Normal Matrix
  979. if (defines.OBJECTSPACE_NORMALMAP)
  980. {
  981. var normalMatrix = world.toNormalMatrix();
  982. this.bindOnlyNormalMatrix(normalMatrix);
  983. }
  984. let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
  985. // Bones
  986. MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
  987. let reflectionTexture: Nullable<BaseTexture> = null;
  988. if (mustRebind) {
  989. this._uniformBuffer.bindToEffect(effect, "Material");
  990. this.bindViewProjection(effect);
  991. reflectionTexture = this._getReflectionTexture();
  992. var refractionTexture = this._getRefractionTexture();
  993. if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync) {
  994. // Texture uniforms
  995. if (scene.texturesEnabled) {
  996. if (this._albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
  997. this._uniformBuffer.updateFloat2("vAlbedoInfos", this._albedoTexture.coordinatesIndex, this._albedoTexture.level);
  998. MaterialHelper.BindTextureMatrix(this._albedoTexture, this._uniformBuffer, "albedo");
  999. }
  1000. if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
  1001. this._uniformBuffer.updateFloat3("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level, this._ambientTextureStrength);
  1002. MaterialHelper.BindTextureMatrix(this._ambientTexture, this._uniformBuffer, "ambient");
  1003. }
  1004. if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
  1005. this._uniformBuffer.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
  1006. MaterialHelper.BindTextureMatrix(this._opacityTexture, this._uniformBuffer, "opacity");
  1007. }
  1008. if (reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
  1009. this._uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
  1010. this._uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
  1011. var polynomials = reflectionTexture.sphericalPolynomial;
  1012. if (defines.USESPHERICALFROMREFLECTIONMAP && polynomials) {
  1013. this._activeEffect.setFloat3("vSphericalX", polynomials.x.x, polynomials.x.y, polynomials.x.z);
  1014. this._activeEffect.setFloat3("vSphericalY", polynomials.y.x, polynomials.y.y, polynomials.y.z);
  1015. this._activeEffect.setFloat3("vSphericalZ", polynomials.z.x, polynomials.z.y, polynomials.z.z);
  1016. this._activeEffect.setFloat3("vSphericalXX_ZZ", polynomials.xx.x - polynomials.zz.x,
  1017. polynomials.xx.y - polynomials.zz.y,
  1018. polynomials.xx.z - polynomials.zz.z);
  1019. this._activeEffect.setFloat3("vSphericalYY_ZZ", polynomials.yy.x - polynomials.zz.x,
  1020. polynomials.yy.y - polynomials.zz.y,
  1021. polynomials.yy.z - polynomials.zz.z);
  1022. this._activeEffect.setFloat3("vSphericalZZ", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z);
  1023. this._activeEffect.setFloat3("vSphericalXY", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z);
  1024. this._activeEffect.setFloat3("vSphericalYZ", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z);
  1025. this._activeEffect.setFloat3("vSphericalZX", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);
  1026. }
  1027. this._uniformBuffer.updateFloat3("vReflectionMicrosurfaceInfos",
  1028. reflectionTexture.getSize().width,
  1029. reflectionTexture.lodGenerationScale,
  1030. reflectionTexture.lodGenerationOffset);
  1031. }
  1032. if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
  1033. this._uniformBuffer.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
  1034. MaterialHelper.BindTextureMatrix(this._emissiveTexture, this._uniformBuffer, "emissive");
  1035. }
  1036. if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
  1037. this._uniformBuffer.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
  1038. MaterialHelper.BindTextureMatrix(this._lightmapTexture, this._uniformBuffer, "lightmap");
  1039. }
  1040. if (StandardMaterial.SpecularTextureEnabled) {
  1041. if (this._metallicTexture) {
  1042. this._uniformBuffer.updateFloat3("vReflectivityInfos", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength);
  1043. MaterialHelper.BindTextureMatrix(this._metallicTexture, this._uniformBuffer, "reflectivity");
  1044. }
  1045. else if (this._reflectivityTexture) {
  1046. this._uniformBuffer.updateFloat3("vReflectivityInfos", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0);
  1047. MaterialHelper.BindTextureMatrix(this._reflectivityTexture, this._uniformBuffer, "reflectivity");
  1048. }
  1049. if (this._microSurfaceTexture) {
  1050. this._uniformBuffer.updateFloat2("vMicroSurfaceSamplerInfos", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level);
  1051. MaterialHelper.BindTextureMatrix(this._microSurfaceTexture, this._uniformBuffer, "microSurfaceSampler");
  1052. }
  1053. }
  1054. if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) {
  1055. this._uniformBuffer.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias);
  1056. MaterialHelper.BindTextureMatrix(this._bumpTexture, this._uniformBuffer, "bump");
  1057. if (scene._mirroredCameraPosition) {
  1058. this._uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
  1059. } else {
  1060. this._uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
  1061. }
  1062. }
  1063. if (refractionTexture && StandardMaterial.RefractionTextureEnabled) {
  1064. this._uniformBuffer.updateMatrix("refractionMatrix", refractionTexture.getReflectionTextureMatrix());
  1065. var depth = 1.0;
  1066. if (!refractionTexture.isCube) {
  1067. if ((<any>refractionTexture).depth) {
  1068. depth = (<any>refractionTexture).depth;
  1069. }
  1070. }
  1071. this._uniformBuffer.updateFloat4("vRefractionInfos", refractionTexture.level, this._indexOfRefraction, depth, this._invertRefractionY ? -1 : 1);
  1072. this._uniformBuffer.updateFloat3("vRefractionMicrosurfaceInfos",
  1073. refractionTexture.getSize().width,
  1074. refractionTexture.lodGenerationScale,
  1075. refractionTexture.lodGenerationOffset);
  1076. }
  1077. }
  1078. // Point size
  1079. if (this.pointsCloud) {
  1080. this._uniformBuffer.updateFloat("pointSize", this.pointSize);
  1081. }
  1082. // Colors
  1083. if (defines.METALLICWORKFLOW) {
  1084. PBRMaterial._scaledReflectivity.r = (this._metallic === undefined || this._metallic === null) ? 1 : this._metallic;
  1085. PBRMaterial._scaledReflectivity.g = (this._roughness === undefined || this._roughness === null) ? 1 : this._roughness;
  1086. this._uniformBuffer.updateColor4("vReflectivityColor", PBRMaterial._scaledReflectivity, 0);
  1087. }
  1088. else {
  1089. this._uniformBuffer.updateColor4("vReflectivityColor", this._reflectivityColor, this._microSurface);
  1090. }
  1091. this._uniformBuffer.updateColor3("vEmissiveColor", this._emissiveColor);
  1092. this._uniformBuffer.updateColor3("vReflectionColor", this._reflectionColor);
  1093. this._uniformBuffer.updateColor4("vAlbedoColor", this._albedoColor, this.alpha * mesh.visibility);
  1094. // Misc
  1095. this._lightingInfos.x = this._directIntensity;
  1096. this._lightingInfos.y = this._emissiveIntensity;
  1097. this._lightingInfos.z = this._environmentIntensity;
  1098. this._lightingInfos.w = this._specularIntensity;
  1099. this._uniformBuffer.updateVector4("vLightingIntensity", this._lightingInfos);
  1100. }
  1101. // Textures
  1102. if (scene.texturesEnabled) {
  1103. if (this._albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
  1104. this._uniformBuffer.setTexture("albedoSampler", this._albedoTexture);
  1105. }
  1106. if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
  1107. this._uniformBuffer.setTexture("ambientSampler", this._ambientTexture);
  1108. }
  1109. if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
  1110. this._uniformBuffer.setTexture("opacitySampler", this._opacityTexture);
  1111. }
  1112. if (reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
  1113. if (defines.LODBASEDMICROSFURACE) {
  1114. this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
  1115. }
  1116. else {
  1117. this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
  1118. this._uniformBuffer.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
  1119. this._uniformBuffer.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
  1120. }
  1121. }
  1122. if (defines.ENVIRONMENTBRDF) {
  1123. this._uniformBuffer.setTexture("environmentBrdfSampler", this._environmentBRDFTexture);
  1124. }
  1125. if (refractionTexture && StandardMaterial.RefractionTextureEnabled) {
  1126. if (defines.LODBASEDMICROSFURACE) {
  1127. this._uniformBuffer.setTexture("refractionSampler", refractionTexture);
  1128. }
  1129. else {
  1130. this._uniformBuffer.setTexture("refractionSampler", refractionTexture._lodTextureMid || refractionTexture);
  1131. this._uniformBuffer.setTexture("refractionSamplerLow", refractionTexture._lodTextureLow || refractionTexture);
  1132. this._uniformBuffer.setTexture("refractionSamplerHigh", refractionTexture._lodTextureHigh || refractionTexture);
  1133. }
  1134. }
  1135. if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
  1136. this._uniformBuffer.setTexture("emissiveSampler", this._emissiveTexture);
  1137. }
  1138. if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
  1139. this._uniformBuffer.setTexture("lightmapSampler", this._lightmapTexture);
  1140. }
  1141. if (StandardMaterial.SpecularTextureEnabled) {
  1142. if (this._metallicTexture) {
  1143. this._uniformBuffer.setTexture("reflectivitySampler", this._metallicTexture);
  1144. }
  1145. else if (this._reflectivityTexture) {
  1146. this._uniformBuffer.setTexture("reflectivitySampler", this._reflectivityTexture);
  1147. }
  1148. if (this._microSurfaceTexture) {
  1149. this._uniformBuffer.setTexture("microSurfaceSampler", this._microSurfaceTexture);
  1150. }
  1151. }
  1152. if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) {
  1153. this._uniformBuffer.setTexture("bumpSampler", this._bumpTexture);
  1154. }
  1155. }
  1156. // Clip plane
  1157. MaterialHelper.BindClipPlane(this._activeEffect, scene);
  1158. // Colors
  1159. scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor);
  1160. var eyePosition = scene._forcedViewPosition ? scene._forcedViewPosition : (scene._mirroredCameraPosition ? scene._mirroredCameraPosition : (<Camera>scene.activeCamera).globalPosition);
  1161. var invertNormal = (scene.useRightHandedSystem === (scene._mirroredCameraPosition != null));
  1162. effect.setFloat4("vEyePosition",
  1163. eyePosition.x,
  1164. eyePosition.y,
  1165. eyePosition.z,
  1166. invertNormal ? -1 : 1);
  1167. effect.setColor3("vAmbientColor", this._globalAmbientColor);
  1168. }
  1169. if (mustRebind || !this.isFrozen) {
  1170. // Lights
  1171. if (scene.lightsEnabled && !this._disableLighting) {
  1172. MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights, this._usePhysicalLightFalloff);
  1173. }
  1174. // View
  1175. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || reflectionTexture) {
  1176. this.bindView(effect);
  1177. }
  1178. // Fog
  1179. MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
  1180. // Morph targets
  1181. if (defines.NUM_MORPH_INFLUENCERS) {
  1182. MaterialHelper.BindMorphTargetParameters(mesh, this._activeEffect);
  1183. }
  1184. // image processing
  1185. this._imageProcessingConfiguration.bind(this._activeEffect);
  1186. // Log. depth
  1187. MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
  1188. }
  1189. this._uniformBuffer.update();
  1190. this._afterBind(mesh);
  1191. }
  1192. public getAnimatables(): IAnimatable[] {
  1193. var results = [];
  1194. if (this._albedoTexture && this._albedoTexture.animations && this._albedoTexture.animations.length > 0) {
  1195. results.push(this._albedoTexture);
  1196. }
  1197. if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {
  1198. results.push(this._ambientTexture);
  1199. }
  1200. if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {
  1201. results.push(this._opacityTexture);
  1202. }
  1203. if (this._reflectionTexture && this._reflectionTexture.animations && this._reflectionTexture.animations.length > 0) {
  1204. results.push(this._reflectionTexture);
  1205. }
  1206. if (this._emissiveTexture && this._emissiveTexture.animations && this._emissiveTexture.animations.length > 0) {
  1207. results.push(this._emissiveTexture);
  1208. }
  1209. if (this._metallicTexture && this._metallicTexture.animations && this._metallicTexture.animations.length > 0) {
  1210. results.push(this._metallicTexture);
  1211. }
  1212. else if (this._reflectivityTexture && this._reflectivityTexture.animations && this._reflectivityTexture.animations.length > 0) {
  1213. results.push(this._reflectivityTexture);
  1214. }
  1215. if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {
  1216. results.push(this._bumpTexture);
  1217. }
  1218. if (this._lightmapTexture && this._lightmapTexture.animations && this._lightmapTexture.animations.length > 0) {
  1219. results.push(this._lightmapTexture);
  1220. }
  1221. if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) {
  1222. results.push(this._refractionTexture);
  1223. }
  1224. return results;
  1225. }
  1226. private _getReflectionTexture(): BaseTexture {
  1227. if (this._reflectionTexture) {
  1228. return this._reflectionTexture;
  1229. }
  1230. return this.getScene().environmentTexture;
  1231. }
  1232. private _getRefractionTexture(): Nullable<BaseTexture> {
  1233. if (this._refractionTexture) {
  1234. return this._refractionTexture;
  1235. }
  1236. if (this._linkRefractionWithTransparency) {
  1237. return this.getScene().environmentTexture;
  1238. }
  1239. return null;
  1240. }
  1241. public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {
  1242. if (forceDisposeTextures) {
  1243. if (this._albedoTexture) {
  1244. this._albedoTexture.dispose();
  1245. }
  1246. if (this._ambientTexture) {
  1247. this._ambientTexture.dispose();
  1248. }
  1249. if (this._opacityTexture) {
  1250. this._opacityTexture.dispose();
  1251. }
  1252. if (this._reflectionTexture) {
  1253. this._reflectionTexture.dispose();
  1254. }
  1255. if (this._environmentBRDFTexture && this.getScene()._environmentBRDFTexture !== this._environmentBRDFTexture) {
  1256. this._environmentBRDFTexture.dispose();
  1257. }
  1258. if (this._emissiveTexture) {
  1259. this._emissiveTexture.dispose();
  1260. }
  1261. if (this._metallicTexture) {
  1262. this._metallicTexture.dispose();
  1263. }
  1264. if (this._reflectivityTexture) {
  1265. this._reflectivityTexture.dispose();
  1266. }
  1267. if (this._bumpTexture) {
  1268. this._bumpTexture.dispose();
  1269. }
  1270. if (this._lightmapTexture) {
  1271. this._lightmapTexture.dispose();
  1272. }
  1273. if (this._refractionTexture) {
  1274. this._refractionTexture.dispose();
  1275. }
  1276. }
  1277. this._renderTargets.dispose();
  1278. if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
  1279. this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
  1280. }
  1281. super.dispose(forceDisposeEffect, forceDisposeTextures);
  1282. }
  1283. }
  1284. }