Home Technical Talk

Shader - Rotate Cubemap - Any tips?

polycounter lvl 12
Offline / Send Message
Ace-Angel polycounter lvl 12
Heya peeps,

Been trying to find a way to rotate cubemaps on a shader level (EI: 180* upside down, etc).

Problem is, I'm not sure how to go about it, I tried a following a few random snippets of HLSL on the net, but they all ended up 'warping' my cubemap in one point, rather then rotating it.

So yeah, any tips would be grand and much appreciated!

Replies

  • commander_keen
    Offline / Send Message
    commander_keen polycounter lvl 18
    One way to do this is to convert your normal (used to sample the cubemap) to polar coords, rotate as desired, then convert back to normal coords.

    Heres some C# code i wrote a while ago. Its not optimized and Im not sure if you want the "xAngle -= 90.0f;" line.
    static public Vector3 ToAngles(Vector3 normal) {
    	float yAngle = (float)Math.Atan2(normal.z,normal.x); 
    	yAngle *= 180.0f/(float)Math.PI;
    	yAngle = Mathf.Loop(yAngle,360.0f);
    
    	float xAngle = (float)Math.Acos(-normal.y);
    	xAngle *= 180.0f/(float)Math.PI;
    	xAngle -= 90.0f;
    	xAngle = Mathf.Loop(xAngle, 360.0f);
    	if (normal.y >= 0.999999) {
    		xAngle = 90.0f;
    				
    	}
    	if (normal.y <= -0.999999) {
    		xAngle = 270.0f;
    	}
    
    	return new Vector3(xAngle, yAngle, 0.0f);
    }
    static public Vector3 ToNormal(Vector3 angles) {
    	angles = Vector3.Loop(angles, 360.0f);
    	Vector3 piRot = angles*(float)(Math.PI/180.0);
    	Vector3 normal;
    
    	normal.x = (float)Math.Sin(piRot.y);
    	normal.y = (float)Math.Tan(piRot.x);
    	normal.z = (float)Math.Cos(piRot.y);
    
    	if (angles.x < 180.0f && angles.x > 89.999999) {
    		normal = new Vector3(0.0f, 1.0f, 0.0f);
    	}
    	if (angles.x > 180.0f && angles.x < 270.000009) {
    		normal = new Vector3(0.0f, -1.0f, 0.0f);
    	}
    	return Vector3.Normalize(normal);
    }
    

    Theres probably a better way dealing with matrix multiplication, but I doubt you can do that with a locked down shader system like unreals (assuming this is for unreal).
  • chronic
    Offline / Send Message
    chronic polycounter lvl 10
    This might be a little dirty but it works for me, you stack them one around the other
    float3 rotateVectorAboutX(float angle, float3 vec)
    { 
      angle = radians(angle);
      float3x3 rotationMatrix ={float3(1.0,0.0,0.0),
                                float3(0.0,cos(angle),-sin(angle)),
                                float3(0.0,sin(angle),cos(angle))};
      return mul(vec, rotationMatrix);
    }
    
    float3 rotateVectorAboutY(float angle, float3 vec)
    { 
      angle = radians(angle);
      float3x3 rotationMatrix ={float3(cos(angle),0.0,sin(angle)),
                                float3(0.0,1.0,0.0),
                                float3(-sin(angle),0.0,cos(angle))};
      return mul(vec, rotationMatrix);
    }
    
    float3 rotateVectorAboutZ(float angle, float3 vec)
    {
      angle = radians(angle);
      float3x3 rotationMatrix ={float3(cos(angle),-sin(angle),0.0),
                                float3(sin(angle),cos(angle),0.0),
                                float3(0.0,0.0,1.0)};
      return mul(vec, rotationMatrix);
    }
    
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Thanks guys, will try and see what I connote with these snippets, cheers!

    EDIT: OK, so might as well keep in this thread to keep things organized. When I try straight up HLSL, it seems to be working, but when I try creating in a nodal based app like UDK, no dice.

    Also, it seems to be breaking at 180* angles.

    Here is what I got so far in UDK, I assuming for now float3x3 is a Append?

    38152791.png
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 18
    sometimes simply swizzling or negating components is enough.
    especially for those "magic" angles, the results of cos or sin will be mostly 1 or -1 or so ;)
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Thanks Butcher, will try that and report back, cheers!

    EDIT: Yeah, I have no idea at this point what to do in UDK, I tried doing the shader in Max and RenderMonkey, and they seem to be working (I only need to figure out the correct math for Radians to Degree's to get true values) and they do follow the 'magic' formula, but I guess I'm too stupid to figure out how to open up UDK's rotation to me since it keeps on giving me errors or refusing to rotate.
Sign In or Register to comment.