- 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