123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- import { __decorate } from "../tslib.es6.js";
- import { serializeAsMeshReference, serializeAsVector3 } from "../Misc/decorators.js";
- import { SerializationHelper } from "../Misc/decorators.serialization.js";
- import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture.js";
- import { Matrix, Vector3 } from "../Maths/math.vector.js";
- import { AbstractScene } from "../abstractScene.js";
- AbstractScene.prototype.removeReflectionProbe = function (toRemove) {
- if (!this.reflectionProbes) {
- return -1;
- }
- const index = this.reflectionProbes.indexOf(toRemove);
- if (index !== -1) {
- this.reflectionProbes.splice(index, 1);
- }
- return index;
- };
- AbstractScene.prototype.addReflectionProbe = function (newReflectionProbe) {
- if (!this.reflectionProbes) {
- this.reflectionProbes = [];
- }
- this.reflectionProbes.push(newReflectionProbe);
- };
- /**
- * Class used to generate realtime reflection / refraction cube textures
- * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/reflectionProbes
- */
- export class ReflectionProbe {
- /**
- * Creates a new reflection probe
- * @param name defines the name of the probe
- * @param size defines the texture resolution (for each face)
- * @param scene defines the hosting scene
- * @param generateMipMaps defines if mip maps should be generated automatically (true by default)
- * @param useFloat defines if HDR data (float data) should be used to store colors (false by default)
- * @param linearSpace defines if the probe should be generated in linear space or not (false by default)
- */
- constructor(
- /** defines the name of the probe */
- name, size, scene, generateMipMaps = true, useFloat = false, linearSpace = false) {
- this.name = name;
- this._viewMatrix = Matrix.Identity();
- this._target = Vector3.Zero();
- this._add = Vector3.Zero();
- this._invertYAxis = false;
- /** Gets or sets probe position (center of the cube map) */
- this.position = Vector3.Zero();
- /**
- * Gets or sets an object used to store user defined information for the reflection probe.
- */
- this.metadata = null;
- /** @internal */
- this._parentContainer = null;
- this._scene = scene;
- if (scene.getEngine().supportsUniformBuffers) {
- this._sceneUBOs = [];
- for (let i = 0; i < 6; ++i) {
- this._sceneUBOs.push(scene.createSceneUniformBuffer(`Scene for Reflection Probe (name "${name}") face #${i}`));
- }
- }
- // Create the scene field if not exist.
- if (!this._scene.reflectionProbes) {
- this._scene.reflectionProbes = [];
- }
- this._scene.reflectionProbes.push(this);
- let textureType = 0;
- if (useFloat) {
- const caps = this._scene.getEngine().getCaps();
- if (caps.textureHalfFloatRender) {
- textureType = 2;
- }
- else if (caps.textureFloatRender) {
- textureType = 1;
- }
- }
- this._renderTargetTexture = new RenderTargetTexture(name, size, scene, generateMipMaps, true, textureType, true);
- this._renderTargetTexture.gammaSpace = !linearSpace;
- this._renderTargetTexture.invertZ = scene.useRightHandedSystem;
- const useReverseDepthBuffer = scene.getEngine().useReverseDepthBuffer;
- this._renderTargetTexture.onBeforeRenderObservable.add((faceIndex) => {
- if (this._sceneUBOs) {
- scene.setSceneUniformBuffer(this._sceneUBOs[faceIndex]);
- scene.getSceneUniformBuffer().unbindEffect();
- }
- switch (faceIndex) {
- case 0:
- this._add.copyFromFloats(1, 0, 0);
- break;
- case 1:
- this._add.copyFromFloats(-1, 0, 0);
- break;
- case 2:
- this._add.copyFromFloats(0, this._invertYAxis ? 1 : -1, 0);
- break;
- case 3:
- this._add.copyFromFloats(0, this._invertYAxis ? -1 : 1, 0);
- break;
- case 4:
- this._add.copyFromFloats(0, 0, scene.useRightHandedSystem ? -1 : 1);
- break;
- case 5:
- this._add.copyFromFloats(0, 0, scene.useRightHandedSystem ? 1 : -1);
- break;
- }
- if (this._attachedMesh) {
- this.position.copyFrom(this._attachedMesh.getAbsolutePosition());
- }
- this.position.addToRef(this._add, this._target);
- const lookAtFunction = scene.useRightHandedSystem ? Matrix.LookAtRHToRef : Matrix.LookAtLHToRef;
- const perspectiveFunction = scene.useRightHandedSystem ? Matrix.PerspectiveFovRH : Matrix.PerspectiveFovLH;
- lookAtFunction(this.position, this._target, Vector3.Up(), this._viewMatrix);
- if (scene.activeCamera) {
- this._projectionMatrix = perspectiveFunction(Math.PI / 2, 1, useReverseDepthBuffer ? scene.activeCamera.maxZ : scene.activeCamera.minZ, useReverseDepthBuffer ? scene.activeCamera.minZ : scene.activeCamera.maxZ, this._scene.getEngine().isNDCHalfZRange);
- scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);
- if (scene.activeCamera.isRigCamera && !this._renderTargetTexture.activeCamera) {
- this._renderTargetTexture.activeCamera = scene.activeCamera.rigParent || null;
- }
- }
- scene._forcedViewPosition = this.position;
- });
- let currentApplyByPostProcess;
- this._renderTargetTexture.onBeforeBindObservable.add(() => {
- this._currentSceneUBO = scene.getSceneUniformBuffer();
- scene.getEngine()._debugPushGroup?.(`reflection probe generation for ${name}`, 1);
- currentApplyByPostProcess = this._scene.imageProcessingConfiguration.applyByPostProcess;
- if (linearSpace) {
- scene.imageProcessingConfiguration.applyByPostProcess = true;
- }
- });
- this._renderTargetTexture.onAfterUnbindObservable.add(() => {
- scene.imageProcessingConfiguration.applyByPostProcess = currentApplyByPostProcess;
- scene._forcedViewPosition = null;
- if (this._sceneUBOs) {
- scene.setSceneUniformBuffer(this._currentSceneUBO);
- }
- scene.updateTransformMatrix(true);
- scene.getEngine()._debugPopGroup?.(1);
- });
- }
- /** Gets or sets the number of samples to use for multi-sampling (0 by default). Required WebGL2 */
- get samples() {
- return this._renderTargetTexture.samples;
- }
- set samples(value) {
- this._renderTargetTexture.samples = value;
- }
- /** Gets or sets the refresh rate to use (on every frame by default) */
- get refreshRate() {
- return this._renderTargetTexture.refreshRate;
- }
- set refreshRate(value) {
- this._renderTargetTexture.refreshRate = value;
- }
- /**
- * Gets the hosting scene
- * @returns a Scene
- */
- getScene() {
- return this._scene;
- }
- /** Gets the internal CubeTexture used to render to */
- get cubeTexture() {
- return this._renderTargetTexture;
- }
- /** Gets or sets the list of meshes to render */
- get renderList() {
- return this._renderTargetTexture.renderList;
- }
- set renderList(value) {
- this._renderTargetTexture.renderList = value;
- }
- /**
- * Attach the probe to a specific mesh (Rendering will be done from attached mesh's position)
- * @param mesh defines the mesh to attach to
- */
- attachToMesh(mesh) {
- this._attachedMesh = mesh;
- }
- /**
- * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups
- * @param renderingGroupId The rendering group id corresponding to its index
- * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
- */
- setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil) {
- this._renderTargetTexture.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
- }
- /**
- * Clean all associated resources
- */
- dispose() {
- const index = this._scene.reflectionProbes.indexOf(this);
- if (index !== -1) {
- // Remove from the scene if found
- this._scene.reflectionProbes.splice(index, 1);
- }
- if (this._parentContainer) {
- const index = this._parentContainer.reflectionProbes.indexOf(this);
- if (index > -1) {
- this._parentContainer.reflectionProbes.splice(index, 1);
- }
- this._parentContainer = null;
- }
- if (this._renderTargetTexture) {
- this._renderTargetTexture.dispose();
- this._renderTargetTexture = null;
- }
- if (this._sceneUBOs) {
- for (const ubo of this._sceneUBOs) {
- ubo.dispose();
- }
- this._sceneUBOs = [];
- }
- }
- /**
- * Converts the reflection probe information to a readable string for debug purpose.
- * @param fullDetails Supports for multiple levels of logging within scene loading
- * @returns the human readable reflection probe info
- */
- toString(fullDetails) {
- let ret = "Name: " + this.name;
- if (fullDetails) {
- ret += ", position: " + this.position.toString();
- if (this._attachedMesh) {
- ret += ", attached mesh: " + this._attachedMesh.name;
- }
- }
- return ret;
- }
- /**
- * Get the class name of the refection probe.
- * @returns "ReflectionProbe"
- */
- getClassName() {
- return "ReflectionProbe";
- }
- /**
- * Serialize the reflection probe to a JSON representation we can easily use in the respective Parse function.
- * @returns The JSON representation of the texture
- */
- serialize() {
- const serializationObject = SerializationHelper.Serialize(this, this._renderTargetTexture.serialize());
- serializationObject.isReflectionProbe = true;
- serializationObject.metadata = this.metadata;
- return serializationObject;
- }
- /**
- * Parse the JSON representation of a reflection probe in order to recreate the reflection probe in the given scene.
- * @param parsedReflectionProbe Define the JSON representation of the reflection probe
- * @param scene Define the scene the parsed reflection probe should be instantiated in
- * @param rootUrl Define the root url of the parsing sequence in the case of relative dependencies
- * @returns The parsed reflection probe if successful
- */
- static Parse(parsedReflectionProbe, scene, rootUrl) {
- let reflectionProbe = null;
- if (scene.reflectionProbes) {
- for (let index = 0; index < scene.reflectionProbes.length; index++) {
- const rp = scene.reflectionProbes[index];
- if (rp.name === parsedReflectionProbe.name) {
- reflectionProbe = rp;
- break;
- }
- }
- }
- reflectionProbe = SerializationHelper.Parse(() => reflectionProbe || new ReflectionProbe(parsedReflectionProbe.name, parsedReflectionProbe.renderTargetSize, scene, parsedReflectionProbe._generateMipMaps), parsedReflectionProbe, scene, rootUrl);
- reflectionProbe.cubeTexture._waitingRenderList = parsedReflectionProbe.renderList;
- if (parsedReflectionProbe._attachedMesh) {
- reflectionProbe.attachToMesh(scene.getMeshById(parsedReflectionProbe._attachedMesh));
- }
- if (parsedReflectionProbe.metadata) {
- reflectionProbe.metadata = parsedReflectionProbe.metadata;
- }
- return reflectionProbe;
- }
- }
- __decorate([
- serializeAsMeshReference()
- ], ReflectionProbe.prototype, "_attachedMesh", void 0);
- __decorate([
- serializeAsVector3()
- ], ReflectionProbe.prototype, "position", void 0);
- //# sourceMappingURL=reflectionProbe.js.map
|