Jelajahi Sumber

add instances optim to render Target

David Catuhe 6 tahun lalu
induk
melakukan
a153815033

+ 2 - 0
src/Layers/effectLayer.ts

@@ -635,6 +635,8 @@ export abstract class EffectLayer {
         var scene = this._scene;
         var engine = scene.getEngine();
 
+        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+
         if (!material) {
             return;
         }

+ 2 - 0
src/Lights/Shadows/shadowGenerator.ts

@@ -906,6 +906,8 @@ export class ShadowGenerator implements IShadowGenerator {
         var engine = scene.getEngine();
         let material = subMesh.getMaterial();
 
+        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+
         if (!material || subMesh.verticesCount === 0) {
             return;
         }

+ 14 - 6
src/Materials/Textures/renderTargetTexture.ts

@@ -16,6 +16,7 @@ import { RenderingManager } from "../../Rendering/renderingManager";
 import { Constants } from "../../Engines/constants";
 
 import "../../Engines/Extensions/engine.renderTarget";
+import { InstancedMesh } from 'Meshes';
 
 declare type Engine = import("../../Engines/engine").Engine;
 
@@ -676,12 +677,19 @@ export class RenderTargetTexture extends Texture {
                 }
 
                 if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && !isMasked) {
-                    mesh._activate(sceneRenderId);
-
-                    for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
-                        var subMesh = mesh.subMeshes[subIndex];
-                        scene._activeIndices.addCount(subMesh.indexCount, false);
-                        this._renderingManager.dispatch(subMesh, mesh);
+                    if (mesh._activate(sceneRenderId, true)) {
+                        if (!mesh.isAnInstance) {
+                            mesh._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;
+                        } else {
+                            mesh = (mesh as InstancedMesh).sourceMesh;
+                        }
+                        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = true;
+
+                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
+                            var subMesh = mesh.subMeshes[subIndex];
+                            scene._activeIndices.addCount(subMesh.indexCount, false);
+                            this._renderingManager.dispatch(subMesh, mesh);
+                        }
                     }
                 }
             }

+ 7 - 8
src/Meshes/abstractMesh.ts

@@ -73,6 +73,10 @@ class _InternalAbstractMeshDataInfo {
     public _skeleton: Nullable<Skeleton> = null;
     public _layerMask: number = 0x0FFFFFFF;
     public _computeBonesUsingShaders = true;
+    public _isActive = false;
+    public _onlyForInstances = false;
+    public _isActiveIntermediate = false;
+    public _onlyForInstancesIntermediate = false;
 }
 
 /**
@@ -153,7 +157,8 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
     }
 
     // Internal data
-    private _internalAbstractMeshDataInfo = new _InternalAbstractMeshDataInfo();
+    /** @hidden */
+    public _internalAbstractMeshDataInfo = new _InternalAbstractMeshDataInfo();
 
     /**
      * The culling strategy to use to check whether the mesh must be rendered or not.
@@ -283,12 +288,6 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
     public _occlusionQuery: Nullable<WebGLQuery> = null;
 
     /** @hidden */
-    public _isActive = false;
-
-    /** @hidden */
-    public _onlyForInstances = false;
-
-    /** @hidden */
     public _renderingGroup: Nullable<RenderingGroup> = null;
 
     /**
@@ -1045,7 +1044,7 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
     }
 
     /** @hidden */
