소스 검색

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into master

David Catuhe 4 년 전
부모
커밋
e8570df4c4

+ 1 - 0
dist/preview release/what's new.md

@@ -71,6 +71,7 @@
 - Add support for detail maps in both the standard and PBR materials ([Popov72](https://github.com/Popov72))
 - Added abstractMesh method to get all particle systems that use the mesh as an emitter ([PirateJC](https://github.com/PirateJC))
 - Added customization options to VirtualJoystick ([#7398](https://github.com/BabylonJS/Babylon.js/issues/7398)) ([Rockwell15](https://github.com/Rockwell15))
+- Handle meshes with LODs in render target textures (meaning in glow/highlight layers, shadow generators, depth renderer, etc) ([Popov72](https://github.com/Popov72))
 
 ### NME
 

+ 1 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -1676,7 +1676,7 @@ export class GLTFLoader implements IGLTFLoader {
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView, kind).then((babylonBuffer) => {
                 const size = GLTFLoader._GetNumComponents(context, accessor.type);
                 return new VertexBuffer(this._babylonScene.getEngine(), babylonBuffer, kind, false, false, bufferView.byteStride,
-                    false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                    false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true, 1, true);
             });
         }
 

+ 6 - 6
src/Lights/Shadows/shadowGenerator.ts

@@ -226,6 +226,9 @@ export class ShadowGenerator implements IShadowGenerator {
     /** Gets or sets the custom shader name to use */
     public customShaderOptions: ICustomShaderOptions;
 
+    /** Gets or sets a custom function to allow/disallow rendering a sub mesh in the shadow map */
+    public customAllowRendering: (subMesh: SubMesh) => boolean;
+
     /**
      * Observable triggered before the shadow is rendered. Can be used to update internal effect state
      */
@@ -1099,12 +1102,9 @@ export class ShadowGenerator implements IShadowGenerator {
         }
 
         var hardwareInstancedRendering = engine.getCaps().instancedArrays && (batch.visibleInstances[subMesh._id] !== null && batch.visibleInstances[subMesh._id] !== undefined || renderingMesh.hasThinInstances);
-        if (effectiveMesh._internalAbstractMeshDataInfo._currentLOD !== effectiveMesh) {
-            if (hardwareInstancedRendering) {
-                delete batch.renderSelf[subMesh._id];
-            } else {
-                return;
-            }
+
+        if (this.customAllowRendering && !this.customAllowRendering(subMesh)) {
+            return;
         }
 
         if (this.isReady(subMesh, hardwareInstancedRendering, isTransparent)) {

+ 21 - 9
src/Materials/Textures/renderTargetTexture.ts

@@ -18,7 +18,6 @@ import { Constants } from "../../Engines/constants";
 
 import "../../Engines/Extensions/engine.renderTarget";
 import "../../Engines/Extensions/engine.renderTargetCube";
-import { InstancedMesh } from '../../Meshes/instancedMesh';
 import { Engine } from '../../Engines/engine';
 
 /**
@@ -742,7 +741,7 @@ export class RenderTargetTexture extends Texture {
         for (var meshIndex = 0; meshIndex < currentRenderListLength; meshIndex++) {
             var mesh = currentRenderList[meshIndex];
 
-            if (mesh) {
+            if (mesh && !mesh.isBlocked) {
                 if (this.customIsReadyFunction) {
                     if (!this.customIsReadyFunction(mesh, this.refreshRate)) {
                         this.resetRefreshCounter();
@@ -754,6 +753,16 @@ export class RenderTargetTexture extends Texture {
                     continue;
                 }
 
+                if (!mesh._internalAbstractMeshDataInfo._currentLODIsUpToDate && scene.activeCamera) {
+                    mesh._internalAbstractMeshDataInfo._currentLOD = scene.customLODSelector ? scene.customLODSelector(mesh, scene.activeCamera) : mesh.getLOD(scene.activeCamera);
+                    mesh._internalAbstractMeshDataInfo._currentLODIsUpToDate = true;
+                }
+                if (!mesh._internalAbstractMeshDataInfo._currentLOD) {
+                    continue;
+                }
+
+                let meshToRender = mesh._internalAbstractMeshDataInfo._currentLOD;
+
                 mesh._preActivateForIntermediateRendering(sceneRenderId);
 
                 let isMasked;
@@ -764,19 +773,22 @@ export class RenderTargetTexture extends Texture {
                 }
 
                 if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && !isMasked) {
+                    if (meshToRender !== mesh) {
+                        meshToRender._activate(sceneRenderId, true);
+                    }
                     if (mesh._activate(sceneRenderId, true) && mesh.subMeshes.length) {
                         if (!mesh.isAnInstance) {
-                            mesh._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;
+                            meshToRender._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;
                         } else {
-                            if (!mesh._internalAbstractMeshDataInfo._actAsRegularMesh) {
-                                mesh = mesh._internalAbstractMeshDataInfo._currentLOD ?? (mesh as InstancedMesh).sourceMesh;
+                            if (mesh._internalAbstractMeshDataInfo._actAsRegularMesh) {
+                                meshToRender = mesh;
                             }
                         }
-                        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = true;
+                        meshToRender._internalAbstractMeshDataInfo._isActiveIntermediate = true;
 
-                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
-                            var subMesh = mesh.subMeshes[subIndex];
-                            this._renderingManager.dispatch(subMesh, mesh);
+                        for (var subIndex = 0; subIndex < meshToRender.subMeshes.length; subIndex++) {
+                            var subMesh = meshToRender.subMeshes[subIndex];
+                            this._renderingManager.dispatch(subMesh, meshToRender);
                         }
                     }
                 }

+ 1 - 0
src/Meshes/abstractMesh.ts

@@ -88,6 +88,7 @@ class _InternalAbstractMeshDataInfo {
     public _onlyForInstancesIntermediate = false;
     public _actAsRegularMesh = false;
     public _currentLOD: Nullable<AbstractMesh> = null;
+    public _currentLODIsUpToDate: boolean = false;
 }
 
 /**

+ 22 - 2
src/Meshes/buffer.ts

@@ -13,6 +13,7 @@ export class Buffer {
     private _updatable: boolean;
     private _instanced: boolean;
     private _divisor: number;
+    private _isAlreadyOwned = false;
 
     /**
      * Gets the byte stride.
@@ -168,6 +169,20 @@ export class Buffer {
         }
     }
 
+    /** @hidden */
+    public _increaseReferences() {
+        if (!this._buffer) {
+            return;
+        }
+
+        if (!this._isAlreadyOwned) {
+            this._isAlreadyOwned = true;
+            return;
+        }
+
+        this._buffer.references++;
+    }
+
     /**
      * Release all resources
      */
@@ -279,12 +294,17 @@ export class VertexBuffer {
      * @param normalized whether the data contains normalized data (optional)
      * @param useBytes set to true if stride and offset are in bytes (optional)
      * @param divisor defines the instance divisor to use (1 by default)
+     * @param takeBufferOwnership defines if the buffer should be released when the vertex buffer is disposed
      */
     constructor(engine: any, data: DataArray | Buffer, kind: string, updatable: boolean, postponeInternalCreation?: boolean, stride?: number,
-        instanced?: boolean, offset?: number, size?: number, type?: number, normalized = false, useBytes = false, divisor = 1) {
+        instanced?: boolean, offset?: number, size?: number, type?: number, normalized = false, useBytes = false, divisor = 1, takeBufferOwnership = false) {
         if (data instanceof Buffer) {
             this._buffer = data;
-            this._ownsBuffer = false;
+            this._ownsBuffer = takeBufferOwnership;
+
+            if (takeBufferOwnership) {
+                this._buffer._increaseReferences();
+            }
         } else {
             this._buffer = new Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
             this._ownsBuffer = true;

+ 3 - 1
src/scene.ts

@@ -3548,6 +3548,7 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
         const len = meshes.length;
         for (let i = 0; i < len; i++) {
             const mesh = meshes.data[i];
+            mesh._internalAbstractMeshDataInfo._currentLODIsUpToDate = false;
             if (mesh.isBlocked) {
                 continue;
             }
@@ -3567,10 +3568,11 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
 
             // Switch to current LOD
             let meshToRender = this.customLODSelector ? this.customLODSelector(mesh, this.activeCamera) : mesh.getLOD(this.activeCamera);
+            mesh._internalAbstractMeshDataInfo._currentLOD = meshToRender;
+            mesh._internalAbstractMeshDataInfo._currentLODIsUpToDate = true;
             if (meshToRender === undefined || meshToRender === null) {
                 continue;
             }
-            mesh._internalAbstractMeshDataInfo._currentLOD = meshToRender;
 
             // Compute world matrix if LOD is billboard
             if (meshToRender !== mesh && meshToRender.billboardMode !== TransformNode.BILLBOARDMODE_NONE) {

BIN
tests/validation/ReferenceImages/glowlayerandlods.png


BIN
tests/validation/ReferenceImages/shadowsandlod.png


BIN
tests/validation/ReferenceImages/shadowsinstancesleft.png


BIN
tests/validation/ReferenceImages/shadowsinstancesright.png


+ 22 - 0
tests/validation/config.json

@@ -945,6 +945,28 @@
             "referenceImage": "geometrybufferrenderer.png",
             "renderCount": 10,
             "excludeFromAutomaticTesting": true
+        },
+        {
+            "title": "Shadows and LODs",
+            "playgroundId": "#F7KZ7C#9",
+            "referenceImage": "shadowsandlod.png"
+        },
+        {
+            "title": "Glow layer and LODs",
+            "playgroundId": "#UNS6ZV#2",
+            "referenceImage": "glowlayerandlods.png"
+        },
+        {
+            "title": "Shadows with instances in left handed system",
+            "renderCount": 10,
+            "playgroundId": "#MSAHKR#12",
+            "referenceImage": "shadowsinstancesleft.png"
+        },
+        {
+            "title": "Shadows with instances in right handed system",
+            "renderCount": 10,
+            "playgroundId": "#MSAHKR#13",
+            "referenceImage": "shadowsinstancesright.png"
         }
     ]
 }