Polar Coordinate Material Function

So I’ve been playing around with this to test material functions.

There’s a slight error at the top middle where the texture wraps radially. Looks like the I’m getting values of something like 0.01 to 0.99 instead of 0.0 to 1.0, which is annoying. Not sure why that’s happening. If I can get it to work I’ll try to post it up so anyone can use it.

Okay, figured it out.

You can download it here: http://pietermans.com/blog/downloads/

Here’s a peek:

So what does it actually look like when its applied? I assume its like polar coords filter in photoshop to some degree?

Yeah, that’s more or less what its for. It’s useful for when you need a radial effect like ripples (put the UVs through a panner first).

Why not post a screenshot of the material here? I’d suppose many people feel strange about having to download a single material function from an external site, espacially for a relatively simple one like this.

For anyone interested in converting from cartesian to polar or spherical coordinates, back and forth, check out this post:

That’s a good point, Malkavian! Thanks. I’ve uploaded an image of the graph. Thanks for the link, btw, that looks REALLY useful! :smiley: Do you mind if I include a link to that with the graph on my blog?

Hi! I’m glad that you worked out the issue you were dealing with. Did your initial results from one of the functions provided with UE4?

There is a function in UE4 called VectorToRadialValue that creates radial coordinates as well. I was just curious and wanted to know if you had an issue with the node.

Thanks

btw - you might notice (when viewed at a large scale) that a sampling error forms at the point where the radial gradient completes it’s rotation. To correct this you can select the texture node and change the textures mipvaluemode to miplevel under from within the details panel. You can then use a scalar value in the textures “level” input. This removes the sampling error.

Also, you could alternatively look into the ComputeMipLevel function.

It’s basically the same but the default mat function is always dividing by 2*Pi so there is no parameter to change the radial scale.

True words about the mip artifacts. In UE3 you could fix this by using tex2Dgrad of which I’d assume it’s faster than manually computing the mip level using ddx/ddy and log2.

Its not that easy to tell with that texture but when I simply output the radial as a constant and put it through a frac it repeated three times and a bit. Suspiciously close to 3.14 times! That’s right, I forgot to divide by Pi. Wups. D:

I forgot about VectorToRadialValue. I did blitz through the material compendium but not everythings stuck and I guess that one just fell through the cracks.

Thanks for the advice about mips, I’ll keep it in mind.

Cool - good point about the tex2dgrad function

Feanix - np :wink:

Pietermans Website seems to be down so here is the material graph again. I also added UV Animation/Tiling:


By the way: To avoid this ugly pixel line:

You can manually set to use always the highest mipmap. This will fix it. But careful: this is not good for performance nor quality when you see your texture from distance!

Imgur

The reason is, that for choosing a mipmap, the graphic card looks at two neightbor-pixels and compares the UVs. If the coordinates are far from eachother, the engine chooses a smaller mipmap (because it seems that the polygon/pixels are far in the back of the scene). For us this means, that at the position where our texture “tiles” over the radial coordinates, there’s a big jump in uv-coordinates and because of that the engine chooses the smallest mipmap for those pixels.

10 Likes

Was Looking for this, what code is in the custom node named “atan2” ?

I tried something like this:

// Input: UV (U, V) - standard texture coordinates
// Output: Polar coordinates (Radius, Theta)

float2 UV = In.xy;

// Center the UV coordinates around (0,0)
UV -= 0.5;

// Compute the Radius
float Radius = length(UV);

// Compute the angle Theta
float Theta = atan2(UV.y, UV.x);

// Convert Theta from radians to [0, 1] range if needed
Theta = (Theta + PI) / (2.0 * PI);

// Output the Polar coordinates
return float2(Radius, Theta);

(Name the input “In”)


1 Like