-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for texture rotation #11863
Conversation
Awesome! |
Hmm... How about one step in between? texture.matrix = new THREE.Matrix3();
texture.matrixAutoUpdate = true; Then, for people interested in rotation/center, they could disable Your example would then be more about how to manually compose the matrix manually. |
So, are you suggesting NOT adding |
Yeah, as a first step. I'm afraid this could open a door to people requesting different order of operations. |
Hmm... the matrix is not actually "updated". It is You are proposing the user have two ways to specify the uv transform matrix -- the first is via That approach seems to be a bit confusing to me, but I will go with it... You prefer Can you suggest another term instead of |
Yeah. I thought it would be intuitive to follow what we do with |
@mrdoob OK, I implemented the API you requested. |
src/renderers/WebGLRenderer.js
Outdated
var offset = uvScaleMap.offset; | ||
var repeat = uvScaleMap.repeat; | ||
|
||
uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, 0, 0, 0 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this is better?
if ( uvScaleMap.matrixAutoUpdate === true ) {
var offset = uvScaleMap.offset;
var repeat = uvScaleMap.repeat;
uvScaleMap.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, 0, 0, 0 );
}
uniforms.uvTransform.value.copy( uvScaleMap.matrix );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK... you realize, however, that there may be multiple textures, and only one will have its matrix
"updated" by the renderer. The way I wrote it, texture.matrix
is never modified by the renderer
Are you OK with that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I understand.
Eventually we'll be updating all and send them to the shader. I still have to study Ben's PR.
Done! |
What do you think about splitting So the code could be something like this: texture.matrix
.identity()
.translate( - center.x, - center.y )
.scale( 1 / repeat.x, 1 / repeat.y )
.rotate( rotation )
.translate( offset.x, offset.y )
.translate( center.x, center.y ); |
Users naturally think in terms of what they want the texture to do. For example, "rotate counterclockwise around the center". However, the uv-transform matrix is not applied to the texture, but to the uvs of the geometry. So rotating the texture counterclockwise corresponds to a rotation of the uvs clockwise; scaling the texture down corresponds to scaling the uvs up. This is why we use the term "repeat" -- it expresses the transform in terms of the texture, even though it is the uvs that are being transformed. It is also why I declared a positive value of So the answer to your question is I feel your suggested approach would be confusing. |
Only advanced users that want to transform the uvs in custom ways will have to deal with this part of the api though. Most of the users will continue using Basically we're creating a new api for advanced users. I think it may be better to make this api intuitive for advanced users instead of trying to accommodate the current api into its logic? A bit like BufferGeometry is more designed for advanced users... |
@mrdoob I made the changes you proposed. Feedback requested... I am thinking that |
Sounds good to me! 😊 |
@mrdoob Done! |
I've just realised that we https://github.com/mrdoob/three.js/blob/dev/src/textures/Texture.js#L224-L299
|
Yes, I noted that in the PR. |
@mrdoob Done! I think we are good to go. |
@mrdoob Whatever you want to do with this is fine... |
I vote for a merge 😊 |
Thanks! 😊 |
Hmm, I think something break here: http://rawgit.com/mrdoob/three.js/dev/examples/misc_ubiquity_test2.html |
In 2017 people still seem to be confused with how to manipulate textures with three.js. From #5876 (comment):
I disagree with this, for example you could be using a tiled, repeatable leather texture with multiple channels (map, specularMap, normalMap, glossMap) and a completely different, baked AO map. The example from stack overflow, seems like a much better candidate for a uniform change with each draw call, then drawing different geometries, but I may not quite understand the balance. Lets's say you scatter 100 cube meshes in your scene and scale them. You want all of them to show the brick in "world space" aka if two different sized boxes are right next to each other, they should show the brick texture of the same size. Now lets say all these boxes are sitting on a ground plane, so they have some kind of AO/light map. Option 1 (i've seen this done a few times)
In this option, we process new geometry for each texture variation. If it's not a cube but something larger, this may consume more memory, the tradeoff being less operations in the shader? Option 2 (i've seen this have problems with duplicating the texture data)
^ This kinda makes more sense but i'm not sure if i see the entire picture. The 100 textures are just a wrapper, they all use the same image, so technically it should be 1 texture, 1 geometry, the tradeoff being more operations in the shader? I'm having a hard time understanding why is it ok to use uniforms to scale a mesh for example, but not the texture? Ie. we don't scale the So where is the state of texture transformations at right now? In other words
Will give me three misaligned textures on the material? All three would use the same uv attribute (channel?) which they would transform using their matrix? If only one is used i'd really like to learn the reasoning behind this :) I.e. how far did three.js go from:
I always found this confusing ^. So if you populate all the maps in a material, only one |
@pailhead How about creating a new issue instead? This PR has been merged and the conversation is clear and focused. |
As proposed in #5876 (comment).
This PR is backward-compatible. It adds
texture.rotation
andtexture.center
.Instead of passing
Vector4 offsetRepeat
to the shader,Matrix3 uvTransform
is passed.I chose to retain the terminology
offset/repeat
-- instead of using the termstranslate/scale
. When we increase the scale of something from 1 to 2, for example, we expect the size to increase. But when increasing the texture scale from 1 to 2, the texture actually decreases in size. So, to me,repeat
seems to be a better term.