Skip to content

Conversation

@mrdoob
Copy link
Owner

@mrdoob mrdoob commented Apr 7, 2023

Related issue: #25721

Description

Support up to 4 uv channels instead of just 2.
Also moved attribute definitions to WebGLProgram.js.

@github-actions
Copy link

github-actions bot commented Apr 7, 2023

📦 Bundle size

Full ESM build, minified and gzipped.

Filesize Gzipped Diff from dev
628.1 kB 156.1 kB +389 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Filesize Gzipped Diff from dev
419.6 kB 102.2 kB +389 B

@mrdoob
Copy link
Owner Author

mrdoob commented Apr 7, 2023

I really dislike the uv, uv2, uv3, uv4 names...

But I don't know how many things, if any, would be to rename them now.

And if we did, should it be uv_0? texcoord_0? ...?

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 7, 2023

But I don't know how many things, if any, would be to rename them now.

I'm afraid too many things depend on these names. But if we could start from scratch I would favor the texcoord_0 semantic. Maybe as texCoord_0.

@pailhead
Copy link
Contributor

pailhead commented Apr 7, 2023

uv_0 sounds good.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Apr 7, 2023

I slightly prefer "uv" over "texcoord". I think the glTF "texcoord" abbreviation is less common, and we use the word UV elsewhere in our API, not just the attribute name, so it is quite a breaking change. It would be great for the index used in the name to match up with the value assigned to texture.channel, and not be off by 1.

Do we want to mix underscores with camel case though? If we someday add an additional set of skinning weights, do we prefer skinWeight2 or skinWeight_2 or ...?

@WestLangley
Copy link
Collaborator

I really dislike the uv, uv2, uv3, uv4 names...

Me, too.

How about

geometry.attributes.uvs[ i ]

with .uv and .uv2 retained as getters for backwards compatibility.

@pailhead
Copy link
Contributor

pailhead commented Apr 7, 2023

@WestLangley I think it can’t just be a simple array since then you could make it sparse? Some api (add, remove) could be more robust.

@gkjohnson
Copy link
Collaborator

I personally do not see the issue with uv, uv2, etc names or why an underscore or changing to "texcoord" would be an improvement. Either way all suggestions and current implementation all seem understandable to me.

Whatever the case, though, please do not use an array of BufferAttributes in the attributes dictionary:

geometry.attributes.uvs[ i ]

with .uv and .uv2 retained as getters for backwards compatibility.

I've often generically iterated over the attribute fields to process them into textures, merge geometries, compress data, etc. Adding a new object structure in attributes doesn't add a lot of value and will needlessly break and complicate user code. There's also a level of simplicity with attribute dictionary names directly mapping to attribute value names in shader code.

Please also consider that changing the name of uv will break user land shaders that use that field in vertex programs.

@pailhead
Copy link
Contributor

pailhead commented Apr 8, 2023

What about a mechanism on the geometry not the attributes? Not sure how it would look like, but this doesn’t feel like this belongs on the attributes, rather above it, managing them.

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 8, 2023

I fully agree with what @gkjohnson said 👍 .

@mrdoob
Copy link
Owner Author

mrdoob commented Apr 9, 2023

I did a bad job at explaining what it is that I don't like 😅

When I implemented texture.channel I made it so it follows GLTF's TEXCOORD ids but the Three.js developer it'll be confusing because texture.channel doesn't map the ids used in the attribute.

GLTF channel attribute
TEXCOORD_0 0 uv
TEXCOORD_1 1 uv2
TEXCOORD_2 2 uv3
TEXCOORD_3 3 uv4

Option 1
One solution would be to make texture.channel start by 1 instead.
But that could be confusing when authoring content.

GLTF channel attribute
TEXCOORD_0 1 uv
TEXCOORD_1 2 uv2
TEXCOORD_2 3 uv3
TEXCOORD_3 4 uv4

