- Home /
Question by
Han-Wen · Jun 04, 2020 at 03:36 PM ·
shaderquaternionrotate
Rotate Gameobject by vertex shader with quaternion
Hi, I am trying to rotate a cube by vertex shader with quaternion, the cube position is (0,0,1), and rotate axis is (1,0,0), I had tried the quaternion rotate method, but things do not work like I expected, it scale up and down the gameobject from the (0,0,0) point, what did I do wrong, this is driving me crazy since I can not figure out why. Please help! Here is my whole shader code :
Shader "Unlit/NewTestTrackShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_OffsetX("Offset X",float) = 0
_OffsetY("Offset Y",float) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent-1"}
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 posWorld : TEXCOORD1;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 posWorld : TEXCOORD1;
};
float4 RotateionAxisToQuaternion(float3 axis,half angle){
half half_angle = radians(angle/2);
float4 q = (axis.x * sin(half_angle),
axis.y * sin(half_angle),
axis.z * sin(half_angle),
cos(half_angle));
return q;
}
/////////
float3 RotateVertexposition(float3 vertexPosition,float3 axis,float angle){
float4 q = RotateionAxisToQuaternion(axis,angle);
float3 v = vertexPosition;
return v + 2 * cross(q.xyz,cross(q.xyz,v) + q.w * v);
}
//// Equal Above Function
float4 quat_mult(float4 q1, float4 q2){
float4 qr;
qr.x = (q1.w * q2.x) + (q1.x * q2.w) + (q1.y * q2.z) - (q1.z * q2.y);
qr.y = (q1.w * q2.y) - (q1.x * q2.z) + (q1.y * q2.w) + (q1.z * q2.x);
qr.z = (q1.w * q2.z) + (q1.x * q2.y) - (q1.y * q2.x) + (q1.z * q2.w);
qr.w = (q1.w * q2.w) - (q1.x * q2.x) - (q1.y * q2.y) - (q1.z * q2.z);
return qr;
}
float4 quat_conj(float4 q){
return float4(-q.x, -q.y, -q.z, q.w);
}
float3 rotate_vertex_position_detail(float3 position, float3 axis, float angle){
float4 qr = RotateionAxisToQuaternion(axis, angle);
float4 qr_conj = quat_conj(qr);
float4 q_pos = float4(position.x, position.y, position.z, 0);
float4 q_p = quat_mult(qr, q_pos);
float4 qp_q = quat_mult(q_p, qr_conj);
return float3(qp_q.x, qp_q.y, qp_q.z);
}
////////////////////
sampler2D _MainTex;
float4 _MainTex_ST;
float_OffsetX,_OffsetY,;
v2f vert (appdata v)
{
v2f o;
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
float3 axis_X = (1,0,0);
float3 axis_Y = (0,1,0);
float3 axis_Z = (0,0,1);
o.posWorld.xyz = rotate_vertex_position_detail(o.posWorld.xyz, axis_X, _OffsetX);
v.vertex = mul(unity_WorldToObject, o.posWorld);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return half4(col);
}
ENDCG
}
}
}
and here is what it look like :
screen-shot-2020-06-03-at-24105-pm.png
(114.3 kB)
Comment
Your answer
![](https://koobas.hobune.stream/wayback/20220612235948im_/https://answers.unity.com/themes/thub/images/avi.jpg)