UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

224 lines (222 loc) 9.69 kB
import { __decorate } from "../../tslib.es6.js"; import { MaterialDefines } from "../../Materials/materialDefines.js"; import { MaterialPluginBase } from "../../Materials/materialPluginBase.js"; import { PBRBaseMaterial } from "../../Materials/PBR/pbrBaseMaterial.js"; import { expandToProperty, serialize, serializeAsTexture } from "../../Misc/decorators.js"; import { RegisterClass } from "../../Misc/typeStore.js"; /** * @internal */ class MaterialIBLShadowsRenderDefines extends MaterialDefines { constructor() { super(...arguments); this.RENDER_WITH_IBL_SHADOWS = false; this.COLORED_IBL_SHADOWS = false; } } /** * Plugin used to render the contribution from IBL shadows. */ export class IBLShadowsPluginMaterial extends MaterialPluginBase { get isColored() { return this._isColored; } set isColored(value) { if (this._isColored === value) { return; } this._isColored = value; this._markAllSubMeshesAsTexturesDirty(); } _markAllSubMeshesAsTexturesDirty() { this._enable(this._isEnabled); this._internalMarkAllSubMeshesAsTexturesDirty(); } /** * Gets a boolean indicating that the plugin is compatible with a give shader language. * @returns true if the plugin is compatible with the shader language */ isCompatible() { return true; } constructor(material) { super(material, IBLShadowsPluginMaterial.Name, 310, new MaterialIBLShadowsRenderDefines()); /** * The opacity of the shadows. */ this.shadowOpacity = 1.0; this._isEnabled = false; this._isColored = false; /** * Defines if the plugin is enabled in the material. */ this.isEnabled = false; this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[1]; } prepareDefines(defines) { defines.RENDER_WITH_IBL_SHADOWS = this._isEnabled; defines.COLORED_IBL_SHADOWS = this.isColored; } getClassName() { return "IBLShadowsPluginMaterial"; } getUniforms() { return { ubo: [ { name: "renderTargetSize", size: 2, type: "vec2" }, { name: "shadowOpacity", size: 1, type: "float" }, ], fragment: `#ifdef RENDER_WITH_IBL_SHADOWS uniform vec2 renderTargetSize; uniform float shadowOpacity; #endif`, }; } getSamplers(samplers) { samplers.push("iblShadowsTexture"); } bindForSubMesh(uniformBuffer) { if (this._isEnabled) { uniformBuffer.bindTexture("iblShadowsTexture", this.iblShadowsTexture); uniformBuffer.updateFloat2("renderTargetSize", this._material.getScene().getEngine().getRenderWidth(), this._material.getScene().getEngine().getRenderHeight()); uniformBuffer.updateFloat("shadowOpacity", this.shadowOpacity); } } getCustomCode(shaderType, shaderLanguage) { let frag; if (shaderLanguage === 1 /* ShaderLanguage.WGSL */) { frag = { // eslint-disable-next-line @typescript-eslint/naming-convention CUSTOM_FRAGMENT_DEFINITIONS: ` #ifdef RENDER_WITH_IBL_SHADOWS var iblShadowsTextureSampler: sampler; var iblShadowsTexture: texture_2d<f32>; #ifdef COLORED_IBL_SHADOWS fn computeIndirectShadow() -> vec3f { var uv = fragmentInputs.position.xy / uniforms.renderTargetSize; var shadowValue: vec3f = textureSample(iblShadowsTexture, iblShadowsTextureSampler, uv).rgb; return mix(shadowValue, vec3f(1.0), 1.0 - uniforms.shadowOpacity); } #else fn computeIndirectShadow() -> vec2f { var uv = fragmentInputs.position.xy / uniforms.renderTargetSize; var shadowValue: vec2f = textureSample(iblShadowsTexture, iblShadowsTextureSampler, uv).rg; return mix(shadowValue, vec2f(1.0), 1.0 - uniforms.shadowOpacity); } #endif #endif `, }; if (this._material instanceof PBRBaseMaterial) { // eslint-disable-next-line @typescript-eslint/naming-convention frag["CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION"] = ` #ifdef RENDER_WITH_IBL_SHADOWS #ifndef UNLIT #ifdef REFLECTION #ifdef COLORED_IBL_SHADOWS var shadowValue: vec3f = computeIndirectShadow(); finalIrradiance *= shadowValue; finalRadianceScaled *= mix(vec3f(1.0), shadowValue, roughness); #else var shadowValue: vec2f = computeIndirectShadow(); finalIrradiance *= vec3f(shadowValue.x); finalRadianceScaled *= vec3f(mix(pow(shadowValue.y, 4.0), shadowValue.x, roughness)); #endif #endif #else finalDiffuse *= computeIndirectShadow().x; #endif #endif `; } else { frag["CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR"] = ` #ifdef RENDER_WITH_IBL_SHADOWS #ifdef COLORED_IBL_SHADOWS var shadowValue: vec3f = computeIndirectShadow(); color *= toGammaSpace(vec4f(shadowValue, 1.0f)); #else var shadowValue: vec2f = computeIndirectShadow(); color *= toGammaSpace(vec4f(shadowValue.x, shadowValue.x, shadowValue.x, 1.0f)); #endif #endif `; } } else { frag = { // eslint-disable-next-line @typescript-eslint/naming-convention CUSTOM_FRAGMENT_DEFINITIONS: ` #ifdef RENDER_WITH_IBL_SHADOWS uniform sampler2D iblShadowsTexture; #ifdef COLORED_IBL_SHADOWS vec3 computeIndirectShadow() { vec2 uv = gl_FragCoord.xy / renderTargetSize; vec3 shadowValue = texture2D(iblShadowsTexture, uv).rgb; return mix(shadowValue.rgb, vec3(1.0), 1.0 - shadowOpacity); } #else vec2 computeIndirectShadow() { vec2 uv = gl_FragCoord.xy / renderTargetSize; vec2 shadowValue = texture2D(iblShadowsTexture, uv).rg; return mix(shadowValue.rg, vec2(1.0), 1.0 - shadowOpacity); } #endif #endif `, }; if (this._material instanceof PBRBaseMaterial) { // eslint-disable-next-line @typescript-eslint/naming-convention frag["CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION"] = ` #ifdef RENDER_WITH_IBL_SHADOWS #ifndef UNLIT #ifdef REFLECTION #ifdef COLORED_IBL_SHADOWS vec3 shadowValue = computeIndirectShadow(); finalIrradiance.rgb *= shadowValue.rgb; finalRadianceScaled *= mix(vec3(1.0), shadowValue.rgb, roughness); #else vec2 shadowValue = computeIndirectShadow(); finalIrradiance *= shadowValue.x; finalRadianceScaled *= mix(pow(shadowValue.y, 4.0), shadowValue.x, roughness); #endif #endif #else finalDiffuse *= computeIndirectShadow().x; #endif #endif `; } else { frag["CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR"] = ` #ifdef RENDER_WITH_IBL_SHADOWS #ifdef COLORED_IBL_SHADOWS vec3 shadowValue = computeIndirectShadow(); color.rgb *= toGammaSpace(shadowValue.rgb); #else vec2 shadowValue = computeIndirectShadow(); color.rgb *= toGammaSpace(shadowValue.x); #endif #endif `; } } return shaderType === "vertex" ? null : frag; } } /** * Defines the name of the plugin. */ IBLShadowsPluginMaterial.Name = "IBLShadowsPluginMaterial"; __decorate([ serializeAsTexture() ], IBLShadowsPluginMaterial.prototype, "iblShadowsTexture", void 0); __decorate([ serialize() ], IBLShadowsPluginMaterial.prototype, "shadowOpacity", void 0); __decorate([ serialize(), expandToProperty("_markAllSubMeshesAsTexturesDirty") ], IBLShadowsPluginMaterial.prototype, "isEnabled", void 0); RegisterClass(`BABYLON.IBLShadowsPluginMaterial`, IBLShadowsPluginMaterial); //# sourceMappingURL=iblShadowsPluginMaterial.js.map