Non-Linear Displacement

Displacement is known as a shader which moves the points of a surface in the direction of its normal vector. This page shows some research about another type of displacement shading which breaks this convention and gives it another dimension.


Linear Displacement:

This is an exanple of an ordinary displacement shader applied on a surface. The amount of displacement is controlled by a noise function. the surface shader "reads" the amount of displacement on each point and dependin on this value gives it a color ranging from red to pale yellow. (For more information refer to " Displacement" section)

Non-Linear Displacement:



Normally displacement shader moves each point of the surface along its normal vector, then the normals are recalculated.
In my method on the other hand, we don't stop here. The new displaced surface is treated like a usual surface that is going to be displaced again. Now the normal vectors are the ones belong to the displaced surface and each point could be displaced along these new normal vectors.
(see the image on the left)



This is the result of displacing the displaced surface.
Here is the code:

						
 displacement
 Buldge(float    Km = 0.1,
                 Buldge = 0.25,
                 freq = 8;
        output varying float hump = 0)
 {
 normal n = normalize(N);
 hump = noise(P * freq);
   
 // Calculating Displacement -----------------

 P = P + n * hump * Km ;

 // Recalculating Normals --------------------
 N = calculatenormal(P);
   
 // Recalculating Displacement ---------------

 n = normalize(N);
 P = P + n * hump * Km * Buldge ;

 // Rcalculating New Normals -----------------
 N = calculatenormal(P);
 }
						

You can see that the calculation of displacement and normal is happening two times, with a smaller scale in second time.

A Little Further...



We can now play around with different values and functions to create very nice and unique non-linear displacement shaders.

 
 displacement
 BuldgeDisp(float    Km = 0.1,
                     freq = 8,
                     buldge = 0.1,
                     buldgeFreq = 4,
                     buldgeEffect = 2,
                     buldgePhase = 0;
            output varying float    hump = 0)
 {
 normal n = normalize(N);
 hump = noise(P * freq);
   
 P = P + n * hump * Km ;
 N = calculatenormal(P);
   
 //---------------------------------------------

   
 n = normalize(N);
 vector n1 = n * sin ((hump*buldgeFreq+
             buldgePhase)*2*PI)*(buldgeEffect/10);
   
 P =P + buldge * (n1) / 100;
 N = calculatenormal(P);
 }


In this example, the new surface is pushed along the recalculated surface normals and the amount of displacement is multiplied by a sine function. Shading Rate is very important here as we are moving the points in different directions and not only in the direction of normal vector. Therefore a smaller shading rate is suggested for this shader to prevent displacing artifacts. This animation is created only by shifting the phase of the sine function.