Showing posts with label hexagon. Show all posts
Showing posts with label hexagon. Show all posts

Hexagonal patterns in Blender's geometry nodes

 I have been experimenting a bit with geometry nodes lately and I thought I´d share this one

The .blend file is available from my GitHub repository. (Click the 'download raw file' button in the upper right corner to download it; Inside is a sample scene, and the geometry node itself is called 'Hexagon pattern')

Tips

The input mesh is simply repeated across the pattern and nothing fancy is done to it. If the repeated meshes are butted up to each other you may want to remove any coinciding vertices, and I could have done that in the geometry nodes itself but that is unnecessary as you can easily apply a weld modifier to achieve the exact same effect. And other modifier too of course, like a solidify modifier perhaps, to give the grid some thickness.

If you just want a quick hexagonal pattern in a shader, you may want to have a look at this post.

Some details

The node setup is pretty straight forward:

We get the bounding box of the object we want to repeat, scale it a bit so we can add a gap if we like, and the repeat the mesh for a set number of iterations along the x-axis. Then we replicate the result along the y-direction and end with applying a material index.

If we look at the repeat x section, we see that there isn´t much to it:

We simply join a shifted version of the input for a set number of times. The offset in the x-direction is twice the maximum of x dimension of the bounding box, i.e. we assume that the input mesh is symmetrical around the origin.

The repeat y section isn´t all that much different, except for a little detail:

That detail is that we move the new mesh up in the y-direction by a configurable scaling factor, where the default is fit for a six sided cylinder, a.k.a. a hexagon, but you can change that to something else if needed.
We also move the row either to the right or the left, depending on whether we are in an odd or even row. We determine this odd/evenness by taking the iteration number module 2 and using a switch node to provide a multiplication factor of -1 or 1 respectively that we apply to our x offset. If we wouldn´t alternate this move in the x-direction we would get a skewed grid, which might be find, but I prefer to work with a square grid.



Blender procedural hexagon pattern

I needed a texture for a hexagonal pattern that was fully procedural. In the past I wrote one in Open Shading Language but I wanted one that utilized the GPU and worked for Eevee as well. So I implemented a node group that uses basic nodes only. An example is shown below.



The node group is straight forward to use and has options to change the scale and the width of the line. An usage example is shown in this noodle:


Availability


It is available for download from my GitHub repository. To append the node group so that you can use it in your material, simply select File -> Append ..., browse to the .blend file you downloaded and locate the Hex Nodegroup. After that you can use it in the Shader editor with Node -> Group -> Hex

Implementation details


The Hex nodegroup simply overlays three 60° rotated copies of a pattern of dashed stripes


Each dash is the side of a hexagon. The stripes are created with another node group shown below (click to enlarge)


It contains two almost identical frames: one to produce a set of vertical dashes and another one to create a simlar set but offset in the x and y direction. The dashes are generated each time from a wave texture in the x direction that is combined with a greater than node to produce narrow vertical lines. From this we subtract broader horizontal lines generated in the same fashion to create the gaps between the dashes.

Hexagon shader texture for Blender Cycles on GPU and CPU

First stab at adding a hexagon pattern to Cycles that can be used on the GPU as well as the CPU and that is not based on OSL.

The image was created with the following noodle:

As you can see, the hexagon node provide both a color and two float outputs. The first is the distance squared to the centre of the hexagon, the second one the distance squared to the centre of the nearest neighbour. Having both output allows for the easy creation of an edge, as shown in the noodle.

Code

The code follows the implementation of the OSL version closely and might be sub-optimal. My first steps will be to document my steps in creating a completely new node (because no less than 15(!) files needed to be changed or added to implement a single node. After that I want to optimize the code a bit and wait for feedback on my previous patch before submitting this one.

A hexagon shader in OSL, second edition

A while ago I made a simple OSL shader for hexagonal tilings. Prompted by some questions on BlenderArtists I decided to create a more versatile version that retained the color options but added the distance to the closest edge. That feature may help in creating crips edge patterns because the previously availble distance to the closest center creates rounded shapes that might be suitable for bee hives but not for hard edged stuff like floor tiles etc.

The noodle used to create the image is shown below (click to enlarge):

The color code has stayed the same except for the calculation of the distance to the edge. This might be a bit inefficient, but at least it's easy to read.
The additions are shown below, the full code is available on GitHub.
    // distance to nearest edge
    
    float x = mod(Coordinates[0]/3,1.0);
    float y = mod(Coordinates[1]/3,A2);
   
    #define N 18
    vector hc[N] = {
        vector(  0, -A2/3     ,0),
        vector(  0,     0     ,0),
        vector(  0,  A2/3     ,0),
        vector(  0,2*A2/3     ,0),
        vector(  0,  A2       ,0),
        vector(  0,4*A2/3     ,0),

        vector(0.5, -A2/3+A2/6,0),
        vector(0.5,     0+A2/6,0),
        vector(0.5,  A2/3+A2/6,0),
        vector(0.5,2*A2/3+A2/6,0),
        vector(0.5,  A2  +A2/6,0),
        vector(0.5,4*A2/3+A2/6,0),

        vector(1.0, -A2/3     ,0),
        vector(1.0,     0     ,0),
        vector(1.0,  A2/3     ,0),
        vector(1.0,2*A2/3     ,0),
        vector(1.0,  A2       ,0),
        vector(1.0,4*A2/3     ,0)
    };
    
    float d[N], t;
    
    for(int i=0; i < N; i++){
        float dx = x - hc[i][0];
        float dy = y - hc[i][1];
        d[i] = hypot(dx, dy); 
    }
    
    for(int j= N-1; j >= 0; j--){
        for(int i= 0; i < j; i++){
            if(d[i] > d[i+1]){ 
                SWAP(t, d[i], d[i+1]);
            }
        }
    }
    
    Center  = d[0];
    Edge    = d[1] - d[0];
    InEdge  = Edge < Width;
The approach we have taken is very simple: the hc enumerates all nearby hexagon centers. We then calculate all the distances to these points and sort them shortest to longest (yes with a bubble sort: with 18 elements it might just be faster to do it with a more efficient sorting algorithm at the cost of much more complex code so I don't bother).
The Edge is not realy the distance to the closest edge but the difference between the closest center and the next closest. Near the edge these values are more and more the same so Edge will approach zero. For convience we provide a comparison with some threshold also.
If you would like to know more about programming OSL you might be interested in my book "Open Shading Language for Blender". More on the availability of this book and a sample can be found on this page.