Sign in to follow this  
genesys

rotating uv's

Recommended Posts

I want to rotate a texture on a plane . . . so i'm trying to rotate the uv coordinates. To achieve that, i want to conver the cartesian uv coordinates into polar coordinates, changing the angle and then converting them back into cartesian coordinates . . . this is my code (at the moment i'm not changing the angle - so the formula shouldn't change anygthing - but unfortunately it does): float angle = (atan((Input.uvcoordinate.y-0.5)/(Input.uvcoordinate.x-0.5))+PI*(step(Input.uvcoordinate.x-0.5,0))*sign(Input.uvcoordinate.y-0.5))/(2*PI); float radius = sqrt(pow(Input.uvcoordinate.x-0.5,2)+pow(Input.uvcoordinate.y-0.5,2)); Output.uvcoordinate = float2(radius*cos(angle)+0.5, radius*sin(angle)+0.5); Can someone help me with that?

Share this post


Link to post
Share on other sites
Is there any reason that you're not using the texture matrix for this? In case you weren't aware, you can set the texture matrix for the texture stage to a rotation matrix, which will result in the texture coordinates being rotated

Share this post


Link to post
Share on other sites
Since someone asked about texture matrices yesterday, here's the link.

You can apply a transformation (translation, rotation, etc.) to your UVs inside the D3D pipeline, rather than modifying vertices. The advantage is that on modern cards, you just put you original vertices in static on-card buffers, this saves tons of AGP bandwidth, and will render faster.

The hardware T&L if you're using the fixed pipeline, or your vertex shader if you're using shaders, can transform the UVs by a matrix as it's processing your vertices for other things, such as light, etc. Just tell D3D what the matrix is, tell it you want to transform texture coordinates, and then draw.

Share this post


Link to post
Share on other sites
And how can I implement this transformation in my HLSL code??

unfortunately i'm "just" the artist . . . modeling 3D stuff and writing some HLSL shaders for them - but i've absolutely no indepth clue of a 3D API . . .

Share this post


Link to post
Share on other sites
now i'm trying that:

float2x2 rotation = {cos(time), -sin(time),
sin(time), cos(time)};

Output.uvcoordinate = dot(rotation, Input.uvcoordinate.xy);




but it also doesn't work . . . just getting the error

error X3017: 'dot': cannot implicitly convert from 'float2x2' to 'const float1'

Share this post


Link to post
Share on other sites
You'll want the matrix to be a float3x2 if you're going to include translation at some point. If it's just rotation then float2x2 is fine.

You want to use mul, not dot. MUL is used to multiply a matrix by a matrix, or a vector by a matrix. DOT is used for dot products of 2 vectors, and always produces a single float output.

Output.UV = mul(IN.coord0, rotation);

if you opt for float3x2 and do translation too, you'll need this tag a 1.0 on the end of the UV coordinate for it to work correctly.
Output.UV = mul(float3(IN.Coord0.x, IN.coord0.y, 1), rotation);

(I haven't tested the above snippets...)

Share this post


Link to post
Share on other sites
Excuse me, but I'm poised with the same delima.
It seems if I want to use a HLSL shader then I cannot use a TextureMatrix to rotate my textures.


So where do I modify the tu,tv coords? before the pixel shader I would assume?

Share this post


Link to post
Share on other sites
Yes, if you're using a vertex shader, you must replace all vertex processing, which includes

WORLD, VIEW, PROJECTION transforms
TEXTURE transforms
Fog
Lighting
Texture Coordinate Index selection
Texture Coodinate Generation (TSS_TCI_CAMERASPACENORMAL, etc.)
Fixed function matrix palette skinning (only ATI in fixed function anyway)

Just like the world matrix setting texture transforms in D3D's normal fashion does nothing when using a vertex shader.

Just do like you do for the world transform. For world, you must make a variable to hold the world matrix and then you must transform your position by the world matrix in your shader, then in C++ you need to set the matrix with the effect interfaces each frame, instead of using SetTransform(D3DTS_WORLD, mat). In pretty much the same way, you must make a matrix variable for your texture transform, you must apply the transform yourself in the shader (as shown above), and in your C++ code you must generate and set the matrix in the effect interface, instead of SetTransform(D3DTS_TEXTURE0, mat);

Share this post


Link to post
Share on other sites
Yup I got it all working.
I am rotating my cloud, cloud noise and cloud detail textures very simply in my VS now.

Curious tho, I cannot seem to directly change the way it rotates without causing some massive uglyness.

//rotate tu,tv
float2x2 rotation = {cos(time), -sin(time),
sin(time), cos(time)};

OUT.texCoordDiffuse0.xy = mul(IN.texCoordDiffuse0, rotation);
OUT.texCoordDiffuse1.xy = mul(IN.texCoordDiffuse1, rotation);
OUT.texCoordDiffuse3.xy = mul(IN.texCoordDiffuse3, rotation);


I am not rotating texCoordDiffuse2 cuz it is a sunset gradient texture, it never needs rotating.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this