- Home /
 
Transformation matrix with surface shader
Hello,
I'm writing a minimap with fog of war, focus, rotation and scaling features. Now I've hit a snag with the rotation part; somehow, it insists on rotating at the texture corner.
I'm using a matrix thusly:
  void UpdateMatrix()
         {
             if(target != null)
             {
                 // get UV coordinates plus offset
                 posV = target.transform.position - world.transform.position;
                 posV.x = (posV.x/worldSize.x);
                 posV.z = (posV.z/worldSize.y);
                 posV.y = posV.z; // transform to XZ axis
                 posV.z = 0; 
     
                 if(canZoom)
                     // update the zoom level
                     scaV = new Vector3(zoom,zoom,zoom);
                 else
                     // restore the zoom level
                     scaV = new Vector3(1f,1f,1f);
     
                 if(canRotate)
                 {
                     // rotation on Y axis is remapped to texture's Z axis
                     rotQ = Quaternion.Euler(0,0,target.transform.eulerAngles.y);
                 }
                 else
                 {
                     rotQ = Quaternion.identity; // restore rotation
                 }
             }
             else
             {
                 // no target, fixed view settings - restore position, no rotation, original scale
                 posV = new Vector3(0.5f,0.5f,0);
                 rotQ = Quaternion.identity;
                 scaV = new Vector3(1f,1f,1f);
     
             }
     
             matrix = Matrix4x4.TRS(posV,rotQ,scaV);
 
               And the shader part:
 SubShader {
         LOD 100
         Tags
         {
             "Queue" = "Transparent"
         }
         
         Cull Off
         Lighting Off
         
         CGPROGRAM
         #pragma surface surf Lambert alpha
         
         struct Input
         {
             float2 uv_MainTex;
         };
         
         float _Zoom;
         float4x4 _Matrix;
         
         half4 _ActiveColor;
         half4 _ExploredColor;
         half4 _UnexploredColor;
         sampler2D _MainTex;
         sampler2D _FoWMask;
         sampler2D _CutoutMask;
         
         void surf (Input IN, inout SurfaceOutput o)
         {    
         
             half4 basec = tex2D(_MainTex, mul(_Matrix, float4(IN.uv_MainTex, 0, 1.0)).xy); // base
             half4 fowc = tex2D(_FoWMask, mul(_Matrix, float4(IN.uv_MainTex, 0, 1.0)).xy);  // FoW
             half4 finalc = lerp(lerp(_UnexploredColor,_ExploredColor,fowc.g),_ActiveColor,fowc.r); // FoW adjusted color
             o.Emission = basec.rgb * finalc.rgb;
             o.Alpha = basec.a * tex2D(_CutoutMask, IN.uv_MainTex).a;
         }
 
               Note that the world uses XZ plane reference. No matter what I do, I can't seem to get the shader to rotate the textures at the given pivot. Why is that? What am I doing wrong here? I am at the end of my wits.
And yes, I am a beginner, so please do go easy on me!
Thanks for your time.
Answer by MihaP · May 28, 2014 at 07:29 AM
Welp, solved on my own after sleeping it through. The issue was that it rotated the texture around offset from the desired position.
The solution: use two matrices - one to translate,rotate around the desired pivot and scale up. And the other to translate to center of the texture AFTER the rotation and scaling have been done.
     Matrix4x4 m0 = Matrix4x4.TRS(posV,rotQ,scaV); // translate to target position, rotate and scale
     Matrix4x4 m1 = Matrix4x4.TRS(new Vector3(-0.5f,-0.5f,0),Quaternion.identity,Vector3.one); // translate to the center
     matrix = m0*m1;
 
              Your answer