-    public _activate(renderId: number): boolean {
+    public _activate(renderId: number, intermediateRendering: boolean): boolean {
         this._renderId = renderId;
         return true;
     }

+ 11 - 4
src/Meshes/instancedMesh.ts

@@ -278,14 +278,21 @@ export class InstancedMesh extends AbstractMesh {
     }
 
     /** @hidden */
-    public _activate(renderId: number): boolean {
+    public _activate(renderId: number, intermediateRendering: boolean): boolean {
         if (this._currentLOD) {
             this._currentLOD._registerInstanceForRenderId(this, renderId);
         }
 
-        if (!this._currentLOD._isActive) {
-            this._currentLOD._onlyForInstances = true;
-            return true;
+        if (intermediateRendering) {
+            if (!this._currentLOD._internalAbstractMeshDataInfo._isActiveIntermediate) {
+                this._currentLOD._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = true;
+                return true;
+            }
+        } else {
+            if (!this._currentLOD._internalAbstractMeshDataInfo._isActive) {
+                this._currentLOD._internalAbstractMeshDataInfo._onlyForInstances = true;
+                return true;
+            }
         }
         return false;
     }

+ 18 - 10
src/Meshes/mesh.ts

@@ -1371,15 +1371,17 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             return this._instanceDataStorage.previousBatch;
         }
         var scene = this.getScene();
+        const isInIntermediateRendering = scene._isInIntermediateRendering();
+        const onlyForInstances = isInIntermediateRendering ? this._internalAbstractMeshDataInfo._onlyForInstancesIntermediate : this._internalAbstractMeshDataInfo._onlyForInstances;
         let batchCache = this._instanceDataStorage.batchCache;
         batchCache.mustReturn = false;
-        batchCache.renderSelf[subMeshId] = !this._onlyForInstances && this.isEnabled() && this.isVisible;
+        batchCache.renderSelf[subMeshId] = !onlyForInstances && this.isEnabled() && this.isVisible;
         batchCache.visibleInstances[subMeshId] = null;
 
         if (this._instanceDataStorage.visibleInstances) {
             let visibleInstances = this._instanceDataStorage.visibleInstances;
             var currentRenderId = scene.getRenderId();
-            var defaultRenderId = (scene._isInIntermediateRendering() ? visibleInstances.intermediateDefaultRenderId : visibleInstances.defaultRenderId);
+            var defaultRenderId = (isInIntermediateRendering ? visibleInstances.intermediateDefaultRenderId : visibleInstances.defaultRenderId);
             batchCache.visibleInstances[subMeshId] = visibleInstances[currentRenderId];
 
             if (!batchCache.visibleInstances[subMeshId] && defaultRenderId) {
@@ -1518,13 +1520,18 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
      * @returns the current mesh
      */
     public render(subMesh: SubMesh, enableAlphaMode: boolean): Mesh {
-        this._isActive = false;
+        var scene = this.getScene();
+
+        if (scene._isInIntermediateRendering()) {
+            this._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+        } else {
+            this._internalAbstractMeshDataInfo._isActive = false;
+        }
 
         if (this._checkOcclusionQuery()) {
             return this;
         }
 
-        var scene = this.getScene();
         // Managing instances
         var batch = this._getInstancesRenderList(subMesh._id);
 
@@ -1545,13 +1552,14 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
         var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
         let instanceDataStorage = this._instanceDataStorage;
 
-        // Material
-        if (!instanceDataStorage.isFrozen || !this._effectiveMaterial) {
-            let material = subMesh.getMaterial();
+        let material = subMesh.getMaterial();
 
-            if (!material) {
-                return this;
-            }
+        if (!material) {
+            return this;
+        }
+
+        // Material
+        if (!instanceDataStorage.isFrozen || !this._effectiveMaterial || this._effectiveMaterial !== material) {
 
             this._effectiveMaterial = material;
 

+ 4 - 4
src/scene.ts

@@ -3307,14 +3307,14 @@ export class Scene extends AbstractScene implements IAnimatable {
                 this.activeCamera._activeMeshes.push(mesh);
 
                 if (meshToRender !== mesh) {
-                    meshToRender._activate(this._renderId);
+                    meshToRender._activate(this._renderId, false);
                 }
 
-                if (mesh._activate(this._renderId)) {
+                if (mesh._activate(this._renderId, false)) {
                     if (!mesh.isAnInstance) {
-                        meshToRender._onlyForInstances = false;
+                        meshToRender._internalAbstractMeshDataInfo._onlyForInstances = false;
                     }
-                    meshToRender._isActive = true;
+                    meshToRender._internalAbstractMeshDataInfo._isActive = true;
                     this._activeMesh(mesh, meshToRender);
                 }