Already discussed a bit on #14415
We already have renderOrder
for meshes and groups,
but not for materials, which is supported by Unity (as renderQueue
).
It would help sorting rendering order of multi-material meshes in certain condition.
I have no idea how much the idea makes good impact for us but I need this at least (π),
Since I have to display Unity-compatible stuff (I mean, VRM) on https://hub.vroid.com ...
demo below
https://codepen.io/FMS-Cat/pen/pYBwzw
If I understand your pen correctly, you can only achieve your intended visual result right now if you split up the geometry into two, create two meshes, apply different materials and then use Object3D.renderOrder
, correct?
Yes, and that's why I said I don't know how the idea help us.
I don't think merging two or more meshes into one geometry makes us happy in this situation.
Plus, we currently don't have scene description format that describes rendering order of submeshes or materials
(other than VRM, which is unpolished and still wip).
I think the change doesn't cause large impact on both codebase and performance though,
and might help some niche cases (like us π).
Actual our case in VRoid Hub can be seen on the slide below (Japanese π):
https://speakerdeck.com/fms_cat/webshi-jie-tejun-false3dmoterunisheng-wochui-kiip-mufang-fa?slide=42
We currently are addressing the issue by replacing the WebGLRenderLists
for our own one.
It would help sorting rendering order of multi-material meshes in certain condition.
Note that in upcoming r103, GLTFLoader will no longer create multi-material meshes. If it's still a dependency of VRMLoader that may affect this issue.
in upcoming r103, GLTFLoader will no longer create multi-material meshes
https://github.com/mrdoob/three.js/pull/15889
What, I didn't know that!
The PR sounds like we should avoid to use the multi-material meshes...?
All glTF files that worked before should still workβ each primitive (or material) in a glTF mesh will now become a separate threejs Mesh when loaded.
Yes I acknowledged that, and then I no longer need the feature request anymore π
Separating into meshes affects to performance though (at bone update section),
so I might rather use previous merging method anyway.
Plus, since VRM have renderQueue information for materials
then if we can have renderOrder property for materials it still would be more clean and cool.
Just to clarify: Material.renderOrder
is useful for sorting the render order of render items derived from a multi material mesh. If you just have meshes with one material, you could put the information from your render queue directly to Mesh.renderOrder
, right?
Just to clarify: Material.renderOrder is useful for sorting the render order of render items derived from a multi material mesh.
Maybe instead of hardwiring in the renderer:
groupOrder = object.renderOrder;
Maybe we should do this:
addGroup: function ( start, count, materialIndex, groupOrder ) {
this.groups.push( {
start: start,
count: count,
materialIndex: materialIndex !== undefined ? materialIndex : 0,
groupOrder: groupOrder !== undefined ? groupOrder : 0
} );
},
It's the object that needs to be sorted, not the material.
I think it's important not to mix THREE.Group
and BufferGeometry.groups
. The first code snippet from projectObject()
is for the case you assign a render order to an instance of THREE.Group
. This enables nested sorting in the scene graph via Object3D.renderOrder
. BufferGeometry.groups
is only relevant for multi material objects. The derived render items can't be sorted right now via Object3D.renderOrder
and I guess that is @FMS-Cat problem. I would not change the semantics of groupOrder
but rather introduce Material.renderOrder
.
OK.
But still, objects can share materials. Material.renderOrder
does not make sense to me. We render and sort renderable objects, not materials.
I agree. Unity allows to influence the render order on material/shader level (see https://docs.unity3d.com/Manual/SL-SubShaderTags.html) whereas three.js
does this on object level. Hence, it feels inconsistent to introduce Material.renderOrder
.
Even if Material.renderOrder
would be introduced, the feature would not be compatible to Unity's approach like suggested in the issue's title. For example the value of renderOrder
is "relative" to each render list (opaque and transparent objects). Unity's render queue value is global instead.
So the question is now, how about my suggestion above, adding
BufferGeometry.groups[ i ].renderOrder
But even so, this is such an edge case...
If you just have meshes with one material, you could put the information from your render queue directly to Mesh.renderOrder, right?
True.
the value of renderOrder is "relative" to each render list (opaque and transparent objects). Unity's render queue value is global instead.
Yes that is also true, Unity still may use separated render lists internally though,
to achieve opaque should render forward to behind, transparent should render behind to forward.
(and yeah I don't like the way the renderLists gets separated at certain constants (2501 I guess?)).
how about my suggestion above, adding
BufferGeometry.groups[ i ].renderOrder
But even so, this is such an edge case...
Yeah I think so too π©
Closing for now. I think we agree to not introduce Material.renderOrder
. As mentioned by @WestLangley, the engine sorts and renders objects, so it's better if renderOrder
is only related to Object3D
.
If a user really needs to sort the derived render items of a multi material object, the idea is the transform the object into multiple ones and use Object3D.renderOrder
again. In other words, this (special) use case needs to be solved on application level.
Most helpful comment
Closing for now. I think we agree to not introduce
Material.renderOrder
. As mentioned by @WestLangley, the engine sorts and renders objects, so it's better ifrenderOrder
is only related toObject3D
.If a user really needs to sort the derived render items of a multi material object, the idea is the transform the object into multiple ones and use
Object3D.renderOrder
again. In other words, this (special) use case needs to be solved on application level.