pbrBaseMaterial.ts 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308
  1. import { serialize, serializeAsImageProcessingConfiguration, expandToProperty } from "../../Misc/decorators";
  2. import { Observer } from "../../Misc/observable";
  3. import { Logger } from "../../Misc/logger";
  4. import { SmartArray } from "../../Misc/smartArray";
  5. import { BRDFTextureTools } from "../../Misc/brdfTextureTools";
  6. import { Nullable } from "../../types";
  7. import { Camera } from "../../Cameras/camera";
  8. import { Scene } from "../../scene";
  9. import { Matrix, Vector4 } from "../../Maths/math.vector";
  10. import { VertexBuffer } from "../../Meshes/buffer";
  11. import { SubMesh } from "../../Meshes/subMesh";
  12. import { AbstractMesh } from "../../Meshes/abstractMesh";
  13. import { Mesh } from "../../Meshes/mesh";
  14. import { IMaterialClearCoatDefines, PBRClearCoatConfiguration } from "./pbrClearCoatConfiguration";
  15. import { IMaterialAnisotropicDefines, PBRAnisotropicConfiguration } from "./pbrAnisotropicConfiguration";
  16. import { IMaterialBRDFDefines, PBRBRDFConfiguration } from "./pbrBRDFConfiguration";
  17. import { IMaterialSheenDefines, PBRSheenConfiguration } from "./pbrSheenConfiguration";
  18. import { IMaterialSubSurfaceDefines, PBRSubSurfaceConfiguration } from "./pbrSubSurfaceConfiguration";
  19. import { PrePassConfiguration } from "../PrePassConfiguration";
  20. import { Color3, TmpColors } from '../../Maths/math.color';
  21. import { Scalar } from "../../Maths/math.scalar";
  22. import { ImageProcessingConfiguration, IImageProcessingConfigurationDefines } from "../../Materials/imageProcessingConfiguration";
  23. import { Effect, IEffectCreationOptions } from "../../Materials/effect";
  24. import { Material, IMaterialCompilationOptions, ICustomShaderNameResolveOptions } from "../../Materials/material";
  25. import { MaterialDefines } from "../../Materials/materialDefines";
  26. import { PushMaterial } from "../../Materials/pushMaterial";
  27. import { MaterialHelper } from "../../Materials/materialHelper";
  28. import { BaseTexture } from "../../Materials/Textures/baseTexture";
  29. import { Texture } from "../../Materials/Textures/texture";
  30. import { RenderTargetTexture } from "../../Materials/Textures/renderTargetTexture";
  31. import { CubeTexture } from "../../Materials/Textures/cubeTexture";
  32. import { MaterialFlags } from "../materialFlags";
  33. import { Constants } from "../../Engines/constants";
  34. import { IAnimatable } from '../../Animations/animatable.interface';
  35. import "../../Materials/Textures/baseTexture.polynomial";
  36. import "../../Shaders/pbr.fragment";
  37. import "../../Shaders/pbr.vertex";
  38. import { EffectFallbacks } from '../effectFallbacks';
  39. import { IMaterialDetailMapDefines, DetailMapConfiguration } from '../material.detailMapConfiguration';
  40. declare type PrePassRenderer = import("../../Rendering/prePassRenderer").PrePassRenderer;
  41. const onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };
  42. /**
  43. * Manages the defines for the PBR Material.
  44. * @hidden
  45. */
  46. export class PBRMaterialDefines extends MaterialDefines
  47. implements IImageProcessingConfigurationDefines,
  48. IMaterialClearCoatDefines,
  49. IMaterialAnisotropicDefines,
  50. IMaterialBRDFDefines,
  51. IMaterialSheenDefines,
  52. IMaterialSubSurfaceDefines,
  53. IMaterialDetailMapDefines {
  54. public PBR = true;
  55. public NUM_SAMPLES = "0";
  56. public REALTIME_FILTERING = false;
  57. public MAINUV1 = false;
  58. public MAINUV2 = false;
  59. public UV1 = false;
  60. public UV2 = false;
  61. public ALBEDO = false;
  62. public GAMMAALBEDO = false;
  63. public ALBEDODIRECTUV = 0;
  64. public VERTEXCOLOR = false;
  65. public DETAIL = false;
  66. public DETAILDIRECTUV = 0;
  67. public DETAIL_NORMALBLENDMETHOD = 0;
  68. public AMBIENT = false;
  69. public AMBIENTDIRECTUV = 0;
  70. public AMBIENTINGRAYSCALE = false;
  71. public OPACITY = false;
  72. public VERTEXALPHA = false;
  73. public OPACITYDIRECTUV = 0;
  74. public OPACITYRGB = false;
  75. public ALPHATEST = false;
  76. public DEPTHPREPASS = false;
  77. public ALPHABLEND = false;
  78. public ALPHAFROMALBEDO = false;
  79. public ALPHATESTVALUE = "0.5";
  80. public SPECULAROVERALPHA = false;
  81. public RADIANCEOVERALPHA = false;
  82. public ALPHAFRESNEL = false;
  83. public LINEARALPHAFRESNEL = false;
  84. public PREMULTIPLYALPHA = false;
  85. public EMISSIVE = false;
  86. public EMISSIVEDIRECTUV = 0;
  87. public REFLECTIVITY = false;
  88. public REFLECTIVITYDIRECTUV = 0;
  89. public SPECULARTERM = false;
  90. public MICROSURFACEFROMREFLECTIVITYMAP = false;
  91. public MICROSURFACEAUTOMATIC = false;
  92. public LODBASEDMICROSFURACE = false;
  93. public MICROSURFACEMAP = false;
  94. public MICROSURFACEMAPDIRECTUV = 0;
  95. public METALLICWORKFLOW = false;
  96. public ROUGHNESSSTOREINMETALMAPALPHA = false;
  97. public ROUGHNESSSTOREINMETALMAPGREEN = false;
  98. public METALLNESSSTOREINMETALMAPBLUE = false;
  99. public AOSTOREINMETALMAPRED = false;
  100. public METALLIC_REFLECTANCE = false;
  101. public METALLIC_REFLECTANCEDIRECTUV = 0;
  102. public ENVIRONMENTBRDF = false;
  103. public ENVIRONMENTBRDF_RGBD = false;
  104. public NORMAL = false;
  105. public TANGENT = false;
  106. public BUMP = false;
  107. public BUMPDIRECTUV = 0;
  108. public OBJECTSPACE_NORMALMAP = false;
  109. public PARALLAX = false;
  110. public PARALLAXOCCLUSION = false;
  111. public NORMALXYSCALE = true;
  112. public LIGHTMAP = false;
  113. public LIGHTMAPDIRECTUV = 0;
  114. public USELIGHTMAPASSHADOWMAP = false;
  115. public GAMMALIGHTMAP = false;
  116. public RGBDLIGHTMAP = false;
  117. public REFLECTION = false;
  118. public REFLECTIONMAP_3D = false;
  119. public REFLECTIONMAP_SPHERICAL = false;
  120. public REFLECTIONMAP_PLANAR = false;
  121. public REFLECTIONMAP_CUBIC = false;
  122. public USE_LOCAL_REFLECTIONMAP_CUBIC = false;
  123. public REFLECTIONMAP_PROJECTION = false;
  124. public REFLECTIONMAP_SKYBOX = false;
  125. public REFLECTIONMAP_EXPLICIT = false;
  126. public REFLECTIONMAP_EQUIRECTANGULAR = false;
  127. public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
  128. public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
  129. public INVERTCUBICMAP = false;
  130. public USESPHERICALFROMREFLECTIONMAP = false;
  131. public USEIRRADIANCEMAP = false;
  132. public SPHERICAL_HARMONICS = false;
  133. public USESPHERICALINVERTEX = false;
  134. public REFLECTIONMAP_OPPOSITEZ = false;
  135. public LODINREFLECTIONALPHA = false;
  136. public GAMMAREFLECTION = false;
  137. public RGBDREFLECTION = false;
  138. public LINEARSPECULARREFLECTION = false;
  139. public RADIANCEOCCLUSION = false;
  140. public HORIZONOCCLUSION = false;
  141. public INSTANCES = false;
  142. public THIN_INSTANCES = false;
  143. public PREPASS = false;
  144. public PREPASS_IRRADIANCE = false;
  145. public PREPASS_IRRADIANCE_INDEX = -1;
  146. public PREPASS_ALBEDO = false;
  147. public PREPASS_ALBEDO_INDEX = -1;
  148. public PREPASS_DEPTHNORMAL = false;
  149. public PREPASS_DEPTHNORMAL_INDEX = -1;
  150. public PREPASS_POSITION = false;
  151. public PREPASS_POSITION_INDEX = -1;
  152. public PREPASS_VELOCITY = false;
  153. public PREPASS_VELOCITY_INDEX = -1;
  154. public PREPASS_REFLECTIVITY = false;
  155. public PREPASS_REFLECTIVITY_INDEX = -1;
  156. public SCENE_MRT_COUNT = 0;
  157. public NUM_BONE_INFLUENCERS = 0;
  158. public BonesPerMesh = 0;
  159. public BONETEXTURE = false;
  160. public BONES_VELOCITY_ENABLED = false;
  161. public NONUNIFORMSCALING = false;
  162. public MORPHTARGETS = false;
  163. public MORPHTARGETS_NORMAL = false;
  164. public MORPHTARGETS_TANGENT = false;
  165. public MORPHTARGETS_UV = false;
  166. public NUM_MORPH_INFLUENCERS = 0;
  167. public IMAGEPROCESSING = false;
  168. public VIGNETTE = false;
  169. public VIGNETTEBLENDMODEMULTIPLY = false;
  170. public VIGNETTEBLENDMODEOPAQUE = false;
  171. public TONEMAPPING = false;
  172. public TONEMAPPING_ACES = false;
  173. public CONTRAST = false;
  174. public COLORCURVES = false;
  175. public COLORGRADING = false;
  176. public COLORGRADING3D = false;
  177. public SAMPLER3DGREENDEPTH = false;
  178. public SAMPLER3DBGRMAP = false;
  179. public IMAGEPROCESSINGPOSTPROCESS = false;
  180. public EXPOSURE = false;
  181. public MULTIVIEW = false;
  182. public USEPHYSICALLIGHTFALLOFF = false;
  183. public USEGLTFLIGHTFALLOFF = false;
  184. public TWOSIDEDLIGHTING = false;
  185. public SHADOWFLOAT = false;
  186. public CLIPPLANE = false;
  187. public CLIPPLANE2 = false;
  188. public CLIPPLANE3 = false;
  189. public CLIPPLANE4 = false;
  190. public CLIPPLANE5 = false;
  191. public CLIPPLANE6 = false;
  192. public POINTSIZE = false;
  193. public FOG = false;
  194. public LOGARITHMICDEPTH = false;
  195. public FORCENORMALFORWARD = false;
  196. public SPECULARAA = false;
  197. public CLEARCOAT = false;
  198. public CLEARCOAT_DEFAULTIOR = false;
  199. public CLEARCOAT_TEXTURE = false;
  200. public CLEARCOAT_TEXTUREDIRECTUV = 0;
  201. public CLEARCOAT_BUMP = false;
  202. public CLEARCOAT_BUMPDIRECTUV = 0;
  203. public CLEARCOAT_TINT = false;
  204. public CLEARCOAT_TINT_TEXTURE = false;
  205. public CLEARCOAT_TINT_TEXTUREDIRECTUV = 0;
  206. public ANISOTROPIC = false;
  207. public ANISOTROPIC_TEXTURE = false;
  208. public ANISOTROPIC_TEXTUREDIRECTUV = 0;
  209. public BRDF_V_HEIGHT_CORRELATED = false;
  210. public MS_BRDF_ENERGY_CONSERVATION = false;
  211. public SPECULAR_GLOSSINESS_ENERGY_CONSERVATION = false;
  212. public SHEEN = false;
  213. public SHEEN_TEXTURE = false;
  214. public SHEEN_TEXTUREDIRECTUV = 0;
  215. public SHEEN_LINKWITHALBEDO = false;
  216. public SHEEN_ROUGHNESS = false;
  217. public SHEEN_ALBEDOSCALING = false;
  218. public SUBSURFACE = false;
  219. public SS_REFRACTION = false;
  220. public SS_TRANSLUCENCY = false;
  221. public SS_SCATTERING = false;
  222. public SS_THICKNESSANDMASK_TEXTURE = false;
  223. public SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;
  224. public SS_REFRACTIONMAP_3D = false;
  225. public SS_REFRACTIONMAP_OPPOSITEZ = false;
  226. public SS_LODINREFRACTIONALPHA = false;
  227. public SS_GAMMAREFRACTION = false;
  228. public SS_RGBDREFRACTION = false;
  229. public SS_LINEARSPECULARREFRACTION = false;
  230. public SS_LINKREFRACTIONTOTRANSPARENCY = false;
  231. public SS_ALBEDOFORREFRACTIONTINT = false;
  232. public SS_MASK_FROM_THICKNESS_TEXTURE = false;
  233. public UNLIT = false;
  234. public DEBUGMODE = 0;
  235. /**
  236. * Initializes the PBR Material defines.
  237. */
  238. constructor() {
  239. super();
  240. this.rebuild();
  241. }
  242. /**
  243. * Resets the PBR Material defines.
  244. */
  245. public reset(): void {
  246. super.reset();
  247. this.ALPHATESTVALUE = "0.5";
  248. this.PBR = true;
  249. }
  250. }
  251. /**
  252. * The Physically based material base class of BJS.
  253. *
  254. * This offers the main features of a standard PBR material.
  255. * For more information, please refer to the documentation :
  256. * https://doc.babylonjs.com/how_to/physically_based_rendering
  257. */
  258. export abstract class PBRBaseMaterial extends PushMaterial {
  259. /**
  260. * PBRMaterialTransparencyMode: No transparency mode, Alpha channel is not use.
  261. */
  262. public static readonly PBRMATERIAL_OPAQUE = Material.MATERIAL_OPAQUE;
  263. /**
  264. * PBRMaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
  265. */
  266. public static readonly PBRMATERIAL_ALPHATEST = Material.MATERIAL_ALPHATEST;
  267. /**
  268. * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
  269. */
  270. public static readonly PBRMATERIAL_ALPHABLEND = Material.MATERIAL_ALPHABLEND;
  271. /**
  272. * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
  273. * They are also discarded below the alpha cutoff threshold to improve performances.
  274. */
  275. public static readonly PBRMATERIAL_ALPHATESTANDBLEND = Material.MATERIAL_ALPHATESTANDBLEND;
  276. /**
  277. * Defines the default value of how much AO map is occluding the analytical lights
  278. * (point spot...).
  279. */
  280. public static DEFAULT_AO_ON_ANALYTICAL_LIGHTS = 0;
  281. /**
  282. * PBRMaterialLightFalloff Physical: light is falling off following the inverse squared distance law.
  283. */
  284. public static readonly LIGHTFALLOFF_PHYSICAL = 0;
  285. /**
  286. * PBRMaterialLightFalloff gltf: light is falling off as described in the gltf moving to PBR document
  287. * to enhance interoperability with other engines.
  288. */
  289. public static readonly LIGHTFALLOFF_GLTF = 1;
  290. /**
  291. * PBRMaterialLightFalloff Standard: light is falling off like in the standard material
  292. * to enhance interoperability with other materials.
  293. */
  294. public static readonly LIGHTFALLOFF_STANDARD = 2;
  295. /**
  296. * Intensity of the direct lights e.g. the four lights available in your scene.
  297. * This impacts both the direct diffuse and specular highlights.
  298. */
  299. protected _directIntensity: number = 1.0;
  300. /**
  301. * Intensity of the emissive part of the material.
  302. * This helps controlling the emissive effect without modifying the emissive color.
  303. */
  304. protected _emissiveIntensity: number = 1.0;
  305. /**
  306. * Intensity of the environment e.g. how much the environment will light the object
  307. * either through harmonics for rough material or through the refelction for shiny ones.
  308. */
  309. protected _environmentIntensity: number = 1.0;
  310. /**
  311. * This is a special control allowing the reduction of the specular highlights coming from the
  312. * four lights of the scene. Those highlights may not be needed in full environment lighting.
  313. */
  314. protected _specularIntensity: number = 1.0;
  315. /**
  316. * This stores the direct, emissive, environment, and specular light intensities into a Vector4.
  317. */
  318. private _lightingInfos: Vector4 = new Vector4(this._directIntensity, this._emissiveIntensity, this._environmentIntensity, this._specularIntensity);
  319. /**
  320. * Debug Control allowing disabling the bump map on this material.
  321. */
  322. protected _disableBumpMap: boolean = false;
  323. /**
  324. * AKA Diffuse Texture in standard nomenclature.
  325. */
  326. protected _albedoTexture: Nullable<BaseTexture> = null;
  327. /**
  328. * AKA Occlusion Texture in other nomenclature.
  329. */
  330. protected _ambientTexture: Nullable<BaseTexture> = null;
  331. /**
  332. * AKA Occlusion Texture Intensity in other nomenclature.
  333. */
  334. protected _ambientTextureStrength: number = 1.0;
  335. /**
  336. * Defines how much the AO map is occluding the analytical lights (point spot...).
  337. * 1 means it completely occludes it
  338. * 0 mean it has no impact
  339. */
  340. protected _ambientTextureImpactOnAnalyticalLights: number = PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS;
  341. /**
  342. * Stores the alpha values in a texture.
  343. */
  344. protected _opacityTexture: Nullable<BaseTexture> = null;
  345. /**
  346. * Stores the reflection values in a texture.
  347. */
  348. protected _reflectionTexture: Nullable<BaseTexture> = null;
  349. /**
  350. * Stores the emissive values in a texture.
  351. */
  352. protected _emissiveTexture: Nullable<BaseTexture> = null;
  353. /**
  354. * AKA Specular texture in other nomenclature.
  355. */
  356. protected _reflectivityTexture: Nullable<BaseTexture> = null;
  357. /**
  358. * Used to switch from specular/glossiness to metallic/roughness workflow.
  359. */
  360. protected _metallicTexture: Nullable<BaseTexture> = null;
  361. /**
  362. * Specifies the metallic scalar of the metallic/roughness workflow.
  363. * Can also be used to scale the metalness values of the metallic texture.
  364. */
  365. protected _metallic: Nullable<number> = null;
  366. /**
  367. * Specifies the roughness scalar of the metallic/roughness workflow.
  368. * Can also be used to scale the roughness values of the metallic texture.
  369. */
  370. protected _roughness: Nullable<number> = null;
  371. /**
  372. * In metallic workflow, specifies an F0 factor to help configuring the material F0.
  373. * By default the indexOfrefraction is used to compute F0;
  374. *
  375. * This is used as a factor against the default reflectance at normal incidence to tweak it.
  376. *
  377. * F0 = defaultF0 * metallicF0Factor * metallicReflectanceColor;
  378. * F90 = metallicReflectanceColor;
  379. */
  380. protected _metallicF0Factor = 1;
  381. /**
  382. * In metallic workflow, specifies an F90 color to help configuring the material F90.
  383. * By default the F90 is always 1;
  384. *
  385. * Please note that this factor is also used as a factor against the default reflectance at normal incidence.
  386. *
  387. * F0 = defaultF0 * metallicF0Factor * metallicReflectanceColor
  388. * F90 = metallicReflectanceColor;
  389. */
  390. protected _metallicReflectanceColor = Color3.White();
  391. /**
  392. * Defines to store metallicReflectanceColor in RGB and metallicF0Factor in A
  393. * This is multiply against the scalar values defined in the material.
  394. */
  395. protected _metallicReflectanceTexture: Nullable<BaseTexture> = null;
  396. /**
  397. * Used to enable roughness/glossiness fetch from a separate channel depending on the current mode.
  398. * Gray Scale represents roughness in metallic mode and glossiness in specular mode.
  399. */
  400. protected _microSurfaceTexture: Nullable<BaseTexture> = null;
  401. /**
  402. * Stores surface normal data used to displace a mesh in a texture.
  403. */
  404. protected _bumpTexture: Nullable<BaseTexture> = null;
  405. /**
  406. * Stores the pre-calculated light information of a mesh in a texture.
  407. */
  408. protected _lightmapTexture: Nullable<BaseTexture> = null;
  409. /**
  410. * The color of a material in ambient lighting.
  411. */
  412. protected _ambientColor = new Color3(0, 0, 0);
  413. /**
  414. * AKA Diffuse Color in other nomenclature.
  415. */
  416. protected _albedoColor = new Color3(1, 1, 1);
  417. /**
  418. * AKA Specular Color in other nomenclature.
  419. */
  420. protected _reflectivityColor = new Color3(1, 1, 1);
  421. /**
  422. * The color applied when light is reflected from a material.
  423. */
  424. protected _reflectionColor = new Color3(1, 1, 1);
  425. /**
  426. * The color applied when light is emitted from a material.
  427. */
  428. protected _emissiveColor = new Color3(0, 0, 0);
  429. /**
  430. * AKA Glossiness in other nomenclature.
  431. */
  432. protected _microSurface = 0.9;
  433. /**
  434. * Specifies that the material will use the light map as a show map.
  435. */
  436. protected _useLightmapAsShadowmap = false;
  437. /**
  438. * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal
  439. * makes the reflect vector face the model (under horizon).
  440. */
  441. protected _useHorizonOcclusion = true;
  442. /**
  443. * This parameters will enable/disable radiance occlusion by preventing the radiance to lit
  444. * too much the area relying on ambient texture to define their ambient occlusion.
  445. */
  446. protected _useRadianceOcclusion = true;
  447. /**
  448. * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.
  449. */
  450. protected _useAlphaFromAlbedoTexture = false;
  451. /**
  452. * Specifies that the material will keeps the specular highlights over a transparent surface (only the most limunous ones).
  453. * A car glass is a good exemple of that. When sun reflects on it you can not see what is behind.
  454. */
  455. protected _useSpecularOverAlpha = true;
  456. /**
  457. * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.
  458. */
  459. protected _useMicroSurfaceFromReflectivityMapAlpha = false;
  460. /**
  461. * Specifies if the metallic texture contains the roughness information in its alpha channel.
  462. */
  463. protected _useRoughnessFromMetallicTextureAlpha = true;
  464. /**
  465. * Specifies if the metallic texture contains the roughness information in its green channel.
  466. */
  467. protected _useRoughnessFromMetallicTextureGreen = false;
  468. /**
  469. * Specifies if the metallic texture contains the metallness information in its blue channel.
  470. */
  471. protected _useMetallnessFromMetallicTextureBlue = false;
  472. /**
  473. * Specifies if the metallic texture contains the ambient occlusion information in its red channel.
  474. */
  475. protected _useAmbientOcclusionFromMetallicTextureRed = false;
  476. /**
  477. * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.
  478. */
  479. protected _useAmbientInGrayScale = false;
  480. /**
  481. * In case the reflectivity map does not contain the microsurface information in its alpha channel,
  482. * The material will try to infer what glossiness each pixel should be.
  483. */
  484. protected _useAutoMicroSurfaceFromReflectivityMap = false;
  485. /**
  486. * Defines the falloff type used in this material.
  487. * It by default is Physical.
  488. */
  489. protected _lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL;
  490. /**
  491. * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most limunous ones).
  492. * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind.
  493. */
  494. protected _useRadianceOverAlpha = true;
  495. /**
  496. * Allows using an object space normal map (instead of tangent space).
  497. */
  498. protected _useObjectSpaceNormalMap = false;
  499. /**
  500. * Allows using the bump map in parallax mode.
  501. */
  502. protected _useParallax = false;
  503. /**
  504. * Allows using the bump map in parallax occlusion mode.
  505. */
  506. protected _useParallaxOcclusion = false;
  507. /**
  508. * Controls the scale bias of the parallax mode.
  509. */
  510. protected _parallaxScaleBias = 0.05;
  511. /**
  512. * If sets to true, disables all the lights affecting the material.
  513. */
  514. protected _disableLighting = false;
  515. /**
  516. * Number of Simultaneous lights allowed on the material.
  517. */
  518. protected _maxSimultaneousLights = 4;
  519. /**
  520. * If sets to true, x component of normal map value will be inverted (x = 1.0 - x).
  521. */
  522. protected _invertNormalMapX = false;
  523. /**
  524. * If sets to true, y component of normal map value will be inverted (y = 1.0 - y).
  525. */
  526. protected _invertNormalMapY = false;
  527. /**
  528. * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
  529. */
  530. protected _twoSidedLighting = false;
  531. /**
  532. * Defines the alpha limits in alpha test mode.
  533. */
  534. protected _alphaCutOff = 0.4;
  535. /**
  536. * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
  537. */
  538. protected _forceAlphaTest = false;
  539. /**
  540. * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
  541. * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)
  542. */
  543. protected _useAlphaFresnel = false;
  544. /**
  545. * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
  546. * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)
  547. */
  548. protected _useLinearAlphaFresnel = false;
  549. /**
  550. * Specifies the environment BRDF texture used to comput the scale and offset roughness values
  551. * from cos thetav and roughness:
  552. * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
  553. */
  554. protected _environmentBRDFTexture: Nullable<BaseTexture> = null;
  555. /**
  556. * Force the shader to compute irradiance in the fragment shader in order to take bump in account.
  557. */
  558. protected _forceIrradianceInFragment = false;
  559. private _realTimeFiltering: boolean = false;
  560. /**
  561. * Enables realtime filtering on the texture.
  562. */
  563. public get realTimeFiltering() {
  564. return this._realTimeFiltering;
  565. }
  566. public set realTimeFiltering(b: boolean) {
  567. this._realTimeFiltering = b;
  568. this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);
  569. }
  570. private _realTimeFilteringQuality: number = Constants.TEXTURE_FILTERING_QUALITY_LOW;
  571. /**
  572. * Quality switch for realtime filtering
  573. */
  574. public get realTimeFilteringQuality() : number {
  575. return this._realTimeFilteringQuality;
  576. }
  577. public set realTimeFilteringQuality(n: number) {
  578. this._realTimeFilteringQuality = n;
  579. this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);
  580. }
  581. /**
  582. * Can this material render to several textures at once
  583. */
  584. public get canRenderToMRT() {
  585. return true;
  586. }
  587. /**
  588. * Force normal to face away from face.
  589. */
  590. protected _forceNormalForward = false;
  591. /**
  592. * Enables specular anti aliasing in the PBR shader.
  593. * It will both interacts on the Geometry for analytical and IBL lighting.
  594. * It also prefilter the roughness map based on the bump values.
  595. */
  596. protected _enableSpecularAntiAliasing = false;
  597. /**
  598. * Default configuration related to image processing available in the PBR Material.
  599. */
  600. @serializeAsImageProcessingConfiguration()
  601. protected _imageProcessingConfiguration: ImageProcessingConfiguration;
  602. /**
  603. * Keep track of the image processing observer to allow dispose and replace.
  604. */
  605. private _imageProcessingObserver: Nullable<Observer<ImageProcessingConfiguration>> = null;
  606. /**
  607. * Attaches a new image processing configuration to the PBR Material.
  608. * @param configuration
  609. */
  610. protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void {
  611. if (configuration === this._imageProcessingConfiguration) {
  612. return;
  613. }
  614. // Detaches observer.
  615. if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
  616. this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
  617. }
  618. // Pick the scene configuration if needed.
  619. if (!configuration) {
  620. this._imageProcessingConfiguration = this.getScene().imageProcessingConfiguration;
  621. }
  622. else {
  623. this._imageProcessingConfiguration = configuration;
  624. }
  625. // Attaches observer.
  626. if (this._imageProcessingConfiguration) {
  627. this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(() => {
  628. this._markAllSubMeshesAsImageProcessingDirty();
  629. });
  630. }
  631. }
  632. /**
  633. * Stores the available render targets.
  634. */
  635. private _renderTargets = new SmartArray<RenderTargetTexture>(16);
  636. /**
  637. * Sets the global ambient color for the material used in lighting calculations.
  638. */
  639. private _globalAmbientColor = new Color3(0, 0, 0);
  640. /**
  641. * Enables the use of logarithmic depth buffers, which is good for wide depth buffers.
  642. */
  643. private _useLogarithmicDepth: boolean = false;
  644. /**
  645. * If set to true, no lighting calculations will be applied.
  646. */
  647. private _unlit = false;
  648. private _debugMode = 0;
  649. /**
  650. * @hidden
  651. * This is reserved for the inspector.
  652. * Defines the material debug mode.
  653. * It helps seeing only some components of the material while troubleshooting.
  654. */
  655. @expandToProperty("_markAllSubMeshesAsMiscDirty")
  656. public debugMode = 0;
  657. /**
  658. * @hidden
  659. * This is reserved for the inspector.
  660. * Specify from where on screen the debug mode should start.
  661. * The value goes from -1 (full screen) to 1 (not visible)
  662. * It helps with side by side comparison against the final render
  663. * This defaults to -1
  664. */
  665. private debugLimit = -1;
  666. /**
  667. * @hidden
  668. * This is reserved for the inspector.
  669. * As the default viewing range might not be enough (if the ambient is really small for instance)
  670. * You can use the factor to better multiply the final value.
  671. */
  672. private debugFactor = 1;
  673. /**
  674. * Defines the clear coat layer parameters for the material.
  675. */
  676. public readonly clearCoat = new PBRClearCoatConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
  677. /**
  678. * Defines the anisotropic parameters for the material.
  679. */
  680. public readonly anisotropy = new PBRAnisotropicConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
  681. /**
  682. * Defines the BRDF parameters for the material.
  683. */
  684. public readonly brdf = new PBRBRDFConfiguration(this._markAllSubMeshesAsMiscDirty.bind(this));
  685. /**
  686. * Defines the Sheen parameters for the material.
  687. */
  688. public readonly sheen = new PBRSheenConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
  689. /**
  690. * Defines the SubSurface parameters for the material.
  691. */
  692. public readonly subSurface: PBRSubSurfaceConfiguration;
  693. /**
  694. * Defines additionnal PrePass parameters for the material.
  695. */
  696. public readonly prePassConfiguration: PrePassConfiguration;
  697. /**
  698. * Defines the detail map parameters for the material.
  699. */
  700. public readonly detailMap = new DetailMapConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
  701. protected _rebuildInParallel = false;
  702. /**
  703. * Instantiates a new PBRMaterial instance.
  704. *
  705. * @param name The material name
  706. * @param scene The scene the material will be use in.
  707. */
  708. constructor(name: string, scene: Scene) {
  709. super(name, scene);
  710. // Setup the default processing configuration to the scene.
  711. this._attachImageProcessingConfiguration(null);
  712. this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
  713. this._renderTargets.reset();
  714. if (MaterialFlags.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
  715. this._renderTargets.push(<RenderTargetTexture>this._reflectionTexture);
  716. }
  717. this.subSurface.fillRenderTargetTextures(this._renderTargets);
  718. return this._renderTargets;
  719. };
  720. this._environmentBRDFTexture = BRDFTextureTools.GetEnvironmentBRDFTexture(scene);
  721. this.subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this), this._markScenePrePassDirty.bind(this), scene);
  722. this.prePassConfiguration = new PrePassConfiguration();
  723. }
  724. /**
  725. * Gets a boolean indicating that current material needs to register RTT
  726. */
  727. public get hasRenderTargetTextures(): boolean {
  728. if (MaterialFlags.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
  729. return true;
  730. }
  731. return this.subSurface.hasRenderTargetTextures();
  732. }
  733. /**
  734. * Gets the name of the material class.
  735. */
  736. public getClassName(): string {
  737. return "PBRBaseMaterial";
  738. }
  739. /**
  740. * Enabled the use of logarithmic depth buffers, which is good for wide depth buffers.
  741. */
  742. @serialize()
  743. public get useLogarithmicDepth(): boolean {
  744. return this._useLogarithmicDepth;
  745. }
  746. /**
  747. * Enabled the use of logarithmic depth buffers, which is good for wide depth buffers.
  748. */
  749. public set useLogarithmicDepth(value: boolean) {
  750. this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
  751. }
  752. /**
  753. * Returns true if alpha blending should be disabled.
  754. */
  755. protected get _disableAlphaBlending(): boolean {
  756. return (this.subSurface.disableAlphaBlending ||
  757. this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_OPAQUE ||
  758. this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST);
  759. }
  760. /**
  761. * Specifies whether or not this material should be rendered in alpha blend mode.
  762. */
  763. public needAlphaBlending(): boolean {
  764. if (this._disableAlphaBlending) {
  765. return false;
  766. }
  767. return (this.alpha < 1.0) || (this._opacityTexture != null) || this._shouldUseAlphaFromAlbedoTexture();
  768. }
  769. /**
  770. * Specifies whether or not this material should be rendered in alpha test mode.
  771. */
  772. public needAlphaTesting(): boolean {
  773. if (this._forceAlphaTest) {
  774. return true;
  775. }
  776. if (this.subSurface.disableAlphaBlending) {
  777. return false;
  778. }
  779. return this._albedoTexture != null && this._albedoTexture.hasAlpha && (this._transparencyMode == null || this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST);
  780. }
  781. /**
  782. * Specifies whether or not the alpha value of the albedo texture should be used for alpha blending.
  783. */
  784. protected _shouldUseAlphaFromAlbedoTexture(): boolean {
  785. return this._albedoTexture != null && this._albedoTexture.hasAlpha && this._useAlphaFromAlbedoTexture && this._transparencyMode !== PBRBaseMaterial.PBRMATERIAL_OPAQUE;
  786. }
  787. /**
  788. * Gets the texture used for the alpha test.
  789. */
  790. public getAlphaTestTexture(): Nullable<BaseTexture> {
  791. return this._albedoTexture;
  792. }
  793. /**
  794. * Specifies that the submesh is ready to be used.
  795. * @param mesh - BJS mesh.
  796. * @param subMesh - A submesh of the BJS mesh. Used to check if it is ready.
  797. * @param useInstances - Specifies that instances should be used.
  798. * @returns - boolean indicating that the submesh is ready or not.
  799. */
  800. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
  801. if (subMesh.effect && this.isFrozen) {
  802. if (subMesh.effect._wasPreviouslyReady) {
  803. return true;
  804. }
  805. }
  806. if (!subMesh._materialDefines) {
  807. subMesh._materialDefines = new PBRMaterialDefines();
  808. }
  809. const defines = <PBRMaterialDefines>subMesh._materialDefines;
  810. if (this._isReadyForSubMesh(subMesh)) {
  811. return true;
  812. }
  813. const scene = this.getScene();
  814. const engine = scene.getEngine();
  815. if (defines._areTexturesDirty) {
  816. if (scene.texturesEnabled) {
  817. if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
  818. if (!this._albedoTexture.isReadyOrNotBlocking()) {
  819. return false;
  820. }
  821. }
  822. if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
  823. if (!this._ambientTexture.isReadyOrNotBlocking()) {
  824. return false;
  825. }
  826. }
  827. if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {
  828. if (!this._opacityTexture.isReadyOrNotBlocking()) {
  829. return false;
  830. }
  831. }
  832. var reflectionTexture = this._getReflectionTexture();
  833. if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
  834. if (!reflectionTexture.isReadyOrNotBlocking()) {
  835. return false;
  836. }
  837. if (reflectionTexture.irradianceTexture && !reflectionTexture.irradianceTexture.isReadyOrNotBlocking()) {
  838. return false;
  839. }
  840. }
  841. if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {
  842. if (!this._lightmapTexture.isReadyOrNotBlocking()) {
  843. return false;
  844. }
  845. }
  846. if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {
  847. if (!this._emissiveTexture.isReadyOrNotBlocking()) {
  848. return false;
  849. }
  850. }
  851. if (MaterialFlags.SpecularTextureEnabled) {
  852. if (this._metallicTexture) {
  853. if (!this._metallicTexture.isReadyOrNotBlocking()) {
  854. return false;
  855. }
  856. }
  857. else if (this._reflectivityTexture) {
  858. if (!this._reflectivityTexture.isReadyOrNotBlocking()) {
  859. return false;
  860. }
  861. }
  862. if (this._metallicReflectanceTexture) {
  863. if (!this._metallicReflectanceTexture.isReadyOrNotBlocking()) {
  864. return false;
  865. }
  866. }
  867. if (this._microSurfaceTexture) {
  868. if (!this._microSurfaceTexture.isReadyOrNotBlocking()) {
  869. return false;
  870. }
  871. }
  872. }
  873. if (engine.getCaps().standardDerivatives && this._bumpTexture && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {
  874. // Bump texture cannot be not blocking.
  875. if (!this._bumpTexture.isReady()) {
  876. return false;
  877. }
  878. }
  879. if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {
  880. // This is blocking.
  881. if (!this._environmentBRDFTexture.isReady()) {
  882. return false;
  883. }
  884. }
  885. }
  886. }
  887. if (!this.subSurface.isReadyForSubMesh(defines, scene) ||
  888. !this.clearCoat.isReadyForSubMesh(defines, scene, engine, this._disableBumpMap) ||
  889. !this.sheen.isReadyForSubMesh(defines, scene) ||
  890. !this.anisotropy.isReadyForSubMesh(defines, scene) ||
  891. !this.detailMap.isReadyForSubMesh(defines, scene)) {
  892. return false;
  893. }
  894. if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
  895. if (!this._imageProcessingConfiguration.isReady()) {
  896. return false;
  897. }
  898. }
  899. if (!engine.getCaps().standardDerivatives && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
  900. mesh.createNormals(true);
  901. Logger.Warn("PBRMaterial: Normals have been created for the mesh: " + mesh.name);
  902. }
  903. const previousEffect = subMesh.effect;
  904. const lightDisposed = defines._areLightsDisposed;
  905. let effect = this._prepareEffect(mesh, defines, this.onCompiled, this.onError, useInstances, null, subMesh.getRenderingMesh().hasThinInstances);
  906. if (effect) {
  907. if (this._onEffectCreatedObservable) {
  908. onCreatedEffectParameters.effect = effect;
  909. onCreatedEffectParameters.subMesh = subMesh;
  910. this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);
  911. }
  912. // Use previous effect while new one is compiling
  913. if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {
  914. effect = previousEffect;
  915. this._rebuildInParallel = true;
  916. defines.markAsUnprocessed();
  917. if (lightDisposed) {
  918. // re register in case it takes more than one frame.
  919. defines._areLightsDisposed = true;
  920. return false;
  921. }
  922. } else {
  923. this._rebuildInParallel = false;
  924. scene.resetCachedMaterial();
  925. subMesh.setEffect(effect, defines);
  926. this.buildUniformLayout();
  927. }
  928. }
  929. if (!subMesh.effect || !subMesh.effect.isReady()) {
  930. return false;
  931. }
  932. defines._renderId = scene.getRenderId();
  933. subMesh.effect._wasPreviouslyReady = true;
  934. return true;
  935. }
  936. /**
  937. * Specifies if the material uses metallic roughness workflow.
  938. * @returns boolean specifiying if the material uses metallic roughness workflow.
  939. */
  940. public isMetallicWorkflow(): boolean {
  941. if (this._metallic != null || this._roughness != null || this._metallicTexture) {
  942. return true;
  943. }
  944. return false;
  945. }
  946. private _prepareEffect(mesh: AbstractMesh, defines: PBRMaterialDefines, onCompiled: Nullable<(effect: Effect) => void> = null, onError: Nullable<(effect: Effect, errors: string) => void> = null,
  947. useInstances: Nullable<boolean> = null, useClipPlane: Nullable<boolean> = null, useThinInstances: boolean): Nullable<Effect> {
  948. this._prepareDefines(mesh, defines, useInstances, useClipPlane, useThinInstances);
  949. if (!defines.isDirty) {
  950. return null;
  951. }
  952. defines.markAsProcessed();
  953. const scene = this.getScene();
  954. const engine = scene.getEngine();
  955. // Fallbacks
  956. var fallbacks = new EffectFallbacks();
  957. var fallbackRank = 0;
  958. if (defines.USESPHERICALINVERTEX) {
  959. fallbacks.addFallback(fallbackRank++, "USESPHERICALINVERTEX");
  960. }
  961. if (defines.FOG) {
  962. fallbacks.addFallback(fallbackRank, "FOG");
  963. }
  964. if (defines.SPECULARAA) {
  965. fallbacks.addFallback(fallbackRank, "SPECULARAA");
  966. }
  967. if (defines.POINTSIZE) {
  968. fallbacks.addFallback(fallbackRank, "POINTSIZE");
  969. }
  970. if (defines.LOGARITHMICDEPTH) {
  971. fallbacks.addFallback(fallbackRank, "LOGARITHMICDEPTH");
  972. }
  973. if (defines.PARALLAX) {
  974. fallbacks.addFallback(fallbackRank, "PARALLAX");
  975. }
  976. if (defines.PARALLAXOCCLUSION) {
  977. fallbacks.addFallback(fallbackRank++, "PARALLAXOCCLUSION");
  978. }
  979. fallbackRank = PBRAnisotropicConfiguration.AddFallbacks(defines, fallbacks, fallbackRank);
  980. fallbackRank = PBRAnisotropicConfiguration.AddFallbacks(defines, fallbacks, fallbackRank);
  981. fallbackRank = PBRSubSurfaceConfiguration.AddFallbacks(defines, fallbacks, fallbackRank);
  982. fallbackRank = PBRSheenConfiguration.AddFallbacks(defines, fallbacks, fallbackRank);
  983. if (defines.ENVIRONMENTBRDF) {
  984. fallbacks.addFallback(fallbackRank++, "ENVIRONMENTBRDF");
  985. }
  986. if (defines.TANGENT) {
  987. fallbacks.addFallback(fallbackRank++, "TANGENT");
  988. }
  989. if (defines.BUMP) {
  990. fallbacks.addFallback(fallbackRank++, "BUMP");
  991. }
  992. fallbackRank = MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank++);
  993. if (defines.SPECULARTERM) {
  994. fallbacks.addFallback(fallbackRank++, "SPECULARTERM");
  995. }
  996. if (defines.USESPHERICALFROMREFLECTIONMAP) {
  997. fallbacks.addFallback(fallbackRank++, "USESPHERICALFROMREFLECTIONMAP");
  998. }
  999. if (defines.USEIRRADIANCEMAP) {
  1000. fallbacks.addFallback(fallbackRank++, "USEIRRADIANCEMAP");
  1001. }
  1002. if (defines.LIGHTMAP) {
  1003. fallbacks.addFallback(fallbackRank++, "LIGHTMAP");
  1004. }
  1005. if (defines.NORMAL) {
  1006. fallbacks.addFallback(fallbackRank++, "NORMAL");
  1007. }
  1008. if (defines.AMBIENT) {
  1009. fallbacks.addFallback(fallbackRank++, "AMBIENT");
  1010. }
  1011. if (defines.EMISSIVE) {
  1012. fallbacks.addFallback(fallbackRank++, "EMISSIVE");
  1013. }
  1014. if (defines.VERTEXCOLOR) {
  1015. fallbacks.addFallback(fallbackRank++, "VERTEXCOLOR");
  1016. }
  1017. if (defines.MORPHTARGETS) {
  1018. fallbacks.addFallback(fallbackRank++, "MORPHTARGETS");
  1019. }
  1020. if (defines.MULTIVIEW) {
  1021. fallbacks.addFallback(0, "MULTIVIEW");
  1022. }
  1023. //Attributes
  1024. var attribs = [VertexBuffer.PositionKind];
  1025. if (defines.NORMAL) {
  1026. attribs.push(VertexBuffer.NormalKind);
  1027. }
  1028. if (defines.TANGENT) {
  1029. attribs.push(VertexBuffer.TangentKind);
  1030. }
  1031. if (defines.UV1) {
  1032. attribs.push(VertexBuffer.UVKind);
  1033. }
  1034. if (defines.UV2) {
  1035. attribs.push(VertexBuffer.UV2Kind);
  1036. }
  1037. if (defines.VERTEXCOLOR) {
  1038. attribs.push(VertexBuffer.ColorKind);
  1039. }
  1040. MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
  1041. MaterialHelper.PrepareAttributesForInstances(attribs, defines);
  1042. MaterialHelper.PrepareAttributesForMorphTargets(attribs, mesh, defines);
  1043. var shaderName = "pbr";
  1044. var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vAlbedoColor", "vReflectivityColor", "vMetallicReflectanceFactors", "vEmissiveColor", "visibility", "vReflectionColor",
  1045. "vFogInfos", "vFogColor", "pointSize",
  1046. "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos", "vReflectionFilteringInfo", "vMetallicReflectanceInfos",
  1047. "vMicroSurfaceSamplerInfos", "vBumpInfos", "vLightmapInfos",
  1048. "mBones",
  1049. "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "vClipPlane5", "vClipPlane6", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "normalMatrix", "microSurfaceSamplerMatrix", "bumpMatrix", "lightmapMatrix", "metallicReflectanceMatrix",
  1050. "vLightingIntensity",
  1051. "logarithmicDepthConstant",
  1052. "vSphericalX", "vSphericalY", "vSphericalZ",
  1053. "vSphericalXX_ZZ", "vSphericalYY_ZZ", "vSphericalZZ",
  1054. "vSphericalXY", "vSphericalYZ", "vSphericalZX",
  1055. "vSphericalL00",
  1056. "vSphericalL1_1", "vSphericalL10", "vSphericalL11",
  1057. "vSphericalL2_2", "vSphericalL2_1", "vSphericalL20", "vSphericalL21", "vSphericalL22",
  1058. "vReflectionMicrosurfaceInfos",
  1059. "vTangentSpaceParams", "boneTextureWidth",
  1060. "vDebugMode"
  1061. ];
  1062. var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
  1063. "bumpSampler", "lightmapSampler", "opacitySampler",
  1064. "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh", "irradianceSampler",
  1065. "microSurfaceSampler", "environmentBrdfSampler", "boneSampler", "metallicReflectanceSampler"];
  1066. var uniformBuffers = ["Material", "Scene"];
  1067. DetailMapConfiguration.AddUniforms(uniforms);
  1068. DetailMapConfiguration.AddSamplers(samplers);
  1069. PBRSubSurfaceConfiguration.AddUniforms(uniforms);
  1070. PBRSubSurfaceConfiguration.AddSamplers(samplers);
  1071. PBRClearCoatConfiguration.AddUniforms(uniforms);
  1072. PBRClearCoatConfiguration.AddSamplers(samplers);
  1073. PBRAnisotropicConfiguration.AddUniforms(uniforms);
  1074. PBRAnisotropicConfiguration.AddSamplers(samplers);
  1075. PBRSheenConfiguration.AddUniforms(uniforms);
  1076. PBRSheenConfiguration.AddSamplers(samplers);
  1077. PrePassConfiguration.AddUniforms(uniforms);
  1078. PrePassConfiguration.AddSamplers(uniforms);
  1079. if (ImageProcessingConfiguration) {
  1080. ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
  1081. ImageProcessingConfiguration.PrepareSamplers(samplers, defines);
  1082. }
  1083. MaterialHelper.PrepareUniformsAndSamplersList(<IEffectCreationOptions>{
  1084. uniformsNames: uniforms,
  1085. uniformBuffersNames: uniformBuffers,
  1086. samplers: samplers,
  1087. defines: defines,
  1088. maxSimultaneousLights: this._maxSimultaneousLights
  1089. });
  1090. const csnrOptions: ICustomShaderNameResolveOptions = {};
  1091. if (this.customShaderNameResolve) {
  1092. shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines, attribs, csnrOptions);
  1093. }
  1094. var join = defines.toString();
  1095. return engine.createEffect(shaderName, <IEffectCreationOptions>{
  1096. attributes: attribs,
  1097. uniformsNames: uniforms,
  1098. uniformBuffersNames: uniformBuffers,
  1099. samplers: samplers,
  1100. defines: join,
  1101. fallbacks: fallbacks,
  1102. onCompiled: onCompiled,
  1103. onError: onError,
  1104. indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS },
  1105. processFinalCode: csnrOptions.processFinalCode,
  1106. multiTarget: defines.PREPASS
  1107. }, engine);
  1108. }
  1109. private _prepareDefines(mesh: AbstractMesh, defines: PBRMaterialDefines, useInstances: Nullable<boolean> = null, useClipPlane: Nullable<boolean> = null, useThinInstances: boolean = false): void {
  1110. const scene = this.getScene();
  1111. const engine = scene.getEngine();
  1112. // Lights
  1113. MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
  1114. defines._needNormals = true;
  1115. // Multiview
  1116. MaterialHelper.PrepareDefinesForMultiview(scene, defines);
  1117. // PrePass
  1118. MaterialHelper.PrepareDefinesForPrePass(scene, defines, this.canRenderToMRT);
  1119. // Textures
  1120. defines.METALLICWORKFLOW = this.isMetallicWorkflow();
  1121. if (defines._areTexturesDirty) {
  1122. defines._needUVs = false;
  1123. if (scene.texturesEnabled) {
  1124. if (scene.getEngine().getCaps().textureLOD) {
  1125. defines.LODBASEDMICROSFURACE = true;
  1126. }
  1127. if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
  1128. MaterialHelper.PrepareDefinesForMergedUV(this._albedoTexture, defines, "ALBEDO");
  1129. defines.GAMMAALBEDO = this._albedoTexture.gammaSpace;
  1130. } else {
  1131. defines.ALBEDO = false;
  1132. }
  1133. if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
  1134. MaterialHelper.PrepareDefinesForMergedUV(this._ambientTexture, defines, "AMBIENT");
  1135. defines.AMBIENTINGRAYSCALE = this._useAmbientInGrayScale;
  1136. } else {
  1137. defines.AMBIENT = false;
  1138. }
  1139. if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {
  1140. MaterialHelper.PrepareDefinesForMergedUV(this._opacityTexture, defines, "OPACITY");
  1141. defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;
  1142. } else {
  1143. defines.OPACITY = false;
  1144. }
  1145. var reflectionTexture = this._getReflectionTexture();
  1146. if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
  1147. defines.REFLECTION = true;
  1148. defines.GAMMAREFLECTION = reflectionTexture.gammaSpace;
  1149. defines.RGBDREFLECTION = reflectionTexture.isRGBD;
  1150. defines.REFLECTIONMAP_OPPOSITEZ = this.getScene().useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ;
  1151. defines.LODINREFLECTIONALPHA = reflectionTexture.lodLevelInAlpha;
  1152. defines.LINEARSPECULARREFLECTION = reflectionTexture.linearSpecularLOD;
  1153. if (this.realTimeFiltering && this.realTimeFilteringQuality > 0) {
  1154. defines.NUM_SAMPLES = "" + this.realTimeFilteringQuality;
  1155. if (engine.webGLVersion > 1) {
  1156. defines.NUM_SAMPLES = defines.NUM_SAMPLES + "u";
  1157. }
  1158. defines.REALTIME_FILTERING = true;
  1159. } else {
  1160. defines.REALTIME_FILTERING = false;
  1161. }
  1162. if (reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE) {
  1163. defines.INVERTCUBICMAP = true;
  1164. }
  1165. defines.REFLECTIONMAP_3D = reflectionTexture.isCube;
  1166. defines.REFLECTIONMAP_CUBIC = false;
  1167. defines.REFLECTIONMAP_EXPLICIT = false;
  1168. defines.REFLECTIONMAP_PLANAR = false;
  1169. defines.REFLECTIONMAP_PROJECTION = false;
  1170. defines.REFLECTIONMAP_SKYBOX = false;
  1171. defines.REFLECTIONMAP_SPHERICAL = false;
  1172. defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
  1173. defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
  1174. defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
  1175. switch (reflectionTexture.coordinatesMode) {
  1176. case Texture.EXPLICIT_MODE:
  1177. defines.REFLECTIONMAP_EXPLICIT = true;
  1178. break;
  1179. case Texture.PLANAR_MODE:
  1180. defines.REFLECTIONMAP_PLANAR = true;
  1181. break;
  1182. case Texture.PROJECTION_MODE:
  1183. defines.REFLECTIONMAP_PROJECTION = true;
  1184. break;
  1185. case Texture.SKYBOX_MODE:
  1186. defines.REFLECTIONMAP_SKYBOX = true;
  1187. break;
  1188. case Texture.SPHERICAL_MODE:
  1189. defines.REFLECTIONMAP_SPHERICAL = true;
  1190. break;
  1191. case Texture.EQUIRECTANGULAR_MODE:
  1192. defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
  1193. break;
  1194. case Texture.FIXED_EQUIRECTANGULAR_MODE:
  1195. defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
  1196. break;
  1197. case Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
  1198. defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = true;
  1199. break;
  1200. case Texture.CUBIC_MODE:
  1201. case Texture.INVCUBIC_MODE:
  1202. default:
  1203. defines.REFLECTIONMAP_CUBIC = true;
  1204. defines.USE_LOCAL_REFLECTIONMAP_CUBIC = (<any>reflectionTexture).boundingBoxSize ? true : false;
  1205. break;
  1206. }
  1207. if (reflectionTexture.coordinatesMode !== Texture.SKYBOX_MODE) {
  1208. if (reflectionTexture.irradianceTexture) {
  1209. defines.USEIRRADIANCEMAP = true;
  1210. defines.USESPHERICALFROMREFLECTIONMAP = false;
  1211. }
  1212. // Assume using spherical polynomial if the reflection texture is a cube map
  1213. else if (reflectionTexture.isCube) {
  1214. defines.USESPHERICALFROMREFLECTIONMAP = true;
  1215. defines.USEIRRADIANCEMAP = false;
  1216. if (this._forceIrradianceInFragment || this.realTimeFiltering || scene.getEngine().getCaps().maxVaryingVectors <= 8) {
  1217. defines.USESPHERICALINVERTEX = false;
  1218. }
  1219. else {
  1220. defines.USESPHERICALINVERTEX = true;
  1221. }
  1222. }
  1223. }
  1224. } else {
  1225. defines.REFLECTION = false;
  1226. defines.REFLECTIONMAP_3D = false;
  1227. defines.REFLECTIONMAP_SPHERICAL = false;
  1228. defines.REFLECTIONMAP_PLANAR = false;
  1229. defines.REFLECTIONMAP_CUBIC = false;
  1230. defines.USE_LOCAL_REFLECTIONMAP_CUBIC = false;
  1231. defines.REFLECTIONMAP_PROJECTION = false;
  1232. defines.REFLECTIONMAP_SKYBOX = false;
  1233. defines.REFLECTIONMAP_EXPLICIT = false;
  1234. defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
  1235. defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
  1236. defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
  1237. defines.INVERTCUBICMAP = false;
  1238. defines.USESPHERICALFROMREFLECTIONMAP = false;
  1239. defines.USEIRRADIANCEMAP = false;
  1240. defines.USESPHERICALINVERTEX = false;
  1241. defines.REFLECTIONMAP_OPPOSITEZ = false;
  1242. defines.LODINREFLECTIONALPHA = false;
  1243. defines.GAMMAREFLECTION = false;
  1244. defines.RGBDREFLECTION = false;
  1245. defines.LINEARSPECULARREFLECTION = false;
  1246. }
  1247. if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {
  1248. MaterialHelper.PrepareDefinesForMergedUV(this._lightmapTexture, defines, "LIGHTMAP");
  1249. defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;
  1250. defines.GAMMALIGHTMAP = this._lightmapTexture.gammaSpace;
  1251. defines.RGBDLIGHTMAP = this._lightmapTexture.isRGBD;
  1252. } else {
  1253. defines.LIGHTMAP = false;
  1254. }
  1255. if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {
  1256. MaterialHelper.PrepareDefinesForMergedUV(this._emissiveTexture, defines, "EMISSIVE");
  1257. } else {
  1258. defines.EMISSIVE = false;
  1259. }
  1260. if (MaterialFlags.SpecularTextureEnabled) {
  1261. if (this._metallicTexture) {
  1262. MaterialHelper.PrepareDefinesForMergedUV(this._metallicTexture, defines, "REFLECTIVITY");
  1263. defines.ROUGHNESSSTOREINMETALMAPALPHA = this._useRoughnessFromMetallicTextureAlpha;
  1264. defines.ROUGHNESSSTOREINMETALMAPGREEN = !this._useRoughnessFromMetallicTextureAlpha && this._useRoughnessFromMetallicTextureGreen;
  1265. defines.METALLNESSSTOREINMETALMAPBLUE = this._useMetallnessFromMetallicTextureBlue;
  1266. defines.AOSTOREINMETALMAPRED = this._useAmbientOcclusionFromMetallicTextureRed;
  1267. }
  1268. else if (this._reflectivityTexture) {
  1269. MaterialHelper.PrepareDefinesForMergedUV(this._reflectivityTexture, defines, "REFLECTIVITY");
  1270. defines.MICROSURFACEFROMREFLECTIVITYMAP = this._useMicroSurfaceFromReflectivityMapAlpha;
  1271. defines.MICROSURFACEAUTOMATIC = this._useAutoMicroSurfaceFromReflectivityMap;
  1272. } else {
  1273. defines.REFLECTIVITY = false;
  1274. }
  1275. if (this._metallicReflectanceTexture) {
  1276. MaterialHelper.PrepareDefinesForMergedUV(this._metallicReflectanceTexture, defines, "METALLIC_REFLECTANCE");
  1277. } else {
  1278. defines.METALLIC_REFLECTANCE = false;
  1279. }
  1280. if (this._microSurfaceTexture) {
  1281. MaterialHelper.PrepareDefinesForMergedUV(this._microSurfaceTexture, defines, "MICROSURFACEMAP");
  1282. } else {
  1283. defines.MICROSURFACEMAP = false;
  1284. }
  1285. } else {
  1286. defines.REFLECTIVITY = false;
  1287. defines.MICROSURFACEMAP = false;
  1288. }
  1289. if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {
  1290. MaterialHelper.PrepareDefinesForMergedUV(this._bumpTexture, defines, "BUMP");
  1291. if (this._useParallax && this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
  1292. defines.PARALLAX = true;
  1293. defines.PARALLAXOCCLUSION = !!this._useParallaxOcclusion;
  1294. }
  1295. else {
  1296. defines.PARALLAX = false;
  1297. }
  1298. defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;
  1299. } else {
  1300. defines.BUMP = false;
  1301. }
  1302. if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {
  1303. defines.ENVIRONMENTBRDF = true;
  1304. // Not actual true RGBD, only the B chanel is encoded as RGBD for sheen.
  1305. defines.ENVIRONMENTBRDF_RGBD = this._environmentBRDFTexture.isRGBD;
  1306. } else {
  1307. defines.ENVIRONMENTBRDF = false;
  1308. defines.ENVIRONMENTBRDF_RGBD = false;
  1309. }
  1310. if (this._shouldUseAlphaFromAlbedoTexture()) {
  1311. defines.ALPHAFROMALBEDO = true;
  1312. } else {
  1313. defines.ALPHAFROMALBEDO = false;
  1314. }
  1315. }
  1316. defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
  1317. if (this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_STANDARD) {
  1318. defines.USEPHYSICALLIGHTFALLOFF = false;
  1319. defines.USEGLTFLIGHTFALLOFF = false;
  1320. }
  1321. else if (this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_GLTF) {
  1322. defines.USEPHYSICALLIGHTFALLOFF = false;
  1323. defines.USEGLTFLIGHTFALLOFF = true;
  1324. }
  1325. else {
  1326. defines.USEPHYSICALLIGHTFALLOFF = true;
  1327. defines.USEGLTFLIGHTFALLOFF = false;
  1328. }
  1329. defines.RADIANCEOVERALPHA = this._useRadianceOverAlpha;
  1330. if (!this.backFaceCulling && this._twoSidedLighting) {
  1331. defines.TWOSIDEDLIGHTING = true;
  1332. } else {
  1333. defines.TWOSIDEDLIGHTING = false;
  1334. }
  1335. defines.SPECULARAA = scene.getEngine().getCaps().standardDerivatives && this._enableSpecularAntiAliasing;
  1336. }
  1337. if (defines._areTexturesDirty || defines._areMiscDirty) {
  1338. defines.ALPHATESTVALUE = `${this._alphaCutOff}${this._alphaCutOff % 1 === 0 ? "." : ""}`;
  1339. defines.PREMULTIPLYALPHA = (this.alphaMode === Constants.ALPHA_PREMULTIPLIED || this.alphaMode === Constants.ALPHA_PREMULTIPLIED_PORTERDUFF);
  1340. defines.ALPHABLEND = this.needAlphaBlendingForMesh(mesh);
  1341. defines.ALPHAFRESNEL = this._useAlphaFresnel || this._useLinearAlphaFresnel;
  1342. defines.LINEARALPHAFRESNEL = this._useLinearAlphaFresnel;
  1343. }
  1344. if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
  1345. this._imageProcessingConfiguration.prepareDefines(defines);
  1346. }
  1347. defines.FORCENORMALFORWARD = this._forceNormalForward;
  1348. defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
  1349. defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
  1350. // Misc.
  1351. if (defines._areMiscDirty) {
  1352. MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
  1353. defines.UNLIT = this._unlit || ((this.pointsCloud || this.wireframe) && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
  1354. defines.DEBUGMODE = this._debugMode;
  1355. }
  1356. // External config
  1357. this.detailMap.prepareDefines(defines, scene);
  1358. this.subSurface.prepareDefines(defines, scene);
  1359. this.clearCoat.prepareDefines(defines, scene);
  1360. this.anisotropy.prepareDefines(defines, mesh, scene);
  1361. this.brdf.prepareDefines(defines);
  1362. this.sheen.prepareDefines(defines, scene);
  1363. // Values that need to be evaluated on every frame
  1364. MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, useClipPlane, useThinInstances);
  1365. // Attribs
  1366. MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRBaseMaterial.PBRMATERIAL_OPAQUE);
  1367. }
  1368. /**
  1369. * Force shader compilation
  1370. */
  1371. public forceCompilation(mesh: AbstractMesh, onCompiled?: (material: Material) => void, options?: Partial<IMaterialCompilationOptions>): void {
  1372. const localOptions = {
  1373. clipPlane: false,
  1374. useInstances: false,
  1375. ...options
  1376. };
  1377. const defines = new PBRMaterialDefines();
  1378. const effect = this._prepareEffect(mesh, defines, undefined, undefined, localOptions.useInstances, localOptions.clipPlane, mesh.hasThinInstances)!;
  1379. if (this._onEffectCreatedObservable) {
  1380. onCreatedEffectParameters.effect = effect;
  1381. onCreatedEffectParameters.subMesh = null;
  1382. this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);
  1383. }
  1384. if (effect.isReady()) {
  1385. if (onCompiled) {
  1386. onCompiled(this);
  1387. }
  1388. }
  1389. else {
  1390. effect.onCompileObservable.add(() => {
  1391. if (onCompiled) {
  1392. onCompiled(this);
  1393. }
  1394. });
  1395. }
  1396. }
  1397. /**
  1398. * Initializes the uniform buffer layout for the shader.
  1399. */
  1400. public buildUniformLayout(): void {
  1401. // Order is important !
  1402. let ubo = this._uniformBuffer;
  1403. ubo.addUniform("vAlbedoInfos", 2);
  1404. ubo.addUniform("vAmbientInfos", 4);
  1405. ubo.addUniform("vOpacityInfos", 2);
  1406. ubo.addUniform("vEmissiveInfos", 2);
  1407. ubo.addUniform("vLightmapInfos", 2);
  1408. ubo.addUniform("vReflectivityInfos", 3);
  1409. ubo.addUniform("vMicroSurfaceSamplerInfos", 2);
  1410. ubo.addUniform("vReflectionInfos", 2);
  1411. ubo.addUniform("vReflectionFilteringInfo", 2);
  1412. ubo.addUniform("vReflectionPosition", 3);
  1413. ubo.addUniform("vReflectionSize", 3);
  1414. ubo.addUniform("vBumpInfos", 3);
  1415. ubo.addUniform("albedoMatrix", 16);
  1416. ubo.addUniform("ambientMatrix", 16);
  1417. ubo.addUniform("opacityMatrix", 16);
  1418. ubo.addUniform("emissiveMatrix", 16);
  1419. ubo.addUniform("lightmapMatrix", 16);
  1420. ubo.addUniform("reflectivityMatrix", 16);
  1421. ubo.addUniform("microSurfaceSamplerMatrix", 16);
  1422. ubo.addUniform("bumpMatrix", 16);
  1423. ubo.addUniform("vTangentSpaceParams", 2);
  1424. ubo.addUniform("reflectionMatrix", 16);
  1425. ubo.addUniform("vReflectionColor", 3);
  1426. ubo.addUniform("vAlbedoColor", 4);
  1427. ubo.addUniform("vLightingIntensity", 4);
  1428. ubo.addUniform("vReflectionMicrosurfaceInfos", 3);
  1429. ubo.addUniform("pointSize", 1);
  1430. ubo.addUniform("vReflectivityColor", 4);
  1431. ubo.addUniform("vEmissiveColor", 3);
  1432. ubo.addUniform("visibility", 1);
  1433. ubo.addUniform("vMetallicReflectanceFactors", 4);
  1434. ubo.addUniform("vMetallicReflectanceInfos", 2);
  1435. ubo.addUniform("metallicReflectanceMatrix", 16);
  1436. PBRClearCoatConfiguration.PrepareUniformBuffer(ubo);
  1437. PBRAnisotropicConfiguration.PrepareUniformBuffer(ubo);
  1438. PBRSheenConfiguration.PrepareUniformBuffer(ubo);
  1439. PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
  1440. DetailMapConfiguration.PrepareUniformBuffer(ubo);
  1441. ubo.create();
  1442. }
  1443. /**
  1444. * Unbinds the material from the mesh
  1445. */
  1446. public unbind(): void {
  1447. if (this._activeEffect) {
  1448. let needFlag = false;
  1449. if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
  1450. this._activeEffect.setTexture("reflection2DSampler", null);
  1451. needFlag = true;
  1452. }
  1453. if (this.subSurface.unbind(this._activeEffect)) {
  1454. needFlag = true;
  1455. }
  1456. if (needFlag) {
  1457. this._markAllSubMeshesAsTexturesDirty();
  1458. }
  1459. }
  1460. super.unbind();
  1461. }
  1462. /**
  1463. * Binds the submesh data.
  1464. * @param world - The world matrix.
  1465. * @param mesh - The BJS mesh.
  1466. * @param subMesh - A submesh of the BJS mesh.
  1467. */
  1468. public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
  1469. var scene = this.getScene();
  1470. var defines = <PBRMaterialDefines>subMesh._materialDefines;
  1471. if (!defines) {
  1472. return;
  1473. }
  1474. var effect = subMesh.effect;
  1475. if (!effect) {
  1476. return;
  1477. }
  1478. this._activeEffect = effect;
  1479. // Matrices
  1480. if (!defines.INSTANCES || defines.THIN_INSTANCES) {
  1481. this.bindOnlyWorldMatrix(world);
  1482. this.prePassConfiguration.bindForSubMesh(this._activeEffect, scene, mesh, world, this.isFrozen);
  1483. }
  1484. // Normal Matrix
  1485. if (defines.OBJECTSPACE_NORMALMAP) {
  1486. world.toNormalMatrix(this._normalMatrix);
  1487. this.bindOnlyNormalMatrix(this._normalMatrix);
  1488. }
  1489. let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
  1490. // Bones
  1491. MaterialHelper.BindBonesParameters(mesh, this._activeEffect, this.prePassConfiguration);
  1492. let reflectionTexture: Nullable<BaseTexture> = null;
  1493. let ubo = this._uniformBuffer;
  1494. if (mustRebind) {
  1495. var engine = scene.getEngine();
  1496. ubo.bindToEffect(effect, "Material");
  1497. this.bindViewProjection(effect);
  1498. reflectionTexture = this._getReflectionTexture();
  1499. if (!ubo.useUbo || !this.isFrozen || !ubo.isSync) {
  1500. // Texture uniforms
  1501. if (scene.texturesEnabled) {
  1502. if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
  1503. ubo.updateFloat2("vAlbedoInfos", this._albedoTexture.coordinatesIndex, this._albedoTexture.level);
  1504. MaterialHelper.BindTextureMatrix(this._albedoTexture, ubo, "albedo");
  1505. }
  1506. if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
  1507. ubo.updateFloat4("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level, this._ambientTextureStrength, this._ambientTextureImpactOnAnalyticalLights);
  1508. MaterialHelper.BindTextureMatrix(this._ambientTexture, ubo, "ambient");
  1509. }
  1510. if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {
  1511. ubo.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
  1512. MaterialHelper.BindTextureMatrix(this._opacityTexture, ubo, "opacity");
  1513. }
  1514. if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
  1515. ubo.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
  1516. ubo.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
  1517. if ((<any>reflectionTexture).boundingBoxSize) {
  1518. let cubeTexture = <CubeTexture>reflectionTexture;
  1519. ubo.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
  1520. ubo.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
  1521. }
  1522. if (this.realTimeFiltering) {
  1523. const width = reflectionTexture.getSize().width;
  1524. ubo.updateFloat2("vReflectionFilteringInfo", width, Scalar.Log2(width));
  1525. }
  1526. if (!defines.USEIRRADIANCEMAP) {
  1527. var polynomials = reflectionTexture.sphericalPolynomial;
  1528. if (defines.USESPHERICALFROMREFLECTIONMAP && polynomials) {
  1529. if (defines.SPHERICAL_HARMONICS) {
  1530. const preScaledHarmonics = polynomials.preScaledHarmonics;
  1531. this._activeEffect.setVector3("vSphericalL00", preScaledHarmonics.l00);
  1532. this._activeEffect.setVector3("vSphericalL1_1", preScaledHarmonics.l1_1);
  1533. this._activeEffect.setVector3("vSphericalL10", preScaledHarmonics.l10);
  1534. this._activeEffect.setVector3("vSphericalL11", preScaledHarmonics.l11);
  1535. this._activeEffect.setVector3("vSphericalL2_2", preScaledHarmonics.l2_2);
  1536. this._activeEffect.setVector3("vSphericalL2_1", preScaledHarmonics.l2_1);
  1537. this._activeEffect.setVector3("vSphericalL20", preScaledHarmonics.l20);
  1538. this._activeEffect.setVector3("vSphericalL21", preScaledHarmonics.l21);
  1539. this._activeEffect.setVector3("vSphericalL22", preScaledHarmonics.l22);
  1540. }
  1541. else {
  1542. this._activeEffect.setFloat3("vSphericalX", polynomials.x.x, polynomials.x.y, polynomials.x.z);
  1543. this._activeEffect.setFloat3("vSphericalY", polynomials.y.x, polynomials.y.y, polynomials.y.z);
  1544. this._activeEffect.setFloat3("vSphericalZ", polynomials.z.x, polynomials.z.y, polynomials.z.z);
  1545. this._activeEffect.setFloat3("vSphericalXX_ZZ", polynomials.xx.x - polynomials.zz.x,
  1546. polynomials.xx.y - polynomials.zz.y,
  1547. polynomials.xx.z - polynomials.zz.z);
  1548. this._activeEffect.setFloat3("vSphericalYY_ZZ", polynomials.yy.x - polynomials.zz.x,
  1549. polynomials.yy.y - polynomials.zz.y,
  1550. polynomials.yy.z - polynomials.zz.z);
  1551. this._activeEffect.setFloat3("vSphericalZZ", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z);
  1552. this._activeEffect.setFloat3("vSphericalXY", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z);
  1553. this._activeEffect.setFloat3("vSphericalYZ", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z);
  1554. this._activeEffect.setFloat3("vSphericalZX", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);
  1555. }
  1556. }
  1557. }
  1558. ubo.updateFloat3("vReflectionMicrosurfaceInfos",
  1559. reflectionTexture.getSize().width,
  1560. reflectionTexture.lodGenerationScale,
  1561. reflectionTexture.lodGenerationOffset);
  1562. }
  1563. if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {
  1564. ubo.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
  1565. MaterialHelper.BindTextureMatrix(this._emissiveTexture, ubo, "emissive");
  1566. }
  1567. if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {
  1568. ubo.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
  1569. MaterialHelper.BindTextureMatrix(this._lightmapTexture, ubo, "lightmap");
  1570. }
  1571. if (MaterialFlags.SpecularTextureEnabled) {
  1572. if (this._metallicTexture) {
  1573. ubo.updateFloat3("vReflectivityInfos", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength);
  1574. MaterialHelper.BindTextureMatrix(this._metallicTexture, ubo, "reflectivity");
  1575. }
  1576. else if (this._reflectivityTexture) {
  1577. ubo.updateFloat3("vReflectivityInfos", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0);
  1578. MaterialHelper.BindTextureMatrix(this._reflectivityTexture, ubo, "reflectivity");
  1579. }
  1580. if (this._metallicReflectanceTexture) {
  1581. ubo.updateFloat2("vMetallicReflectanceInfos", this._metallicReflectanceTexture.coordinatesIndex, this._metallicReflectanceTexture.level);
  1582. MaterialHelper.BindTextureMatrix(this._metallicReflectanceTexture, ubo, "metallicReflectance");
  1583. }
  1584. if (this._microSurfaceTexture) {
  1585. ubo.updateFloat2("vMicroSurfaceSamplerInfos", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level);
  1586. MaterialHelper.BindTextureMatrix(this._microSurfaceTexture, ubo, "microSurfaceSampler");
  1587. }
  1588. }
  1589. if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {
  1590. ubo.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias);
  1591. MaterialHelper.BindTextureMatrix(this._bumpTexture, ubo, "bump");
  1592. if (scene._mirroredCameraPosition) {
  1593. ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
  1594. } else {
  1595. ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
  1596. }
  1597. }
  1598. }
  1599. // Point size
  1600. if (this.pointsCloud) {
  1601. ubo.updateFloat("pointSize", this.pointSize);
  1602. }
  1603. // Colors
  1604. if (defines.METALLICWORKFLOW) {
  1605. TmpColors.Color3[0].r = (this._metallic === undefined || this._metallic === null) ? 1 : this._metallic;
  1606. TmpColors.Color3[0].g = (this._roughness === undefined || this._roughness === null) ? 1 : this._roughness;
  1607. ubo.updateColor4("vReflectivityColor", TmpColors.Color3[0], 1);
  1608. const ior = this.subSurface.indexOfRefraction;
  1609. const outside_ior = 1; // consider air as clear coat and other layaers would remap in the shader.
  1610. // We are here deriving our default reflectance from a common value for none metallic surface.
  1611. // Based of the schlick fresnel approximation model
  1612. // for dielectrics.
  1613. const f0 = Math.pow((ior - outside_ior) / (ior + outside_ior), 2);
  1614. // Tweak the default F0 and F90 based on our given setup
  1615. this._metallicReflectanceColor.scaleToRef(f0 * this._metallicF0Factor, TmpColors.Color3[0]);
  1616. const metallicF90 = this._metallicF0Factor;
  1617. ubo.updateColor4("vMetallicReflectanceFactors", TmpColors.Color3[0], metallicF90);
  1618. }
  1619. else {
  1620. ubo.updateColor4("vReflectivityColor", this._reflectivityColor, this._microSurface);
  1621. }
  1622. ubo.updateColor3("vEmissiveColor", MaterialFlags.EmissiveTextureEnabled ? this._emissiveColor : Color3.BlackReadOnly);
  1623. ubo.updateColor3("vReflectionColor", this._reflectionColor);
  1624. if (!defines.SS_REFRACTION && this.subSurface.linkRefractionWithTransparency) {
  1625. ubo.updateColor4("vAlbedoColor", this._albedoColor, 1);
  1626. }
  1627. else {
  1628. ubo.updateColor4("vAlbedoColor", this._albedoColor, this.alpha);
  1629. }
  1630. // Misc
  1631. this._lightingInfos.x = this._directIntensity;
  1632. this._lightingInfos.y = this._emissiveIntensity;
  1633. this._lightingInfos.z = this._environmentIntensity * scene.environmentIntensity;
  1634. this._lightingInfos.w = this._specularIntensity;
  1635. ubo.updateVector4("vLightingIntensity", this._lightingInfos);
  1636. }
  1637. // Visibility
  1638. ubo.updateFloat("visibility", mesh.visibility);
  1639. // Textures
  1640. if (scene.texturesEnabled) {
  1641. if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
  1642. ubo.setTexture("albedoSampler", this._albedoTexture);
  1643. }
  1644. if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
  1645. ubo.setTexture("ambientSampler", this._ambientTexture);
  1646. }
  1647. if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {
  1648. ubo.setTexture("opacitySampler", this._opacityTexture);
  1649. }
  1650. if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
  1651. if (defines.LODBASEDMICROSFURACE) {
  1652. ubo.setTexture("reflectionSampler", reflectionTexture);
  1653. }
  1654. else {
  1655. ubo.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
  1656. ubo.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
  1657. ubo.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
  1658. }
  1659. if (defines.USEIRRADIANCEMAP) {
  1660. ubo.setTexture("irradianceSampler", reflectionTexture.irradianceTexture);
  1661. }
  1662. }
  1663. if (defines.ENVIRONMENTBRDF) {
  1664. ubo.setTexture("environmentBrdfSampler", this._environmentBRDFTexture);
  1665. }
  1666. if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {
  1667. ubo.setTexture("emissiveSampler", this._emissiveTexture);
  1668. }
  1669. if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {
  1670. ubo.setTexture("lightmapSampler", this._lightmapTexture);
  1671. }
  1672. if (MaterialFlags.SpecularTextureEnabled) {
  1673. if (this._metallicTexture) {
  1674. ubo.setTexture("reflectivitySampler", this._metallicTexture);
  1675. }
  1676. else if (this._reflectivityTexture) {
  1677. ubo.setTexture("reflectivitySampler", this._reflectivityTexture);
  1678. }
  1679. if (this._metallicReflectanceTexture) {
  1680. ubo.setTexture("metallicReflectanceSampler", this._metallicReflectanceTexture);
  1681. }
  1682. if (this._microSurfaceTexture) {
  1683. ubo.setTexture("microSurfaceSampler", this._microSurfaceTexture);
  1684. }
  1685. }
  1686. if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {
  1687. ubo.setTexture("bumpSampler", this._bumpTexture);
  1688. }
  1689. }
  1690. this.detailMap.bindForSubMesh(ubo, scene, this.isFrozen);
  1691. this.subSurface.bindForSubMesh(ubo, scene, engine, this.isFrozen, defines.LODBASEDMICROSFURACE, this.realTimeFiltering);
  1692. this.clearCoat.bindForSubMesh(ubo, scene, engine, this._disableBumpMap, this.isFrozen, this._invertNormalMapX, this._invertNormalMapY);
  1693. this.anisotropy.bindForSubMesh(ubo, scene, this.isFrozen);
  1694. this.sheen.bindForSubMesh(ubo, scene, this.isFrozen);
  1695. // Clip plane
  1696. MaterialHelper.BindClipPlane(this._activeEffect, scene);
  1697. // Colors
  1698. scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor);
  1699. var eyePosition = scene._forcedViewPosition ? scene._forcedViewPosition : (scene._mirroredCameraPosition ? scene._mirroredCameraPosition : (<Camera>scene.activeCamera).globalPosition);
  1700. var invertNormal = (scene.useRightHandedSystem === (scene._mirroredCameraPosition != null));
  1701. effect.setFloat4("vEyePosition",
  1702. eyePosition.x,
  1703. eyePosition.y,
  1704. eyePosition.z,
  1705. invertNormal ? -1 : 1);
  1706. effect.setColor3("vAmbientColor", this._globalAmbientColor);
  1707. effect.setFloat2("vDebugMode", this.debugLimit, this.debugFactor);
  1708. }
  1709. if (mustRebind || !this.isFrozen) {
  1710. // Lights
  1711. if (scene.lightsEnabled && !this._disableLighting) {
  1712. MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights, this._rebuildInParallel);
  1713. }
  1714. // View
  1715. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || reflectionTexture) {
  1716. this.bindView(effect);
  1717. }
  1718. // Fog
  1719. MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect, true);
  1720. // Morph targets
  1721. if (defines.NUM_MORPH_INFLUENCERS) {
  1722. MaterialHelper.BindMorphTargetParameters(mesh, this._activeEffect);
  1723. }
  1724. // image processing
  1725. this._imageProcessingConfiguration!.bind(this._activeEffect);
  1726. // Log. depth
  1727. MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
  1728. }
  1729. ubo.update();
  1730. this._afterBind(mesh, this._activeEffect);
  1731. }
  1732. /**
  1733. * Returns the animatable textures.
  1734. * @returns - Array of animatable textures.
  1735. */
  1736. public getAnimatables(): IAnimatable[] {
  1737. var results = [];
  1738. if (this._albedoTexture && this._albedoTexture.animations && this._albedoTexture.animations.length > 0) {
  1739. results.push(this._albedoTexture);
  1740. }
  1741. if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {
  1742. results.push(this._ambientTexture);
  1743. }
  1744. if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {
  1745. results.push(this._opacityTexture);
  1746. }
  1747. if (this._reflectionTexture && this._reflectionTexture.animations && this._reflectionTexture.animations.length > 0) {
  1748. results.push(this._reflectionTexture);
  1749. }
  1750. if (this._emissiveTexture && this._emissiveTexture.animations && this._emissiveTexture.animations.length > 0) {
  1751. results.push(this._emissiveTexture);
  1752. }
  1753. if (this._metallicTexture && this._metallicTexture.animations && this._metallicTexture.animations.length > 0) {
  1754. results.push(this._metallicTexture);
  1755. }
  1756. else if (this._reflectivityTexture && this._reflectivityTexture.animations && this._reflectivityTexture.animations.length > 0) {
  1757. results.push(this._reflectivityTexture);
  1758. }
  1759. if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {
  1760. results.push(this._bumpTexture);
  1761. }
  1762. if (this._lightmapTexture && this._lightmapTexture.animations && this._lightmapTexture.animations.length > 0) {
  1763. results.push(this._lightmapTexture);
  1764. }
  1765. this.detailMap.getAnimatables(results);
  1766. this.subSurface.getAnimatables(results);
  1767. this.clearCoat.getAnimatables(results);
  1768. this.sheen.getAnimatables(results);
  1769. this.anisotropy.getAnimatables(results);
  1770. return results;
  1771. }
  1772. /**
  1773. * Returns the texture used for reflections.
  1774. * @returns - Reflection texture if present. Otherwise, returns the environment texture.
  1775. */
  1776. private _getReflectionTexture(): Nullable<BaseTexture> {
  1777. if (this._reflectionTexture) {
  1778. return this._reflectionTexture;
  1779. }
  1780. return this.getScene().environmentTexture;
  1781. }
  1782. /**
  1783. * Returns an array of the actively used textures.
  1784. * @returns - Array of BaseTextures
  1785. */
  1786. public getActiveTextures(): BaseTexture[] {
  1787. var activeTextures = super.getActiveTextures();
  1788. if (this._albedoTexture) {
  1789. activeTextures.push(this._albedoTexture);
  1790. }
  1791. if (this._ambientTexture) {
  1792. activeTextures.push(this._ambientTexture);
  1793. }
  1794. if (this._opacityTexture) {
  1795. activeTextures.push(this._opacityTexture);
  1796. }
  1797. if (this._reflectionTexture) {
  1798. activeTextures.push(this._reflectionTexture);
  1799. }
  1800. if (this._emissiveTexture) {
  1801. activeTextures.push(this._emissiveTexture);
  1802. }
  1803. if (this._reflectivityTexture) {
  1804. activeTextures.push(this._reflectivityTexture);
  1805. }
  1806. if (this._metallicTexture) {
  1807. activeTextures.push(this._metallicTexture);
  1808. }
  1809. if (this._metallicReflectanceTexture) {
  1810. activeTextures.push(this._metallicReflectanceTexture);
  1811. }
  1812. if (this._microSurfaceTexture) {
  1813. activeTextures.push(this._microSurfaceTexture);
  1814. }
  1815. if (this._bumpTexture) {
  1816. activeTextures.push(this._bumpTexture);
  1817. }
  1818. if (this._lightmapTexture) {
  1819. activeTextures.push(this._lightmapTexture);
  1820. }
  1821. this.detailMap.getActiveTextures(activeTextures);
  1822. this.subSurface.getActiveTextures(activeTextures);
  1823. this.clearCoat.getActiveTextures(activeTextures);
  1824. this.sheen.getActiveTextures(activeTextures);
  1825. this.anisotropy.getActiveTextures(activeTextures);
  1826. return activeTextures;
  1827. }
  1828. /**
  1829. * Checks to see if a texture is used in the material.
  1830. * @param texture - Base texture to use.
  1831. * @returns - Boolean specifying if a texture is used in the material.
  1832. */
  1833. public hasTexture(texture: BaseTexture): boolean {
  1834. if (super.hasTexture(texture)) {
  1835. return true;
  1836. }
  1837. if (this._albedoTexture === texture) {
  1838. return true;
  1839. }
  1840. if (this._ambientTexture === texture) {
  1841. return true;
  1842. }
  1843. if (this._opacityTexture === texture) {
  1844. return true;
  1845. }
  1846. if (this._reflectionTexture === texture) {
  1847. return true;
  1848. }
  1849. if (this._reflectivityTexture === texture) {
  1850. return true;
  1851. }
  1852. if (this._metallicTexture === texture) {
  1853. return true;
  1854. }
  1855. if (this._metallicReflectanceTexture === texture) {
  1856. return true;
  1857. }
  1858. if (this._microSurfaceTexture === texture) {
  1859. return true;
  1860. }
  1861. if (this._bumpTexture === texture) {
  1862. return true;
  1863. }
  1864. if (this._lightmapTexture === texture) {
  1865. return true;
  1866. }
  1867. return this.detailMap.hasTexture(texture) ||
  1868. this.subSurface.hasTexture(texture) ||
  1869. this.clearCoat.hasTexture(texture) ||
  1870. this.sheen.hasTexture(texture) ||
  1871. this.anisotropy.hasTexture(texture);
  1872. }
  1873. /**
  1874. * Sets the required values to the prepass renderer.
  1875. * @param prePassRenderer defines the prepass renderer to setup
  1876. */
  1877. public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {
  1878. if (this.subSurface.isScatteringEnabled) {
  1879. let subSurfaceConfiguration = this.getScene().enableSubSurfaceForPrePass();
  1880. if (subSurfaceConfiguration) {
  1881. subSurfaceConfiguration.enabled = true;
  1882. }
  1883. return true;
  1884. }
  1885. return false;
  1886. }
  1887. /**
  1888. * Disposes the resources of the material.
  1889. * @param forceDisposeEffect - Forces the disposal of effects.
  1890. * @param forceDisposeTextures - Forces the disposal of all textures.
  1891. */
  1892. public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {
  1893. if (forceDisposeTextures) {
  1894. if (this._environmentBRDFTexture && this.getScene().environmentBRDFTexture !== this._environmentBRDFTexture) {
  1895. this._environmentBRDFTexture.dispose();
  1896. }
  1897. this._albedoTexture?.dispose();
  1898. this._ambientTexture?.dispose();
  1899. this._opacityTexture?.dispose();
  1900. this._reflectionTexture?.dispose();
  1901. this._emissiveTexture?.dispose();
  1902. this._metallicTexture?.dispose();
  1903. this._reflectivityTexture?.dispose();
  1904. this._bumpTexture?.dispose();
  1905. this._lightmapTexture?.dispose();
  1906. this._metallicReflectanceTexture?.dispose();
  1907. this._microSurfaceTexture?.dispose();
  1908. }
  1909. this.detailMap.dispose(forceDisposeTextures);
  1910. this.subSurface.dispose(forceDisposeTextures);
  1911. this.clearCoat.dispose(forceDisposeTextures);
  1912. this.sheen.dispose(forceDisposeTextures);
  1913. this.anisotropy.dispose(forceDisposeTextures);
  1914. this._renderTargets.dispose();
  1915. if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
  1916. this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
  1917. }
  1918. super.dispose(forceDisposeEffect, forceDisposeTextures);
  1919. }
  1920. }