Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by IVIachine · Jan 12, 2018 at 11:13 PM · rotationshaderrotation axistrianglegeometry shader

How to rotate a triangle created in a geometry shader around its center

I am splitting a quad made of two triangles into 2^n triangles using a tessellation shader where n is how many triangles are generated from each of the two triangles(Currently set to 3). In the geometry shader, I want to take the new triangles and rotate them in place. Even when I offset them based on the center, they still seem to be rotating around a point that isn't their center. The triangles closer to the origin, however, seem to be messed up a lot less. alt text

This is just a few seconds into the rotation. As you can see, the triangles near the center are a lot less offset than the ones farther away. Here is the geometry shader code. The uv1 stores the vertex position in object space. t is a uniform that represents the timestep of the rotation.

 float4 worldOne = mul(unity_ObjectToWorld, g0.data.uv1);
                     float4 worldTwo = mul(unity_ObjectToWorld, g1.data.uv1);
                     float4 worldThree = mul(unity_ObjectToWorld, g2.data.uv1);
 
 float3 u = normalize(cross(worldTwo - worldOne, worldThree - worldOne));
                         float center = (worldOne + worldTwo + worldThree) / 3;
 
                         float3 pos1 = worldOne - center;
                         worldOne = float4(rotatePosition(u, t * .25, pos1) + center,1);
 
                         float3 pos2 = worldTwo - center;
                         worldTwo = float4(rotatePosition(u, t * .25, pos2) + center,1);
 
                         float3 pos3 = worldThree - center;
                         worldThree = float4(rotatePosition(u, t * .25, pos3) + center,1);
 
                         float3 objectOne = mul(unity_WorldToObject, worldOne);
                         float3 objectTwo = mul(unity_WorldToObject, worldTwo);
                         float3 objectThree = mul(unity_WorldToObject, worldThree);
 
                         g0.data.vertex = UnityObjectToClipPos(objectOne);
                         g1.data.vertex = UnityObjectToClipPos(objectTwo);
                         g2.data.vertex = UnityObjectToClipPos(objectThree);


and the helper function:

 float3 rotatePosition(float3 axis, float angle, float3 p)
                 {
                     float3 n = axis; // the axis to rotate about
 
                                                   // Specify the rotation transformation matrix:
                     float3x3 m = float3x3(
                         n.x*n.x * (1.0f - cos(angle)) + cos(angle),       // column 1 of row 1
                         n.x*n.y * (1.0f - cos(angle)) + n.z * sin(angle), // column 2 of row 1
                         n.x*n.z * (1.0f - cos(angle)) - n.y * sin(angle), // column 3 of row 1
 
                         n.y*n.x * (1.0f - cos(angle)) - n.z * sin(angle), // column 1 of row 2
                         n.y*n.y * (1.0f - cos(angle)) + cos(angle),       // ...
                         n.y*n.z * (1.0f - cos(angle)) + n.x * sin(angle), // ...
 
                         n.z*n.x * (1.0f - cos(angle)) + n.y * sin(angle), // column 1 of row 3
                         n.z*n.y * (1.0f - cos(angle)) - n.x * sin(angle), // ...
                         n.z*n.z * (1.0f - cos(angle)) + cos(angle)        // ...
                     );
 
                     // Apply the rotation to our 3D position:
                     float3 q = mul(m,p);
                     return q;
                 }


What am I doing wrong/missing?

example.png (17.6 kB)
Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image insominx · Jan 13, 2018 at 01:16 AM 0
Share

All rotation is actually done based on where 0 is or in 3d (0, 0, 0). In object space, your quad probably has its 0 point in the center but these new triangles you are making do not. The trick is to first translate each point in your sub-triangles so that they are centered around 0 and then perform the rotation. Then, undo the translation you first performed and you will have a triangle that is rotated around its original location.

avatar image IVIachine insominx · Jan 13, 2018 at 01:19 AM 0
Share

Thank you for your quick response! What would this translation consist of? Would I literally subtract the position from itself, rotate, and add the position back?

avatar image insominx IVIachine · Jan 13, 2018 at 01:22 AM 0
Share

I think what you're looking for is for each triangle to rotate around its current center right? If so, then you'll need to compute that center: (v1 + v2 + v3) / 3. That's what you subtract because afterward your coordinates will be relate to this new center point (your new 0).

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Jan 13, 2018 at 01:40 AM

Your main issue seems to be that you have declared your center variable as float, not as float3. Since HLSL allows mixing of vector and scalar values it won't generate a compiler error but the result is not what you would expect.


Don't ask me what center would actually contain in this case:

 float center = (worldOne + worldTwo + worldThree) / 3;

I would have thought that this line should generate an error sinceyour worldOne / Two / Three variables are float4. Dividing by 3 should also result in a float4. Possible values would probably by simply the "x" value.


When you subtract the "center" from your actual position you actually subtract the same value from all three components.


So just delcare the center variable as float3 or 4.


Note the way you rotate your points is very inefficient. The point of constructing a matrix is to reuse it. You should alter your method to just return a matrix. Since the axis and angle is the same for the 3 points you need to create the matrix only once.

 float3x3 createRotation(float3 axis, float angle)
 {
     // ...
     return m;
 }
 
 
 float3 center = (worldOne.xyz + worldTwo.xyz + worldThree.xyz) / 3;
 float3x3 rotation = createRotation(u, t * .25);
 
 worldOne = float4(mul(rotation, worldOne.xyz - center) + center,1);
 worldTwo = float4(mul(rotation, worldTwo.xyz - center) + center,1);
 worldThree = float4(mul(rotation, worldThree.xyz - center) + center,1);

 

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image IVIachine · Jan 13, 2018 at 01:45 AM 0
Share

Oh my god! I cannot believe I didn't catch that!. Thank you so much for your help!

avatar image Bunny83 IVIachine · Jan 13, 2018 at 01:54 AM 1
Share

Don't worry, it almost slipped my eye as well ^^. I spend a lot time to verify your rotation matrix is correct (which is but it seems to be inverted / transposed when you compare it with the one given on wikipedia. So you basically rotate the other way round). Finally by following the code step by step the "float" accidentally hit my eye ^^.

avatar image Bunny83 · Jan 13, 2018 at 01:48 AM 1
Share

Ahh, i just found it in the HLSL documentation:

Vectors may be converted to scalar types (the first element of the vector is selected). A warning is issued if this is done implicitly.

So according to this statement you should actually get a warning. Though i'm not sure if Unity displays all warnings from the shader compiler.

avatar image IVIachine Bunny83 · Jan 13, 2018 at 01:54 AM 0
Share

Would the warnings be in the compiled shader code or in editor?

avatar image Bunny83 IVIachine · Jan 13, 2018 at 02:08 AM 0
Share

Well, if you select the shader asset and look at the inspector it usually shows errors direction in the inspector. However errors usually generate an error log in the console. Though as i said i'm not sure if Unity actually shows warnings.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

139 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Rotate a vertex about "u" Axis 1 Answer

Rotate object on Y Axis when changing transform.up 1 Answer

Set Rotation on Multiple Axis 1 Answer

How to limit how much player can rotate 0 Answers

Rolling a capsule lengthways, sideways and twisting with AddTorque 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges