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.
109174-example.png

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?

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);