POM material

All that is left is to do the work, but I don’t mind breaking it down step by step.

First, you need to create the math function that creates your gradient to test with. I am testing with a simple ‘spheremask’ type gradient which actually makes a cone shape as a heightmap:


float x = distance(frac(UV), 0.5);
x*=2;
x=1-x;
return x;

You can use any math to generate the gradient (meaning it could be float1, float2 for 2d, float3 for 3d noise etc) as long as the return value is a float at the sampled position.

Here’s the entire test material so far showing the cone is working:

Now all we need to do is take the parallax function and replace the texture lookup with function using the offset UV from the loop. To make it simpler we will deal with the Parallax-Only version of the code.

Here is the entire Parallax only code:


float rayheight=1;
float oldray=1;
float2 offset=0;
float oldtex=1;
float texatray;
float yintersect;
int i;

while (i<MaxSteps+1)
{
texatray=(HeightMapChannel, Tex.SampleGrad(TexSampler,UV+offset,InDDX,InDDY));

if (rayheight < texatray)
{
float xintersect = (oldray-oldtex)+(texatray-rayheight);
xintersect=(texatray-rayheight)/xintersect;
yintersect=(oldray*(xintersect))+(rayheight*(1-xintersect));
offset-=(xintersect*UVDist);
break;
}

oldray=rayheight;
rayheight-=stepsize;
offset+=UVDist;
oldtex=texatray;


i++;
}

float3 output;
output.xy=offset;
output.z=yintersect;
return output;

We just need to replace line 11 which is the texture lookup with the math function. That line currently is:


texatray=(HeightMapChannel, Tex.SampleGrad(TexSampler,UV+offset,InDDX,InDDY));

If we instead replace it with our math function from before, but with the “+offset” from the UVs, it will just work.

That translates into these 3 lines:


texatray = distance(frac(UV+offset), 0.5);
texatray*=2;
texatray=1-texatray;

Example (I also created a normal map from the gradient to make it more obvious):

Notice slight problem at the base. Its disconnected because I forgot to clamp the cone function.

Fixed:
Function_parallax_bugfix.JPG


texatray = distance(frac(UV+offset), 0.5);
texatray*=2;
texatray=saturate(1-texatray)+0.0001;

I also just realized that any texture that has absolute black 0 in the heightmap can cause that artifact too (hence the +0.0001). I will need to find a more elegant fix for that. Probably by adjusting the if statement somehow. Or I will just add the 0.0001 to the regular heightmap version as well. Doesn’t seem to cause any other issues so far.

I will reply about the other custom rotator stuff later. But if you are only rotating the x and y then that is essentially the same as rotating around the Z axis (0,0,1). So you should be able to use the rotateaboutaxis node. I am not exactly sure how custom rotator works so I will check it out later.