Showing posts with label stone. Show all posts
Showing posts with label stone. Show all posts

Stonework - A Blender add-on to create stone walls


blenderaddons-ng



There are other options out there, (including my own, probably broken add-on) to create stone walls, but I wanted to try our how easy it would be to create a new add-on that would fit the development and testing framework I am creating, so I created this mesh generator that creates a wall of bricks or stones, with several options to randomize and tweak it.





It creates a clean mesh, although currently it does not add uv-coordinates.

It can be downloaded directly from here, or you might want to have a look at the repository and see what it is about.






Description



Brainrot warning: The following description was generated by an LLM

The add-on  provides an operator that creates a customization "stonework" wall mesh made up of rows of randomly sized rectangular stones separated by configurable gaps. The main features and functionality are:

  • Adds a new mesh object to the scene representing a wall made of stones.
  • Customizable wall dimensions: You can set the total width and height of the wall.
  • Configurable stone size: Control the minimum and maximum width of stones, the height of each row, and the width of the first stone in each row.
  • Randomization: Stones in each row have random widths (within user-specified limits), and you can set a random seed to get a different placement of the stones.
  • Gaps between stones: You can specify the width and depth of the gaps between stones, making the wall look more realistic.
  • Half-stone probability: Optionally, some stones can be half-width for a more natural, irregular pattern.
  • Mesh construction: The add-on ensures all faces are connected, merging vertices where stones meet and splitting faces where a vertex lies on another face’s edge.
  • Extrusion: Stones are extruded along the Z-axis by the gap depth, giving the wall a 3D appearance.
  • User interface: The operator appears in the "Add" menu in the 3D Viewport, under the name "Stonework Wall".

This add-on is useful for quickly generating stylized or realistic stone or brick wall meshes for architectural visualization, games, or other 3D projects.


Irregular stone patterns in OSL, a first attempt

On the BlenderArtists forum a member was analyzing irregular stone walls and posed the interesting question: does this resemble a tree pattern and can it be done in OSL? Quite a lot of thinking and tinkering is needed for a full solution put in this post we explore some of the basic requirements.

Irregular stone patterns


A sample pattern with primary colors, Mondrian eat your heart out :-)
The sample image shows that we have generated a pattern consisting of rows with different heights, each consiting of stones of varying width. Additionally, some stones within a row are further split horizontally. The code to generate the pattern is shown below:
shader stones(
  point p = P,
  vector Scale = 1,
  float w = 0.02,
  float s = 2,
    
  output float Fac = 0
){
  point Pos = p * Scale;
  
  float bot = floor(Pos[1]-1)+cellnoise(Pos[1]-1);
  float lev = floor(Pos[1])+cellnoise(Pos[1]);
  float top = floor(Pos[1]+1)+cellnoise(Pos[1]+1);

  if( Pos[1] < lev ){
    Pos[0] += s*cellnoise(Pos[1]);
  }else{
    Pos[0] += s*cellnoise(Pos[1]+1);
  }
  float left = floor(Pos[0]-1)+cellnoise(Pos[0]-1);
  float mid = floor(Pos[0])+cellnoise(Pos[0]);
  float right = floor(Pos[0]+1)+cellnoise(Pos[0]+1);
  if( 
    ((Pos[0] > left+w) && ( Pos[0] < mid - w )) 
    || 
    ((Pos[0] > mid+w ) && ( Pos[0] < right - w))
  ){
    if( 
      ((Pos[1] > bot+w) && ( Pos[1] < lev - w )) 
      || 
      ((Pos[1] > lev+w ) && ( Pos[1] < top - w))
    ){
      int stoneindex=0;
      float seeda = left;
      float seedb = bot;
      float bounda = mid;
      float boundb = lev;
      
      if( Pos[0] > mid ){ stoneindex += 2; seeda = mid; bounda = right; }
      if( Pos[1] > lev ){ stoneindex += 1; seedb = lev; boundb = top; }
      int pattern = (int)floor(cellnoise(seeda,seedb)*4);
      if( pattern == 0 ){
            // horizontally halved
            float nlev = (seedb + boundb)/2;
            if( (Pos[1] > nlev - w) &&  (Pos[1] < nlev + w) ){
              Fac = 0;
            } else {
              Fac = cellnoise(vector(seeda,seedb,Pos[1]>nlev));
            }
      } else {
        Fac = cellnoise(vector(seeda,seedb,-1));
      }
    }
  }
}
(The code is also available on GitHub.)

Sample node setup

The example image at the top of this article was made with the following node setup (click to enlarge)
:

Further work

Obviously we need more sub patterns for the individual stones and add some distortion to the underlying coordinates to make really random stones. It would probably also be a good idea to vary the spacing between the stones and use the output value to drive displacement and bump maps and the code could certainly do with a bit of cleanup but I thinks this approach is at least shows promiss.