Wojtek Sterna
wojtsterna.bsky.social
Wojtek Sterna
@wojtsterna.bsky.social
Principal Engine Programmer at Flying Wild Hog 🐖
Formerly: NVIDIA, id Software, CD PROJEKT RED, Saxo Bank
Professional 🐱 petter
https://youtu.be/vgsZGZ0csVQ?t=987
t.co
September 30, 2025 at 8:28 PM
𝟰. Unreal uses an even different algorithm with projecting the point to rotate onto the rotation axis. If you make a material using the image below and in the UE material editor go to 𝗪𝗶𝗻𝗱𝗼𝘄 -> 𝗦𝗵𝗮𝗱𝗲𝗿 𝗖𝗼𝗱𝗲 -> 𝗛𝗟𝗦𝗟 𝗖𝗼𝗱𝗲 you can look up implementation of 𝗥𝗼𝘁𝗮𝘁𝗲𝗔𝗯𝗼𝘂𝘁𝗔𝘅𝗶𝘀 function.
July 29, 2025 at 8:49 AM
𝟯. Use Rodrigues' rotation formula (minding the pivot point). This is a pretty neat and fairly short formula that can be used if you don't feel like using matrices or quaternions [2].
July 29, 2025 at 8:49 AM
𝟮. Use a quaternion. Construct a rotation quaternion and transform by it the point we want to rotate (minding the pivot point).
July 29, 2025 at 8:49 AM
And how can such a rotation be implemented? There are at a least a few ways:
𝟭. Use a 3x3 rotation matrix. Build a rotation matrix and transform by it the point we want to rotate (minding the pivot point). Unity seems to be using that approach [1].
July 29, 2025 at 8:49 AM
In Unity's shader graph (Unity's counterpart of Unreal's material editor) we set the position of the vertex directly, and that is reflected in its 𝗥𝗼𝘁𝗮𝘁𝗲 𝗔𝗯𝗼𝘂𝘁 𝗔𝘅𝗶𝘀 node, which contrary to Unreal does not return the offset but returns the absolute rotated point position.
July 29, 2025 at 8:49 AM
So it returns the difference between the rotated point and the input point. This is very much likely due to the fact that in UE5 materials one of the output pins is 𝗪𝗼𝗿𝗹𝗱 𝗣𝗼𝘀𝗶𝘁𝗶𝗼𝗻 𝗢𝗳𝗳𝘀𝗲𝘁, where we put an 𝗼𝗳𝗳𝘀𝗲𝘁 to the vertex position, instead of setting direct value for the vertex position.
July 29, 2025 at 8:49 AM
It is important to realize what is the output of that node because 𝗶𝘁 𝗶𝘀 𝗻𝗼𝘁 the rotated position/point! It actually returns the value of:
𝗥𝗼𝘁𝗮𝘁𝗲𝗱𝗣𝗼𝘀𝗶𝘁𝗶𝗼𝗻 - 𝗣𝗼𝘀𝗶𝘁𝗶𝗼𝗻
July 29, 2025 at 8:49 AM
- 𝗣𝗶𝘃𝗼𝘁𝗣𝗼𝗶𝗻𝘁 - That is the center of rotation, a point around which the rotation will occur.
- 𝗣𝗼𝘀𝗶𝘁𝗶𝗼𝗻 - This is the point/vector that we want to rotate.
July 29, 2025 at 8:49 AM
- 𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗲𝗱𝗥𝗼𝘁𝗮𝘁𝗶𝗼𝗻𝗔𝘅𝗶𝘀 - That is our axis of rotation.
- 𝗥𝗼𝘁𝗮𝘁𝗶𝗼𝗻𝗔𝗻𝗴𝗹𝗲 - That is the angle of rotation. It is quite quirky, because this angle is not expressed in radians or degrees, but in normalized units. A value of 1.0, 2.0, 3.0, ... is a full revolution. 0.5 is 180 degrees rotation, etc.
July 29, 2025 at 8:49 AM
3D engines, like Unreal or Unity, usually expose some functionality that makes such rotations easy. In UE5, in the material editor, as shown in the image below, there is a node called 𝗥𝗼𝘁𝗮𝘁𝗲𝗔𝗯𝗼𝘂𝘁𝗔𝘅𝗶𝘀. It takes four inputs:
July 29, 2025 at 8:49 AM
NormalizedRotationAxisAndAngle.xyz
July 27, 2025 at 3:55 PM
Here's C# implementation:
June 29, 2025 at 2:07 PM
The bolded part is crucial. Nanite, for each pixel has to evaluate 3 vertex positions (of the triangle the pixel belongs to). For that evaluation WPO for each vertex is needed, hence WPO is calculated 3x per pixel.
June 17, 2025 at 9:11 AM
• 𝘜𝘴𝘦𝘴 𝘵𝘩𝘰𝘴𝘦 𝘵𝘰 𝘥𝘦𝘳𝘪𝘷𝘦 𝘵𝘩𝘦 𝘣𝘢𝘳𝘺𝘤𝘦𝘯𝘵𝘳𝘪𝘤 𝘤𝘰𝘰𝘳𝘥𝘪𝘯𝘢𝘵𝘦𝘴 𝘧𝘰𝘳 𝘵𝘩𝘪𝘴 𝘱𝘪𝘹𝘦𝘭
• 𝘈𝘯𝘥 𝘸𝘪𝘵𝘩 𝘵𝘩𝘰𝘴𝘦, 𝘭𝘰𝘢𝘥𝘴 𝘢𝘯𝘥 𝘪𝘯𝘵𝘦𝘳𝘱𝘰𝘭𝘢𝘵𝘦𝘴 𝘵𝘩𝘦 𝘷𝘦𝘳𝘵𝘦𝘹 𝘢𝘵𝘵𝘳𝘪𝘣𝘶𝘵𝘦𝘴."
June 17, 2025 at 9:11 AM
Reference [2] is a link to a presentation from Epic on Nanite, where on slide 23 it says:
"𝘛𝘩𝘦𝘯 𝘢 𝘮𝘢𝘵𝘦𝘳𝘪𝘢𝘭 𝘴𝘩𝘢𝘥𝘦𝘳 𝘱𝘦𝘳 𝘱𝘪𝘹𝘦𝘭:
• 𝘓𝘰𝘢𝘥𝘴 𝘵𝘩𝘦 𝘷𝘪𝘴 𝘣𝘶𝘧𝘧𝘦𝘳
• 𝘓𝘰𝘢𝘥𝘴 𝘵𝘩𝘦 𝘵𝘳𝘪𝘢𝘯𝘨𝘭𝘦 𝘥𝘢𝘵𝘢
• 𝙏𝙧𝙖𝙣𝙨𝙛𝙤𝙧𝙢𝙨 𝙩𝙝𝙚 3 𝙫𝙚𝙧𝙩𝙚𝙭 𝙥𝙤𝙨𝙞𝙩𝙞𝙤𝙣𝙨 𝙩𝙤 𝙩𝙝𝙚 𝙨𝙘𝙧𝙚𝙚𝙣
June 17, 2025 at 9:11 AM