BMWPilote Posted July 26, 2018 Share Posted July 26, 2018 MaterialDefines is per SubMesh and if I have a lot of meshes in the Scene, the memory consumption can be crazy. For some reasons, I cannot merge my meshes (because I need to clone the picked mesh). My scene is static and the meshes are similar. I have only two types of meshes: 1. one use only diffuse color, diffuse texture, glossiness and specular color and IBL. 2. the other one has just an extra opacity value So, although I have a lot of meshes, theirs defines should really almost always the same. My question is that is there any way to share the MaterialDefines? Quote Link to comment Share on other sites More sharing options...
BMWPilote Posted July 26, 2018 Author Share Posted July 26, 2018 I thought about the worst case. Maybe I could use the pbr shader, and use ShaderMaterial with it? Quote Link to comment Share on other sites More sharing options...
Guest Posted July 26, 2018 Share Posted July 26, 2018 Well you can still merge everything which will provide a large memory boost and you can just keep a disabled mesh as source for the clone. Also, not tested but should work: just go through all submeshes and manually set the defines the one single value Quote Link to comment Share on other sites More sharing options...
BMWPilote Posted July 27, 2018 Author Share Posted July 27, 2018 10 hours ago, Deltakosh said: Well you can still merge everything which will provide a large memory boost and you can just keep a disabled mesh as source for the clone. Also, not tested but should work: just go through all submeshes and manually set the defines the one single value "you can just keep a disabled mesh as source for the clone". Could you please explain more? Once merged. The source meshes are all removed...How can I still clone picked mesh dynamically? Quote Link to comment Share on other sites More sharing options...
BMWPilote Posted July 27, 2018 Author Share Posted July 27, 2018 13 hours ago, Deltakosh said: Well you can still merge everything which will provide a large memory boost and you can just keep a disabled mesh as source for the clone. Also, not tested but should work: just go through all submeshes and manually set the defines the one single value Unluckily, just assigning the same MaterialDefines did not work. Only some of the meshes were displayed. Quote Link to comment Share on other sites More sharing options...
BMWPilote Posted July 27, 2018 Author Share Posted July 27, 2018 Is there anyway to separate the MaterialDefines to two parts, one per material and the other per subMesh? Quote Link to comment Share on other sites More sharing options...
Guest Posted July 27, 2018 Share Posted July 27, 2018 Can you repro the test your did for sharing the defines in the PG? I'll try to see if I can help Quote Link to comment Share on other sites More sharing options...
BMWPilote Posted July 28, 2018 Author Share Posted July 28, 2018 23 hours ago, Deltakosh said: Can you repro the test your did for sharing the defines in the PG? I'll try to see if I can help Actually I just copied the code of PBRBaseSimpleMaterial and instead of creating one PBRMaterialDefines for each SubMesh, I created a static PBRMaterailDefines and assign it to all the SubMeshes. Then some of the meshes could not be drawn correctly. Quote Link to comment Share on other sites More sharing options...
Guest Posted July 30, 2018 Share Posted July 30, 2018 Then please share it So we can all work on the same code base Quote Link to comment Share on other sites More sharing options...
BMWPilote Posted August 2, 2018 Author Share Posted August 2, 2018 On 7/31/2018 at 12:38 AM, Deltakosh said: Then please share it So we can all work on the same code base Finally I moved all what I don't need and now the Defines take lightly more than 300 bytes instead of 8000 bytes. import * as BABYLON from 'babylonjs'; import * as custom_pbr_vert from '../../Graphics/Shaders/glsl/custom_pbr_vert.glsl'; import * as custom_pbr_frag from '../../Graphics/Shaders/glsl/custom_pbr_frag.glsl'; import * as MaterialUtils from '../MaterialUtils'; import { MAX_CUTPLANE_COUNT, CUTPLANES_UNIFORM_NAME, CUTPLANE_COUNT_UNIFORM_NAME } from '../MaterialCommonDefinitions'; import { ExtraDataHolder } from '../ExtraDataHolder'; import { RenderOptions } from '../../Preferences'; import { EnhancedScene } from '../../Scene/EnhancedScene'; export class SimplifiedPBRMaterialDefinesShared { OPACITYRGB = false; ALPHAFROMALBEDO = false; SPECULAROVERALPHA = false; RADIANCEOVERALPHA = false; ALPHAFRESNEL = false; LINEARALPHAFRESNEL = false; PREMULTIPLYALPHA = false; METALLICWORKFLOW = false; ROUGHNESSSTOREINMETALMAPALPHA = false; ROUGHNESSSTOREINMETALMAPGREEN = false; METALLNESSSTOREINMETALMAPBLUE = false; AOSTOREINMETALMAPRED = false; ENVIRONMENTBRDF = false; USEPHYSICALLIGHTFALLOFF = false; TWOSIDEDLIGHTING = false; SHADOWFLOAT = false; FORCENORMALFORWARD = false; MICROSURFACEFROMREFLECTIVITYMAP = false; MICROSURFACEAUTOMATIC = false; LODBASEDMICROSFURACE = false; REFLECTION = false; REFLECTIONMAP_3D = false; REFLECTIONMAP_SPHERICAL = false; REFLECTIONMAP_PLANAR = false; REFLECTIONMAP_CUBIC = false; USE_LOCAL_REFLECTIONMAP_CUBIC = false; REFLECTIONMAP_PROJECTION = false; REFLECTIONMAP_SKYBOX = false; REFLECTIONMAP_EXPLICIT = false; REFLECTIONMAP_EQUIRECTANGULAR = false; REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false; REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false; INVERTCUBICMAP = false; USESPHERICALFROMREFLECTIONMAP = false; USESPHERICALINVERTEX = false; REFLECTIONMAP_OPPOSITEZ = false; LODINREFLECTIONALPHA = false; GAMMAREFLECTION = false; CUTPLANE = false; MAX_CUTPLANE_COUNT = MAX_CUTPLANE_COUNT; } export class SimplifiedPBRMaterialDefines extends BABYLON.MaterialDefines { PBR = true; MAINUV1 = false; MAINUV2 = false; UV1 = false; UV2 = false; ALBEDO = false; EMISSIVE = false; REFLECTIVITY = false; OPACITY = false; BUMP = false; ALBEDODIRECTUV = 0; EMISSIVEDIRECTUV = 0; REFLECTIVITYDIRECTUV = 0; OPACITYDIRECTUV = 0; BUMPDIRECTUV = 0; NORMAL = false; TANGENT = false; ALPHABLEND = false; SPECULARTERM = false; LOGARITHMICDEPTH = false; _shared: SimplifiedPBRMaterialDefinesShared; /** * Initializes the PBR Material defines. */ constructor(shared: SimplifiedPBRMaterialDefinesShared) { super(); this._shared = shared; this.rebuild(); } toString(): string { let result = super.toString(); let keys = Object.keys(this._shared); for (var index = 0; index < keys.length; index++) { var prop = keys[index]; var value = (this._shared as any)[prop]; var type = typeof value; switch (type) { case "number": case "string": result += "#define " + prop + " " + value + "\n"; break; default: if (value) { result += "#define " + prop + "\n"; } break; } } return result; } /** * Resets the PBR Material defines. */ reset(): void { super.reset(); this.PBR = true; } get keys(): string[] { return this._keys; } set keys(keys: string[]) { this._keys = keys; } } export abstract class SimplifiedPBRBaseSimpleMaterial extends BABYLON.PBRBaseSimpleMaterial implements ExtraDataHolder { protected _extraData: any; protected _extraDataDirty: boolean = true; protected _sharedDefines: SimplifiedPBRMaterialDefinesShared; constructor(name: string, scene: BABYLON.Scene, extraData: any) { super(name, scene); if (RenderOptions.useLogarithmicDepth) { this.useLogarithmicDepth = true; } let shader = BABYLON.Effect.ShadersStore['custom_pbr' + 'VertexShader']; if (!shader) { let custom_pbr_vertex_shader: string = custom_pbr_vert; BABYLON.Effect.ShadersStore['custom_pbr' + 'VertexShader'] = custom_pbr_vertex_shader; } shader = BABYLON.Effect.ShadersStore['custom_pbr' + 'FragmentShader']; if (!shader) { let custom_pbr_fragment_shader: string = custom_pbr_frag; BABYLON.Effect.ShadersStore['custom_pbr' + 'FragmentShader'] = custom_pbr_fragment_shader; } if (extraData) this._extraData = extraData; else this._extraData = {}; this.onBindObservable.add(() => { const scene = this.getScene() as EnhancedScene; if (this._extraDataDirty || (scene.extraDataDirty && this.alpha < 1.0)) { this.onCutPlanesUpdated(); this._extraDataDirty = false; } }); this._extraData.textureMaps = {}; this._sharedDefines = new SimplifiedPBRMaterialDefinesShared(); } bindForSubMesh(world: BABYLON.Matrix, mesh: BABYLON.Mesh, subMesh: BABYLON.SubMesh): void { var scene = this.getScene(); var defines = <SimplifiedPBRMaterialDefines>subMesh._materialDefines; if (!defines) { return; } var effect = subMesh.effect; if (!effect) { return; } this._activeEffect = effect; // Matrices this.bindOnlyWorldMatrix(world); let mustRebind = this._mustRebind(scene, effect, mesh.visibility); let reflectionTexture: BABYLON.Nullable<BABYLON.BaseTexture> = null; if (mustRebind) { this._uniformBuffer.bindToEffect(effect, "Material"); this.bindViewProjection(effect); reflectionTexture = this._getReflectionTexture(); if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync) { // Texture uniforms if (scene.texturesEnabled) { if (this._albedoTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) { this._uniformBuffer.updateFloat2("vAlbedoInfos", this._albedoTexture.coordinatesIndex, this._albedoTexture.level); BABYLON.MaterialHelper.BindTextureMatrix(this._albedoTexture, this._uniformBuffer, "albedo"); } if (this._opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) { this._uniformBuffer.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level); BABYLON.MaterialHelper.BindTextureMatrix(this._opacityTexture, this._uniformBuffer, "opacity"); } if (reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) { this._uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix()); this._uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, 0); if ((<any>reflectionTexture).boundingBoxSize) { let cubeTexture = <BABYLON.CubeTexture>reflectionTexture; this._uniformBuffer.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition); this._uniformBuffer.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize); } var polynomials = reflectionTexture.sphericalPolynomial; if (defines._shared.USESPHERICALFROMREFLECTIONMAP && polynomials) { this._activeEffect.setFloat3("vSphericalX", polynomials.x.x, polynomials.x.y, polynomials.x.z); this._activeEffect.setFloat3("vSphericalY", polynomials.y.x, polynomials.y.y, polynomials.y.z); this._activeEffect.setFloat3("vSphericalZ", polynomials.z.x, polynomials.z.y, polynomials.z.z); this._activeEffect.setFloat3("vSphericalXX_ZZ", polynomials.xx.x - polynomials.zz.x, polynomials.xx.y - polynomials.zz.y, polynomials.xx.z - polynomials.zz.z); this._activeEffect.setFloat3("vSphericalYY_ZZ", polynomials.yy.x - polynomials.zz.x, polynomials.yy.y - polynomials.zz.y, polynomials.yy.z - polynomials.zz.z); this._activeEffect.setFloat3("vSphericalZZ", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z); this._activeEffect.setFloat3("vSphericalXY", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z); this._activeEffect.setFloat3("vSphericalYZ", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z); this._activeEffect.setFloat3("vSphericalZX", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z); } this._uniformBuffer.updateFloat3("vReflectionMicrosurfaceInfos", reflectionTexture.getSize().width, reflectionTexture.lodGenerationScale, reflectionTexture.lodGenerationOffset); } if (this._emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) { this._uniformBuffer.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level); BABYLON.MaterialHelper.BindTextureMatrix(this._emissiveTexture, this._uniformBuffer, "emissive"); } if (BABYLON.StandardMaterial.SpecularTextureEnabled) { if (this._metallicTexture) { this._uniformBuffer.updateFloat3("vReflectivityInfos", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength); BABYLON.MaterialHelper.BindTextureMatrix(this._metallicTexture, this._uniformBuffer, "reflectivity"); } else if (this._reflectivityTexture) { this._uniformBuffer.updateFloat3("vReflectivityInfos", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0); BABYLON.MaterialHelper.BindTextureMatrix(this._reflectivityTexture, this._uniformBuffer, "reflectivity"); } if (this._microSurfaceTexture) { this._uniformBuffer.updateFloat2("vMicroSurfaceSamplerInfos", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level); BABYLON.MaterialHelper.BindTextureMatrix(this._microSurfaceTexture, this._uniformBuffer, "microSurfaceSampler"); } } if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && BABYLON.StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) { this._uniformBuffer.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias); BABYLON.MaterialHelper.BindTextureMatrix(this._bumpTexture, this._uniformBuffer, "bump"); if (scene._mirroredCameraPosition) { this._uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0); } else { this._uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0); } } } // Colors if (defines._shared.METALLICWORKFLOW) { BABYLON.PBRMaterial._scaledReflectivity.r = (this._metallic === undefined || this._metallic === null) ? 1 : this._metallic; BABYLON.PBRMaterial._scaledReflectivity.g = (this._roughness === undefined || this._roughness === null) ? 1 : this._roughness; this._uniformBuffer.updateColor4("vReflectivityColor", BABYLON.PBRMaterial._scaledReflectivity, 0); } else { this._uniformBuffer.updateColor4("vReflectivityColor", this._reflectivityColor, this._microSurface); } this._uniformBuffer.updateColor3("vEmissiveColor", this._emissiveColor); this._uniformBuffer.updateColor3("vReflectionColor", this._reflectionColor); this._uniformBuffer.updateColor4("vAlbedoColor", this._albedoColor, this.alpha * mesh.visibility); // Misc this._lightingInfos.x = this._directIntensity; this._lightingInfos.y = this._emissiveIntensity; this._lightingInfos.z = this._environmentIntensity; this._lightingInfos.w = this._specularIntensity; this._uniformBuffer.updateVector4("vLightingIntensity", this._lightingInfos); } // Textures if (scene.texturesEnabled) { if (this._albedoTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) { this._uniformBuffer.setTexture("albedoSampler", this._albedoTexture); } if (this._opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) { this._uniformBuffer.setTexture("opacitySampler", this._opacityTexture); } if (reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) { if (defines._shared.LODBASEDMICROSFURACE) { this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture); } else { this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture); this._uniformBuffer.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture); this._uniformBuffer.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture); } } if (defines._shared.ENVIRONMENTBRDF) { this._uniformBuffer.setTexture("environmentBrdfSampler", this._environmentBRDFTexture); } if (this._emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) { this._uniformBuffer.setTexture("emissiveSampler", this._emissiveTexture); } if (BABYLON.StandardMaterial.SpecularTextureEnabled) { if (this._metallicTexture) { this._uniformBuffer.setTexture("reflectivitySampler", this._metallicTexture); } else if (this._reflectivityTexture) { this._uniformBuffer.setTexture("reflectivitySampler", this._reflectivityTexture); } if (this._microSurfaceTexture) { this._uniformBuffer.setTexture("microSurfaceSampler", this._microSurfaceTexture); } } if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && BABYLON.StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) { this._uniformBuffer.setTexture("bumpSampler", this._bumpTexture); } } // Colors scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor); var eyePosition = scene._forcedViewPosition ? scene._forcedViewPosition : (scene._mirroredCameraPosition ? scene._mirroredCameraPosition : (<BABYLON.Camera>scene.activeCamera).globalPosition); var invertNormal = (scene.useRightHandedSystem === (scene._mirroredCameraPosition != null)); effect.setFloat4("vEyePosition", eyePosition.x, eyePosition.y, eyePosition.z, invertNormal ? -1 : 1); effect.setColor3("vAmbientColor", this._globalAmbientColor); } if (mustRebind || !this.isFrozen) { // Lights if (scene.lightsEnabled && !this._disableLighting) { BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights, this._usePhysicalLightFalloff); } // Log. depth BABYLON. MaterialHelper.BindLogDepth(defines, this._activeEffect, scene); } this._uniformBuffer.update(); this._afterBind(mesh, this._activeEffect); } getClassName(): string { return 'SimplifiedPBRBaseSimpleMaterial'; } get extraData(): any { return this._extraData; } get extraDataDirty(): boolean { return this._extraDataDirty; } set extraDataDirty(value: boolean) { this._extraDataDirty = value; } onCutPlanesUpdated(): void { if (this.extraData.cutPlanes) { MaterialUtils.updateCutPlanes(this.getEffect(), this.extraData.cutPlanes); } } isReadyForSubMesh(mesh: BABYLON.AbstractMesh, subMesh: BABYLON.SubMesh, useInstances?: boolean): boolean { if (subMesh.effect && this.isFrozen) { if (this._wasPreviouslyReady) { return true; } } if (!subMesh._materialDefines) { subMesh._materialDefines = new SimplifiedPBRMaterialDefines(this._sharedDefines); } const defines = <SimplifiedPBRMaterialDefines>subMesh._materialDefines; if (!this.checkReadyOnEveryCall && subMesh.effect) { if (defines._renderId === this.getScene().getRenderId()) { return true; } } const scene = this.getScene(); const engine = scene.getEngine(); if (defines._areTexturesDirty) { if (scene.texturesEnabled) { if (this._albedoTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) { if (!this._albedoTexture.isReadyOrNotBlocking()) { return false; } } if (this._opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) { if (!this._opacityTexture.isReadyOrNotBlocking()) { return false; } } var reflectionTexture = this._getReflectionTexture(); if (reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) { if (!reflectionTexture.isReadyOrNotBlocking()) { return false; } } if (this._emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) { if (!this._emissiveTexture.isReadyOrNotBlocking()) { return false; } } if (BABYLON.StandardMaterial.SpecularTextureEnabled) { if (this._metallicTexture) { if (!this._metallicTexture.isReadyOrNotBlocking()) { return false; } } else if (this._reflectivityTexture) { if (!this._reflectivityTexture.isReadyOrNotBlocking()) { return false; } } if (this._microSurfaceTexture) { if (!this._microSurfaceTexture.isReadyOrNotBlocking()) { return false; } } } if (engine.getCaps().standardDerivatives && this._bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) { // Bump texture cannot be not blocking. if (!this._bumpTexture.isReady()) { return false; } } if (this._environmentBRDFTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) { // This is blocking. if (!this._environmentBRDFTexture.isReady()) { return false; } } } } if (!engine.getCaps().standardDerivatives) { let bufferMesh = null; if (mesh.getClassName() === "InstancedMesh") { bufferMesh = (mesh as BABYLON.InstancedMesh).sourceMesh; } else if (mesh.getClassName() === "Mesh") { bufferMesh = mesh as BABYLON.Mesh; } if (bufferMesh && bufferMesh.geometry && bufferMesh.geometry.isReady() && !bufferMesh.geometry.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) { bufferMesh.createNormals(true); BABYLON.Tools.Warn("PBRMaterial: Normals have been created for the mesh: " + bufferMesh.name); } } const effect = this._prepareEnhancedEffect(mesh, defines, this.onCompiled, this.onError, useInstances); if (effect) { scene.resetCachedMaterial(); subMesh.setEffect(effect, defines); this.buildUniformLayout(); } if (!subMesh.effect || !subMesh.effect.isReady()) { return false; } defines._renderId = scene.getRenderId(); this._wasPreviouslyReady = true; return true; } protected _prepareEnhancedEffect(mesh: BABYLON.AbstractMesh, defines: SimplifiedPBRMaterialDefines, onCompiled: BABYLON.Nullable<(effect: BABYLON.Effect) => void> = null, onError: BABYLON.Nullable<(effect: BABYLON.Effect, errors: string) => void> = null, useInstances: BABYLON.Nullable<boolean> = null, useClipPlane: BABYLON.Nullable<boolean> = null): BABYLON.Nullable<BABYLON.Effect> { this._prepareSimplifiedDefines(mesh, defines, useInstances, useClipPlane); if (!defines.isDirty) { return null; } defines.markAsProcessed(); const scene = this.getScene(); const engine = scene.getEngine(); // Fallbacks let fallbacks = new BABYLON.EffectFallbacks(); let fallbackRank = 0; if (defines._shared.USESPHERICALINVERTEX) { fallbacks.addFallback(fallbackRank++, 'USESPHERICALINVERTEX'); } if (defines.LOGARITHMICDEPTH) { fallbacks.addFallback(fallbackRank, 'LOGARITHMICDEPTH'); } if (defines._shared.ENVIRONMENTBRDF) { fallbacks.addFallback(fallbackRank++, 'ENVIRONMENTBRDF'); } if (defines.TANGENT) { fallbacks.addFallback(fallbackRank++, 'TANGENT'); } if (defines.BUMP) { fallbacks.addFallback(fallbackRank++, 'BUMP'); } fallbackRank = BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank++); if (defines.SPECULARTERM) { fallbacks.addFallback(fallbackRank++, 'SPECULARTERM'); } if (defines._shared.USESPHERICALFROMREFLECTIONMAP) { fallbacks.addFallback(fallbackRank++, 'USESPHERICALFROMREFLECTIONMAP'); } if (defines.NORMAL) { fallbacks.addFallback(fallbackRank++, 'NORMAL'); } if (defines.EMISSIVE) { fallbacks.addFallback(fallbackRank++, 'EMISSIVE'); } //Attributes let attribs = [BABYLON.VertexBuffer.PositionKind]; if (defines.NORMAL) { attribs.push(BABYLON.VertexBuffer.NormalKind); } if (defines.TANGENT) { attribs.push(BABYLON.VertexBuffer.TangentKind); } if (defines.UV1) { attribs.push(BABYLON.VertexBuffer.UVKind); } if (defines.UV2) { attribs.push(BABYLON.VertexBuffer.UV2Kind); } let uniforms = ['world', 'view', 'viewProjection', 'vEyePosition', 'vLightsType', 'vAmbientColor', 'vAlbedoColor', 'vReflectivityColor', 'vEmissiveColor', 'vReflectionColor', 'vAlbedoInfos', 'vOpacityInfos', 'vReflectionInfos', 'vReflectionPosition', 'vReflectionSize', 'vEmissiveInfos', 'vReflectivityInfos', 'vMicroSurfaceSamplerInfos', 'vBumpInfos', 'albedoMatrix', 'opacityMatrix', 'reflectionMatrix', 'emissiveMatrix', 'reflectivityMatrix', 'normalMatrix', 'microSurfaceSamplerMatrix', 'bumpMatrix', 'vLightingIntensity', 'logarithmicDepthConstant', 'vSphericalX', 'vSphericalY', 'vSphericalZ', 'vSphericalXX', 'vSphericalYY', 'vSphericalZZ', 'vSphericalXY', 'vSphericalYZ', 'vSphericalZX', 'vReflectionMicrosurfaceInfos', 'vTangentSpaceParams', CUTPLANE_COUNT_UNIFORM_NAME, CUTPLANES_UNIFORM_NAME ]; if (this.extraData.cutPlanes.length > 0) { defines._shared.CUTPLANE = true; defines._shared.MAX_CUTPLANE_COUNT = MAX_CUTPLANE_COUNT; } let samplers = ['albedoSampler', 'reflectivitySampler', 'emissiveSampler', 'bumpSampler', 'opacitySampler', 'reflectionSampler', 'reflectionSamplerLow', 'reflectionSamplerHigh', 'microSurfaceSampler', 'environmentBrdfSampler']; let uniformBuffers = ['Material', 'Scene']; BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(<BABYLON.EffectCreationOptions>{ uniformsNames: uniforms, uniformBuffersNames: uniformBuffers, samplers: samplers, defines: defines, maxSimultaneousLights: this._maxSimultaneousLights }); if (!defines.keys) { defines.rebuild(); } let join = defines.toString(); defines.keys = undefined; return engine.createEffect('custom_pbr', <BABYLON.EffectCreationOptions>{ attributes: attribs, uniformsNames: uniforms, uniformBuffersNames: uniformBuffers, samplers: samplers, defines: join, fallbacks: fallbacks, onCompiled: onCompiled, onError: onError, indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights } }, engine); } private _prepareSimplifiedDefines(mesh: BABYLON.AbstractMesh, defines: SimplifiedPBRMaterialDefines, useInstances: BABYLON.Nullable<boolean> = null, useClipPlane: BABYLON.Nullable<boolean> = null): void { const scene = this.getScene(); // Lights //BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting); defines._needNormals = true; // Textures defines._shared.METALLICWORKFLOW = super.isMetallicWorkflow(); if (defines._areTexturesDirty) { defines._needUVs = false; if (scene.texturesEnabled) { if (scene.getEngine().getCaps().textureLOD) { defines._shared.LODBASEDMICROSFURACE = true; } if (this._albedoTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) { BABYLON.MaterialHelper.PrepareDefinesForMergedUV(this._albedoTexture, defines, "ALBEDO"); } else { defines.ALBEDO = false; } if (this._opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) { BABYLON.MaterialHelper.PrepareDefinesForMergedUV(this._opacityTexture, defines, "OPACITY"); defines._shared.OPACITYRGB = this._opacityTexture.getAlphaFromRGB; } else { defines.OPACITY = false; } var reflectionTexture = this._getReflectionTexture(); if (reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) { defines._shared.REFLECTION = true; defines._shared.GAMMAREFLECTION = reflectionTexture.gammaSpace; defines._shared.REFLECTIONMAP_OPPOSITEZ = this.getScene().useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ; defines._shared.LODINREFLECTIONALPHA = reflectionTexture.lodLevelInAlpha; if (reflectionTexture.coordinatesMode === BABYLON.Texture.INVCUBIC_MODE) { defines._shared.INVERTCUBICMAP = true; } defines._shared.REFLECTIONMAP_3D = reflectionTexture.isCube; switch (reflectionTexture.coordinatesMode) { case BABYLON.Texture.CUBIC_MODE: case BABYLON.Texture.INVCUBIC_MODE: defines._shared.REFLECTIONMAP_CUBIC = true; defines._shared.USE_LOCAL_REFLECTIONMAP_CUBIC = (<any>reflectionTexture).boundingBoxSize ? true : false; break; case BABYLON.Texture.EXPLICIT_MODE: defines._shared.REFLECTIONMAP_EXPLICIT = true; break; case BABYLON.Texture.PLANAR_MODE: defines._shared.REFLECTIONMAP_PLANAR = true; break; case BABYLON.Texture.PROJECTION_MODE: defines._shared.REFLECTIONMAP_PROJECTION = true; break; case BABYLON.Texture.SKYBOX_MODE: defines._shared.REFLECTIONMAP_SKYBOX = true; break; case BABYLON.Texture.SPHERICAL_MODE: defines._shared.REFLECTIONMAP_SPHERICAL = true; break; case BABYLON.Texture.EQUIRECTANGULAR_MODE: defines._shared.REFLECTIONMAP_EQUIRECTANGULAR = true; break; case BABYLON.Texture.FIXED_EQUIRECTANGULAR_MODE: defines._shared.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true; break; case BABYLON.Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE: defines._shared.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = true; break; } if (reflectionTexture.coordinatesMode !== BABYLON.Texture.SKYBOX_MODE) { if (reflectionTexture.sphericalPolynomial) { defines._shared.USESPHERICALFROMREFLECTIONMAP = true; if (this._forceIrradianceInFragment || scene.getEngine().getCaps().maxVaryingVectors <= 8) { defines._shared.USESPHERICALINVERTEX = false; } else { defines._shared.USESPHERICALINVERTEX = true; } } } } else { defines._shared.REFLECTION = false; defines._shared.REFLECTIONMAP_3D = false; defines._shared.REFLECTIONMAP_SPHERICAL = false; defines._shared.REFLECTIONMAP_PLANAR = false; defines._shared.REFLECTIONMAP_CUBIC = false; defines._shared.USE_LOCAL_REFLECTIONMAP_CUBIC = false; defines._shared.REFLECTIONMAP_PROJECTION = false; defines._shared.REFLECTIONMAP_SKYBOX = false; defines._shared.REFLECTIONMAP_EXPLICIT = false; defines._shared.REFLECTIONMAP_EQUIRECTANGULAR = false; defines._shared.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false; defines._shared.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false; defines._shared.INVERTCUBICMAP = false; defines._shared.USESPHERICALFROMREFLECTIONMAP = false; defines._shared.USESPHERICALINVERTEX = false; defines._shared.REFLECTIONMAP_OPPOSITEZ = false; defines._shared.LODINREFLECTIONALPHA = false; defines._shared.GAMMAREFLECTION = false; } if (this._emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) { BABYLON.MaterialHelper.PrepareDefinesForMergedUV(this._emissiveTexture, defines, "EMISSIVE"); } else { defines.EMISSIVE = false; } if (BABYLON.StandardMaterial.SpecularTextureEnabled) { if (this._metallicTexture) { BABYLON.MaterialHelper.PrepareDefinesForMergedUV(this._metallicTexture, defines, "REFLECTIVITY"); defines._shared.ROUGHNESSSTOREINMETALMAPALPHA = this._useRoughnessFromMetallicTextureAlpha; defines._shared.ROUGHNESSSTOREINMETALMAPGREEN = !this._useRoughnessFromMetallicTextureAlpha && this._useRoughnessFromMetallicTextureGreen; defines._shared.METALLNESSSTOREINMETALMAPBLUE = this._useMetallnessFromMetallicTextureBlue; defines._shared.AOSTOREINMETALMAPRED = this._useAmbientOcclusionFromMetallicTextureRed; } else if (this._reflectivityTexture) { BABYLON.MaterialHelper.PrepareDefinesForMergedUV(this._reflectivityTexture, defines, "REFLECTIVITY"); } else { defines.REFLECTIVITY = false; } } else { defines.REFLECTIVITY = false; } if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled && !this._disableBumpMap) { BABYLON.MaterialHelper.PrepareDefinesForMergedUV(this._bumpTexture, defines, "BUMP"); } else { defines.BUMP = false; } if (this._environmentBRDFTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) { defines._shared.ENVIRONMENTBRDF = true; } else { defines._shared.ENVIRONMENTBRDF = false; } if (this._shouldUseAlphaFromAlbedoTexture()) { defines._shared.ALPHAFROMALBEDO = true; } else { defines._shared.ALPHAFROMALBEDO = false; } } defines._shared.SPECULAROVERALPHA = this._useSpecularOverAlpha; defines._shared.USEPHYSICALLIGHTFALLOFF = this._usePhysicalLightFalloff; defines._shared.RADIANCEOVERALPHA = this._useRadianceOverAlpha; if (!this.backFaceCulling && this._twoSidedLighting) { defines._shared.TWOSIDEDLIGHTING = true; } else { defines._shared.TWOSIDEDLIGHTING = false; } defines._shared.PREMULTIPLYALPHA = (this.alphaMode === BABYLON.Engine.ALPHA_PREMULTIPLIED || this.alphaMode === BABYLON.Engine.ALPHA_PREMULTIPLIED_PORTERDUFF); defines.ALPHABLEND = this.needAlphaBlendingForMesh(mesh); defines._shared.ALPHAFRESNEL = this._useAlphaFresnel || this._useLinearAlphaFresnel; defines._shared.LINEARALPHAFRESNEL = this._useLinearAlphaFresnel; } defines._shared.FORCENORMALFORWARD = this._forceNormalForward; // Misc. this._pareDefinesForMisc(mesh, this._useLogarithmicDepth, defines); // Attribs this._prepareDefinesForAttributes(mesh, defines); } private _pareDefinesForMisc(mesh: BABYLON.AbstractMesh, useLogarithmicDepth: boolean, defines: any): void { if (defines._areMiscDirty) { defines["LOGARITHMICDEPTH"] = useLogarithmicDepth; } } private _prepareDefinesForAttributes(mesh: BABYLON.AbstractMesh, defines: any): boolean { if (!defines._areAttributesDirty && defines._needNormals === defines._normals && defines._needUVs === defines._uvs) { return false; } defines._normals = defines._needNormals; defines._uvs = defines._needUVs; defines["NORMAL"] = (defines._needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)); if (defines._needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) { defines["TANGENT"] = true; } if (defines._needUVs) { defines["UV1"] = mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind); defines["UV2"] = mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind); } else { defines["UV1"] = false; defines["UV2"] = false; } return true; } } Quote Link to comment Share on other sites More sharing options...
Guest Posted August 2, 2018 Share Posted August 2, 2018 Good job!! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.