# I actually managed to figure out cellular noise

Show 40 post(s) from this thread on one page
Page 1 of 2 12 Last
• 05-18-2013, 11:56 PM
jrandom
I actually managed to figure out cellular noise
I wanted to see if I could figure out a cellular noise node before reading up on the Worley algorithm (which gives more interesting results, IMHO). Took me a whole freakin' day, but I got there.

The hard part is going to be implementing bump vector generation without absolutely killing render times.

Attachment 114413

Attachment 114414
• 05-19-2013, 05:00 PM
jrandom
Did some refactoring, and also tried an LCG random-number generator, but it gave artifacty results compared to using the simplex noise for the coordinate distortion routine. A Worley cellular noise node will definitely be faster, but this one works out pretty well visually, especially when using a lot of octaves (which is where using the LCG rng directly tended to fail).

Code:

```// //  Cellular_Noise.cpp //  RainyBrain_Nodes // //  Author: Bradley Wilson //  E-Mail: [email protected] //  Public Domain, Zero Restrictions // // ============================================================================ Standard Includes // Standard Includes // ---------------------------------------------------------------------------- #include <cmath> // ============================================================================ RainyBrain Includes // RainyBrain Includes // ---------------------------------------------------------------------------- #include "../Types/LWTypes.h" #include "Cellular_Noise.h" namespace Noise {     // ======================================================================== Noise Generators     // Noise Generators     // ------------------------------------------------------------------------ Generate (3D)     Cellular_Result Cellular::Generate( const double x,                                         const double y,                                         const double z )     {         // Construct points representing the corners of         // a 3x3 integer box region surrounding the incoming         // point.         LWTypes::LWDVector corners[64];                 const double x_floor = std::floor(x);         const double y_floor = std::floor(y);         const double z_floor = std::floor(z);                 const double x_ceil  = std::ceil (x);         const double y_ceil  = std::ceil (y);         const double z_ceil  = std::ceil (z);                 const double x_coords[4] = { x_floor - 1.0, x_floor, x_ceil, x_ceil + 1.0 };         const double y_coords[4] = { y_floor - 1.0, y_floor, y_ceil, y_ceil + 1.0 };         const double z_coords[4] = { z_floor - 1.0, z_floor, z_ceil, z_ceil + 1.0 };                 for ( int ix = 0, icorner = 0; ix < 4; ++ix )             for ( int iy = 0; iy < 4; ++iy, icorner += 4 )             {                 corners[ icorner    ] = LWTypes::LWDVector( x_coords[ix], y_coords[iy], z_coords[0] );                 corners[ icorner + 1 ] = LWTypes::LWDVector( x_coords[ix], y_coords[iy], z_coords[1] );                 corners[ icorner + 2 ] = LWTypes::LWDVector( x_coords[ix], y_coords[iy], z_coords[2] );                 corners[ icorner + 3 ] = LWTypes::LWDVector( x_coords[ix], y_coords[iy], z_coords[3] );             }                         // Create set of distorted corner points deviating at         // most 0.5 units from the original coordinate.         LWTypes::LWDVector distorted_corners[64];                 auto Distort_Point = [&](LWTypes::LWDVector point) -> LWTypes::LWDVector         {             const Noise::Simplex_Result simplex_noise( Noise::Simplex::Generate( point.X(), point.Y(), point.Z() ) );                         return LWTypes::LWDVector ( point.X() + simplex_noise.Noise_dX * 0.25,                                         point.Y() + simplex_noise.Noise_dY * 0.25,                                         point.Z() + simplex_noise.Noise_dZ * 0.25 );         };                 for ( unsigned i = 0; i < 64; ++i )             distorted_corners[i] = Distort_Point( corners[i] );                         // Find distorted corner closest to incoming point         const LWTypes::LWDVector xyz_prime( x, y, z );                 unsigned closest_corner_index    = 0;         double  closest_distance_squared = Math::Distance_Squared( xyz_prime, distorted_corners[0] );                 for ( unsigned  current_corner_index = 1;                         current_corner_index < 64;                       ++current_corner_index)         {             const double distorted_distance_squared = Math::Distance_Squared( xyz_prime, distorted_corners[current_corner_index] );                         if ( distorted_distance_squared < closest_distance_squared )             {                 closest_corner_index    = current_corner_index;                 closest_distance_squared = distorted_distance_squared;             }         }                         // Return distance scaled to [-1, 1] and region         const double            downsample    ( 0.625 );         const LWTypes::LWDVector closest_corner ( distorted_corners[closest_corner_index] );                 return Cellular_Result( (closest_distance_squared * downsample * 2.0) - 1.0,                                 Noise::Simplex::Generate( closest_corner.X(),                                                           closest_corner.Y(),                                                           closest_corner.Z(),                                                           Gradient_Flags_t::No_Gradients ).Noise_01() );     } }```
The constant I use for scaling down the output was determined by trial-and-error because I don't math well.
• 05-20-2013, 01:36 AM
jrandom
Oh hey, regions! Can't believe I forgot to wire up that particular output. I mean, the code was right there.