Option 2
Another solution is to rename the attributes (making sure we don't break backwards compatibility)

GLTF channel attribute
TEXCOORD_0 0 uv0
TEXCOORD_1 1 uv1
TEXCOORD_2 2 uv2
TEXCOORD_3 3 uv3

I think I prefer the second option and if people is okay with it I can give it a try after merging this PR.

@donmccurdy
Copy link
Collaborator

Agreed. I like both of those, and also have a small preference for option 2. No need to change the underlying geometry/attribute API.

@pailhead
Copy link
Contributor

See if you can give it some more thought. I don’t think that this belongs in the attributes, attributes are just attributes. And while texcoord seems to be a GL term, it soon changes to UV. Kinda curious about that historically.

But, since it is doing some magic - some in a sense - more than the magic when you name your buffer ‘foo’ I feel like it could be explored a bit how it would look like if geometry managed this.

more maybe have some builder helper. There is no reason why someone would dynamically alter - remove or add uv attributes at runtime.

@makc
Copy link
Contributor

makc commented Apr 12, 2023

why not just write an attribute name (string) into texture.channel @mrdoob

@pailhead
Copy link
Contributor

Hmmm, you would have to “turn it off” for its actual name? So that you don’t get “horse” and uv0? But I kinda like this idea.

@pailhead
Copy link
Contributor

pailhead commented Apr 12, 2023

Duplicate

@makc
Copy link
Contributor

makc commented Apr 12, 2023

@pailhead like, if users want to use the attribute named "horse" - let them. why not? what's the big deal? just set it to "uv" by default, and to "uvX" in the model loader with correct X for the maps that require another layer.

@pailhead
Copy link
Contributor

pailhead commented Apr 12, 2023

I see, if you write “horse” to an array, you would still call setAttribute(“horse”…) but you would actually get uv_x and no horse? That’s what I meant by management. The presence of channels:[“horse”] means the actual attribute vec2 horse; should not appear.

@makc
Copy link
Contributor

makc commented Apr 12, 2023

why array? I was talking about apparently numeric property of Texture that mrdoob modelled after gltf spec. apparently.

@makc
Copy link
Contributor

makc commented Apr 12, 2023

e.g. if the texture is marked to use "horse" (or "uv3"), three would check if there is such an attribute (and it normally will be, because the loader loaded uv3, or the user added the horse) and if not - throw some error at which point the user knows his code needs fixing.

@pailhead
Copy link
Contributor

pailhead commented Apr 12, 2023

I think I get it, there wouldn’t even be a channel int, just the name of the attribute to be used as such channel?

@makc
Copy link
Contributor

makc commented Apr 12, 2023

yep.

@pailhead
Copy link
Contributor

As an interface that makes sense to me. Feels like it would be a massive change.

@pailhead
Copy link
Contributor

Actually, i don't think it would be such a massive change. Such an list would still mean that textures are used via

attribute vec3 horse;
varying vec2 vUv0;

... 

  vUv0 = horse.xy;

Could actually even eliminate a lot of this duplicated code that deals with injecting attribute vec2 uv_x.

@makc
Copy link
Contributor

makc commented Apr 12, 2023

more massive than renaming uv to uv_0 for no reason? 😅 like, people will need to edit their shaders and stuff

@makc
Copy link
Contributor

makc commented Apr 13, 2023

vUv0 = horse.xy;

just do 'v' + capitalize(attributeName). so that uv turns to vUv (like now? iirc), uv3 to vUv3, horse to vHorse

@pailhead
Copy link
Contributor

I was thinking at least the fragment shaders wouldn’t have to be changed. And there is no need to prefix anything just point an attribute to where uv would have been accessed

@makc
Copy link
Contributor

makc commented Apr 13, 2023

but then you have to order them somehow. and you would also have a failure if users specify 5 channels.

besides, how would that even work your way? suppose you have hardcoded ao map to vUv2 in fragment, but material.aoMap.channel is 4 - what do you do? if you just route 4-th attribute into vUv2, it means no other map/code can use vUv2 in fragment shader... so in the end, you will have one varying per texture, even if they all use the same attribute?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants