PeapBoy

Members
  • Content count

    46
  • Joined

  • Last visited

  1. First I wanted to add a new propertyType to handle this but we cannot anticipate if a diffuse/reflection/whatever texture will be - or not - a RTT. So I just check sourceProperty.isRenderTarget in clone function.
  2. I agree. I could do this on monday if you want.
  3. Hello, When cloning a material - say, a BABYLON.StandardMaterial -, everything is fine except for renderTargetTexture. PG: https://playground.babylonjs.com/#BLG0FL material.clone() function calls renderTargetTexture.clone() function. But renderTargetTexture.clone() function creates a new empty RenderTargetTexture with the same properties. Btw, I'm sure that adding "scene.customRenderTargetTextures.push()" at the end of the clone function would resolve this issue. But I don't think that people want to create a new RTT each time they clone a material (it would kill the app, especially on iOS devices). Not sure about which behaviour adopt here, any idea ? Thanks !
  4. How are managed material defines ?

    Seems like you did the last change, thanks !
  5. How are managed material defines ?

    Something like this ? MultiMaterial.prototype.isReady = function (mesh) { if (!mesh) { return false; } if (!mesh.subMeshes || mesh.subMeshes.length === 0) { return true; } for (var index = 0; index < mesh.subMeshes.length; index++) { var subMesh = mesh.subMeshes[index]; var subMaterial = this.subMaterials[subMesh._materialIndex]; if (subMaterial) { if (!material.isReadyForSubMesh(mesh, subMesh)) { return false; } } } return true; } But if we do this, you're not guaranteed to verify every material of subMaterials array. So it could return true without being really ready. It only returns true if every used subMaterial is ready.
  6. How are managed material defines ?

    Hello, I still have a case where defines are wrong But I found why. PushMaterial.prototype.isReady = function (mesh, useInstances) { if (!mesh) { return false; } if (!mesh.subMeshes || mesh.subMeshes.length === 0) { return true; } return this.isReadyForSubMesh(mesh, mesh.subMeshes[0], useInstances); }; PushMaterial.prototype.bind = function (world, mesh) { if (!mesh) { return; } this.bindForSubMesh(world, mesh, mesh.subMeshes[0]); }; In these two functions, we use mesh.subMeshes[0] without knowing if this subMesh does use the material. These function are called by Scene._checkIsReady() function, that's why I faced this case. For example. I have a MultiMaterial which has two subMaterials : a Standard and a PBR. MultiMaterial.isReady(mesh) will call PushMaterial.isReady(mesh) for each subMaterial. First, it will go through StandardMaterial.isReadyForSubMesh() function, create StandardMaterialDefines and set them to mesh.subMeshes[0]. Then, it will go through the PBRMaterial.isReadyForSubMesh() function with StandardMaterialDefines instead of PBRMaterialDefines. Because we called the two functions with the same subMesh. I understand it's necessary for retrocompatibility (there was only isReady function before, right ?). So I can't simply put the defines to undefined after calling the isReadyForSubMesh function...
  7. How are managed material defines ?

    Hello again, When calling subMesh.getMaterial() function, we actually set the new subMaterial to the subMesh. I think we should reset the defines here. public getMaterial(): Material { var rootMaterial = this._renderingMesh.material; if (rootMaterial && (<MultiMaterial>rootMaterial).getSubMaterial) { var multiMaterial = <MultiMaterial>rootMaterial; var effectiveMaterial = multiMaterial.getSubMaterial(this.materialIndex); if (this._currentMaterial !== effectiveMaterial) { this._currentMaterial = effectiveMaterial; if (this._materialDefines) { this._materialDefines.markAllAsDirty(); } } return effectiveMaterial; } if (!rootMaterial) { return this._mesh.getScene().defaultMaterial; } return rootMaterial; } Instead of this : if (this._materialDefines) { this._materialDefines.markAllAsDirty(); } We could do this : this._materialDefines = undefined; Because if we assign a new material the line before, materialDefines are not the good ones anymore (except if you change the material from a PBR to a PBR or from a Standard to a Standard). Since I'm sure I don't understand everything so I may miss some important processes, I prefer asking here if it makes sense rather than submitting a PR immmediately.
  8. How are managed material defines ?

    Of course ! However, I just realized that the issue I have in my app is not exactly the same as the one in the PG. My bug appears because of my subMaterials. I can see in this code that there's a complete mechanism when subMaterials are set : Object.defineProperty(MultiMaterial.prototype, "subMaterials", { get: function () { return this._subMaterials; }, set: function (value) { this._subMaterials = value; this._hookArray(value); }, enumerable: true, configurable: true }); MultiMaterial.prototype._hookArray = function (array) { var _this = this; var oldPush = array.push; array.push = function () { var items = []; for (var _i = 0; _i < arguments.length; _i++) { items[_i] = arguments[_i]; } var result = oldPush.apply(array, items); _this._markAllSubMeshesAsTexturesDirty(); return result; }; var oldSplice = array.splice; array.splice = function (index, deleteCount) { var deleted = oldSplice.apply(array, [index, deleteCount]); _this._markAllSubMeshesAsTexturesDirty(); return deleted; }; }; I have three questions about this part : - Why adding a new material only affects textures and not everything ? (TexturesDirty flag) - How are the materialDefines assigned to undefined ? (They aren't, right ? That's my issue in my app, I think) - If we add a subMaterial using subMaterials[materialIndex] = new Material() instead of using subMaterials.push() function, is the dirty flag rised ?
  9. How are managed material defines ?

    As I show it in my PG, sometimes it happens that setEffect(null) is not enough. In some cases, this._materialEffect is null. So, if you call setEffect(null), it will return immediately without setting the defines to undefined. I have this issue in my app. I tried to reproduce it and make it simple in the PG. https://www.babylonjs-playground.com/#YNCHVR
  10. How are managed material defines ?

    Shame on me, I didn't think about looking for "setEffect(null)" Thanks Mmh now, I understand the issue in the PG above. First time setMaterial (and setEffect(null)) is called, (this._materialEffect === effect) is (undefined === null) so we assign undefined to materialDefines and null to materialEffect. Then we create StandardMaterialDefines at the beginning of the isReady function. If something is not ready yet, we don't call setEffect and materialEffect stays at null. Second time setMaterial (and setEffect(null)) is called, (this._materialEffect === effect) is (null === null) so we return and don't assign undefined to materialDefines. Then I find myself with StandardMaterialDefines instead of PBRMaterialDefines or undefined. And boom. setEffect(null) is not enough in the particular case where something isn't ready in material isReady function() and materialEffect is not replaced by a value. Do you mind if we assign directly subMesh._materialDefines = undefined in the material set function ? Moreover, it's been a long time I wonder why we don't use defines in bindForSubMesh function to save some if instructions. But I could open a new post for this.
  11. Hello everybody, I face some errors in my app concerning material defines, I don't understand how they're managed. To render a mesh, subMesh.getMaterial().isReadyForSubMesh() and subMesh.getMaterial().bindForSubMesh() functions are successively called each frame, right ? Material defines are created at the beginning of the isReady function if subMesh doesn't have defines (so, if it's the first time this mesh is rendered, I assume). Defines are stored in subMesh with the _materialDefines property. Guess we begin with a standard material, we'll get StandardMaterialDefines on our subMesh and use the isReady function of StandardMaterial. Now, I assign another material to my mesh (a PBR for example). We'll now use the isReady function of PBRMaterial. In the isReady function, we'll only check if defines exist and we will work with StandardMaterialDefines instead of PBRMaterialDefines, no ? This is what happens to me in some circumstances... PG: https://www.babylonjs-playground.com/#YNCHVR (Open your console) But then, there is a mechanism that handles this issue and this doesn't happen anymore. I don't understand this either. Someone could enlight me please ?
  12. Material push mode: The new big optimization

    Hi, As far as I know, yes material push mode is in the latest build for Standard Material. Not for PBRMaterial yet. And materials from materialsLibrary (water, fur, etc.) also are in push mode.
  13. Get complete shader source code on error

    Ok nice ! Good luck with push mode & UBOs
  14. Get complete shader source code on error

    Ok, done, thank you. Just one question. Since BabylonJS has a backward compatibility policy, can I remove a function ? Because I replaced _dumpShadersName (which is only used here) by _dumpShadersSource. Two other things I think about : - Maybe some developers do NOT want that random users of their site could see the content of their shaders when it fails to compile ? - It may add a huge amount of text in the console and it may be uncomfortable if you're not debugging this. I tried to order the content as good as I could though. Anyway, PR is sent.