Attachment 114429

Attachment 114430
• 05-22-2013, 12:43 PM
jrandom
Final verdict: pretty-looking, but slow and doesn't do anything a fully-featured Worley noise node wouldn't do. It was an interesting experiment, but I'm going to scrap this one and just move on to a good Worley implementation.
• 05-22-2013, 03:54 PM
probiner
hey jrandom, don't understand a things but it is always nice to see ppl stretching things to get somewhere :)

Cheers
• 05-22-2013, 05:04 PM
jrandom
There's not a lot of activity in this forum, so I talk a lot and post code in the hopes that it might help out any random newbie node devs who stumble through here.
• 05-23-2013, 12:20 AM
jrandom
(My development cycle has slowed down greatly since I installed Skyrim on my XBox. In retrospect, that may have not been the greatest idea ever.)
• 05-23-2013, 09:26 PM
GoatDude
I would love to be a node developer, but I have enough trouble just trying to use them.
• 05-24-2013, 01:26 AM
jrandom
Nodes are great and highly-intuitive. You have to completely ditch the "layer" mindset, though. :) Instead of layering things on top of each other, you're plugging outputs into inputs. It's wonderfully powerful.
• 05-24-2013, 06:22 AM
kmacphail
Thanks jrandom, I greatly appreciate you taking the time to post your code and results.

Cheers,

-Kevin
• 05-24-2013, 12:24 PM
jrandom
If I can get Worley noise working this weekend, I'll go ahead and post the entire codebase so anyone who's trying to implement procedural texture nodes can take a look. (I won't actually be compiling the final binaries for win/mac as I don't want it to bo an official release until I get a wider variety of texture nodes implemented, so it'll be a source-only sorta deal.)

And to think this all started because I wanted a better Brick node...
• 05-26-2013, 04:03 PM
jrandom
As promised, C++11 source code for Simplex and Worley Cellular noise types. The actual noise algorithms are in Noise/ and the nodes themselves are in RainyBrain_Nodes/Textures_3D.

The code could certainly stand for some refactoring and the Worley node doesn't have bump map generation implemented yet, but the basics are all there.

Attachment 114529 Attachment 114528
• 05-26-2013, 06:00 PM
pinkmouse
Quote:

Originally Posted by jrandom
...And to think this all started because I wanted a better Brick node...

With different bonding patterns? :D
• 05-26-2013, 08:28 PM
jrandom
Quote:

Originally Posted by pinkmouse
With different bonding patterns? :D

Any good examples you could point me at? I'm not entirely sure what that means.
• 05-27-2013, 03:23 AM
pinkmouse
Here you go, Bonds. The standard running bond that LW and others produce is common on modern buildings that use brickwork as a decorative skin over blocks or concrete slab, but anything older than 50 years or so will use one of the alternating bonds as they are structural. I wouldn't fret about all of them, but English, Flemish, and possibly garden wall or American should do 99% of applications.

Oh, and if you haven't seen the DP Renderman brickwork node, have a look at it, it does some interesting things.
Show 40 post(s) from this thread on one page
Page 1 of 2 12 Last