Godot version:
Godot 3+
OS/device including version:
Any
Issue description:
It would be cool to have a way to assign different materials to the mesh instances when using MultiMesh.
So let's assume we want to render 4 cubes. Every cube should have a different material. The 4 materials are for example: StoneMaterial, DirtMaterial, GrassMaterial and WoodMaterial.
The idea is to just code something like:
MultiMesh.mesh = cubeMesh
MultiMesh.instance_count = 4
MultiMesh.set_instance_material(0, StoneMaterial)
MultiMesh.set_instance_material(1, DirtMaterial)
MultiMesh.set_instance_material(2, GrassMaterial)
MultiMesh.set_instance_material(3, WoodMaterial)
In real applications this could be extended to thousands of cubes and the benefit of using MultiMesh is huge here. So this feature could make it simpler to write for example voxel games (best example here: Minecraft). So if this could be possible to implement then this would be extremely cool :)
I thought the point of multimesh was to offer hardware instancing performance in one draw call for identical objects. Is it still beneficial (or even possible) with multiple shaders/uniforms in OpenGL?
If it's not possible or not beneficial then there could be at least a (even if very basic) way to support different textures. So we have one material containing different textures. Then an index could be used to "apply" the desired texture.
I'm no expert in OpenGL programming but I remember that I read some articles about this topic in which some ways were discussed to (at least) enable different textures when using instanced rendering. One of the proposals was to use texture arrays. And within the underlying VAO indices are "stored" to tell OpenGL which texture to use for the current rendered instance. But I don't know if the instancing of which I speak at the moment is the same as what is meant by hardware instancing. I mean instancing in case of e.g. glDrawElementsInstanced(...).
So eventually at least a very basic way to use different textures could be possible? Even this would be a huge improvement for my use cases because I am a litte voxel freak, hehe :)
using a material shader that can switch it's properties based on the COLOR vertex attribute being passed in to each individual multimesh instance. That's how I add different animations or color or features to my multimeshes to make variety.
to explain further. Let's say i want to switch those 4 textures like you say. What you do is you write your own shader with those 4 textures as input parameters. Then for each instance you want, set the instance color to encode your options. e.g.
set_instance_color(0, Color(0))
set_instance_color(1, Color(1))
set_instance_color(2, Color(2))
then in your shader, just get the sum rgba value to determine which material you want to apply. voila. but yea you're gonna have to make a big shader. A tip is to make a spatial material you like, hten convert it to shader material. Then edit the shader material so instead of one albedo texture, it takes 4 albedo texture. same with normals. Then just go to where those textures are being applied and do if else condition for each type of material you want to switch out.
This provokes another question.
As far as I understood from the documentation (I don't remember where exactly): "It's best to have one material with different parameters for all objects, to minimize GPU shader switching which is most expensive. So, in Godot 3.0, we've focused on creating one SpatialMaterial that works for almost anything, so try to use it for as many objects as you can to avoid switching". My understanding is that SpatialMaterial is exactly that - one material with different parameters.
If that's true, then overriding material _parameters_ per instance shouldn't be a big deal. Or did I misunderstand that, and changing one property in SpatialMaterial actually creates a different shader? Maybe because this way the resulting shaders are smaller and faster that "parametric" ones?
If so, then does it make sense to introduce a "BloatedMaterial" for cases when having a "parametric" shader would be faster than many "smaller" materials? (Actually, I can't imagine a scenario where it woudn't.)
Per object material parameters can help. But doesn't work with multimesh
This wont work, as everything is drawn using a single draw call. Why dont you use a few multimeshes with different materials?
And like I said you can have the mesh include all possible texture
combinations, and use the multimesh instance color to tell which textures
to use
On Sat, Sep 1, 2018, 12:24 PM Juan Linietsky notifications@github.com
wrote:
This wont work, as everything is drawn using a single draw call. Why dont
you use a few multimeshes with different materials?—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/17472#issuecomment-417870497,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADLZ9h56S1pKX63ISqpaiUR6uGKIYphWks5uWrS_gaJpZM4SnPX0
.
So then, do I understand correctly that:
https://github.com/godotengine/godot/issues/21269 see what I'm working on as I'm trying to achieve something similar (animation + agent variety while only doing single mesh draw calls).
Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.
The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.
If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!
I see it's already doable using some shader magic. Likely a candidate for documenting, alongside the multimesh flock of fish trick, in Godot documentation?
Well, if this is really possible, you can create issue on Godot-docs pointing here.