• 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?

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

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

Bullet rifling simulation 1 Answer

Using shadow texture to recieve shadows (on grass) 1 Answer

Rotating On Two Axes Independantly 0 Answers

Odd rotation on the wrong axis 0 Answers


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