Showing posts with label leaves. Show all posts
Showing posts with label leaves. Show all posts

NewGrowth interactive tree modeling for Blender: new version



NewGrowth, the Blender add-on that lets you interactively paint 3d trees, got a number of nice new features:

Many drawing options can now be changed while drawing

No need to choose them before you start creating a tree.
This includes the branch segment length and the kill distance. This means you can now create bushier and more sparse sections in the same tree.

Tree finalization now sports a Curve option

This will generate a curve based trunk instead of a mesh based one. This results in a superior quality trunk and is faster as well, so this is now the default. The old methods are still there and because this is all parameterized this means you can convert trees created in older versions of NewGrowth to the new curve model and back if you want.

Twig generation

You now have the option to add twigs consisting of three leaves instead of just a single leaf, which will quickly enhance the density of your tree.

Minor tweaks and bug fixes

Too many to list them all here but you now have the option to add some root and branch flare and if yo draw in rendered view instead of solid view the interactive tree is no longer all black.

The fully illustrated manual has been updated as well to reflect all the changes and the add-on is now tested on Blender 2.83 LTS




Random Vertex Colors, a simple addon

In a previous article I presented an addon to generate a floor board with individual planks. Each individual plank was adorned with a random vertex color that can be used to create materials with random color variations for each face.

When working with the Ivy Generator recently I wanted this same feature and indeed my own space tree addon could benefit from this as well, because just like IvyGen it generates a single mesh object with a face. for each leaf. So I decided to separate this functionality from the floor board generator so it can be used in different situations.

Once the addon is installed it can be used on any mesh object when in vertex paint mode as shown below:

It will replace the vertex colors of the active vertex color layer with colors that are random but equal for each face. In Cycles vertex colors can be accessed with an attribute node, an example node setup can be found in the article on the floor board generator referred to at the start of this article.

Code availability

All functionality of this add-on plus a lot more is now available as a convenient all-in-one add-on on BlenderMarket. It comes with an extensive PDF manual and your purchase will encourage me to develop new Blender add-ons.

The simple code shown in this article is available for download at GitHub and is uploaded to the upload section of Blender extensions tracker so if you find bugs you may post them there as well.

[2016 Feb 7] The version currently in GitHub is much faster for large meshes because it uses Numpy. Check this article to see why.

A new tree add-on part V: speeding up skinning of the tree skeleton

one of the issues that bothered me about my new tree add-on was that applying the skin modifier to flesh out the branch skeleton was incredibly slow, especially for larger trees. I therefore decided i'd try writing my own skinning routine and the results are quite promising: a factor 10 or more for moderately sized trees.


The new version (0.0.7) is as usual available on GitHub. How to use and install this add-on is documented in previous articles: I II III IV.
The new skinning method is the default if you uncheck the no modifiers checkbox but if you like you can still select Blenders skin modifier from the drop down as shown on the right. (This can also be done later because we leave the skeleton itself intact; as it only consists of edges it won't show up in renders but you could use it to add any modifier later on).

Timings

The table below lists some timings for my computer, all values were left to their defaults except for the number of endpoints:
Timings in seconds for generating a tree skeleton
Endpoints No modifier Own skinning Blenders skinmod
100 0.02 0.04 0.46
200 0.04 0.07 0.74
400 0.08 0.16 1.51
400 0.56 0.87 14.43

The last line shows the results for a fair sized, bushy tree (400 endpoints, but with the internode length and kill distances reduced to 0.5 and 2.5 respectively and with 3000 extra endpoints per 1000 iterations). The difference between less than a second and more than 14 seconds is the difference between comfortable modelling and frustration, and there is still some room for improvement because the code is still riddled with print statements.
There are three factors that help to speed up the skinning operation compared to blenders built-in skin modifier:
  • unlike the modifier we do not have to make a copy of the mesh,
  • we also generate a lot less geometry it seems and
  • we don't have to deal with special cases: the skin modifier can handle any geometry while our skinning just has to deal with straight edges or simple forks.

Results

When we apply a subsurface modifier to our skinned branches the result is already quite acceptable although I see room for improvement, specifically in the shape of the forks. As you can see there is some bulging were the branches join and this is especially noticeable when there is either a very sharp anngle between the branches or when both branches bend out of plane. Fortunately the highlighted 5-gon lends itself to all kinds of angle dependant adaptations so I expect I can tweak this further to get smoother results.
The focus for the next minor release will be on bug fixing and code cleanup to prepare for a full 1.0.0 release. This will be accompanied by better (hopefully: -) docs as well.

New tree addon part II: a better workflow

Version 0.0.4 of my new tree add-on is focused on defining the crown shape with groups of objects

usability enhancements

In the previous version of the add-on the markers or endpoints that represent the resources that the growing branches compete for were distributed inside an invisible ellipsoid. The resulting distribution could me made visible with the show markers option but from a usability point of view that was not ideal. likewise the su bstraction of markers from the distribution for those markers that were in the set of currently selected objects was less than intuitive, the more so since producing a tree would deselectsll objects forcing the user to select them again when trying for a different tree shape.

In this new version we allow for different way to define a crown shape using groups. If you select the use groups option you can choose three different groups:

    the Crown group
    any markers generated will lie inside the objects that are part of this group.
    the Shadow group
    any markers generated will not lie in any objects in this group. This group is optional.
    the Exclusion group
    growing branches will not penetrate into any objects in this group but stop. This group is also optional.
The shape of the marker cloud is determined by the combined shapes of the objects in the crown group minus those in the shadow group. If you use a shadow group it must be different from the crown group otherwise no markers would be produced at all (although there is a safeguard in the add-on to prevent this). If you use an exclusion group this should differ from the crown group as well although it might be the same as the shadow group.

workflow

The workflow now becomes pretty straight forward:

  • create a crowngroup, for example a bunch of different icospheres,
  • assign anything casting a shadow to a shadow group (here a box),
  • optional: assign anything impenetrable to an exclusion group (or reuse the shadow group),
  • position the 3d cursor at the place where the bole of the tree should start,
  • click update tree (here shown with the parameter settings that produce the tree in the screenshot),
Of course you can alter the other options as well. Don't forget to disable any objects for rendering that you used just to define a group otherwise you won't see much of your tree.

Code availability

This release is version 0.0.4 and avaible as a zipfile on GitHub

A new tree add-on

Blender already has a few add-ons to generate plant or tree objects, notably IvyGen and Sapling and recently I added a general L-system add-on into the mix. In this post I present a new add-on that creates trees based on the space colonization algorithm by Adam Runions.

A new kind of tree

This add-on now has a professional cousin available on Blender Market. It offers new functionality like controlling crown shapes with the grease pencil and is bundled with quite a few ready to use trees that can be used as is or function as a starting point. A YouTube playlist with examples/tutorials is available as well.

Documentation for this add-on now has its own page.

The GitHub repository now serves version 0.0.4 which makes it possible to define the shape of the crown with groups of objects. Details can be found in this follow-up article.
The GitHub repository now serves version 0.0.3 which allows more than one leaf per internode and has a control to determine how much these leaves are clumped. Note that the oft maximum of leaves is still 1.0, if you want more, click and alter the value by hand.
The GitHub repository now serves version 0.0.2 which adds the ability the enable the generation of new endpoint markers while the tree is generated. This will allow for bushier trees with extra small twigs on the main branches
[Some additional sample trees are near the end of this article] Because IvyGen is limited to climbing shrubs and Sapling requires a fair amount of user interaction to get nice results, I thought it would be interesting to explore the possibilities of generating trees with the space colonization algorithm as described by Adam Runions.
This algorithm models the growth of a tree by letting branches compete for resources (think light) as they grow. The distribution and density of these resources control the final shape and the algorithm lends itself easily to adapt to environmental influences like walls blocking light etc. a feature that comes in handy when doing architectural modelling for example.
In the first version of this add-on many features are already available but it is not yet a finished tool. Any remsrks and criticisms are welcome of course. This article describes how to install and use the add-on but does not give an in depth account of its design or underlying principles, that is left for a later article. I do present some example images with their parameter settings to get you started.
The code is available on github. Just download the latest zip from the release directory and install the add-on with File->user preferences->addons install from file by pointing it to the zip file. You can then toggle the checkbox to use it (It is in the Add Mesh category as SCA Tree Generator). Remebr to uninstall the add-on first if you installed an earlier version by clicking the remove button.

Creating a tree

To add a tree, position your 3d cursor where you would like the tree to grow and select Add->Mesh->Add Tree to Scene. A small tree skeleton will appear and in the toolbar on the left of the 3d view will be a number of options. (Press T if the tool bar isn't visible) User interaction is copied from IvyGen so changing the values of options doesn't have an immediate effect but new values are applied when you click update tree. This is necessary because generating larger trees can take quite some time and if that was attempted on each value change the add-on would become unusably slow.
An overview of all the options is available with the source, here we just highlight the more important ones.(tip: before you start experimenting it might be a good idea to check the no modifiers checkbox because the tree trunk is given substance by the skin modifier and will take many seconds on larger trees}
The whole idea of the space colonization algorithm is to populate a volume (an ellipsoid in our case) with markers and let a growth point (at the the 3d cursor) start growing in the direction of the nearest markers. As a growth point (called internode or branchpoint in the add-on in a not entirely botanically correct fashion) approaches a marker close enough, this marker is removed and subsequent growth is in the direction of a slightly different set of nearest markers. A branchpoint can have any number of markers in its sphere of influence but conversely a marker has only a single closest branchpoint. Because of that branches may develop sideshoots (read more on this in the original article)
This means that the number of markers and their distribution are the crucial parameters in determining the shape of the final tree,(tip if you check the show markers option in the debug panel, the markers that were generated at the start of the tree generation will be visualized as small tetrahedrons. That way you get a clear picture of their distribution. This feature is used in most images that follow.)

Some example trees and their marker distributions

Note that only the parameters that differ from their defaults are shown in the picture.

Few endpoints vs. many endpoints


Near central axis vs. near surface


More endpoints near the top


Mix and match


Even shrubs are possible as shown on the right.

adding leaves

When you click the add leaves button a new panel with options will appear with controls for the leaves. The number of leaves controls the probability that an internode (branch segment) carries a leaf. The size and size variation of these leaves can be controlled, as well as the variation in orientation of the leaves. The number of connections option controls how much 'old wood' carries leaves. If you set this to 1 only new twigs will carry leaves.

Shaping the branches

When you click on the add modifiers option, three modifiers are added to the trunk skeleton (shown in the opening image of this article):
  • a subsurface modifier to smooth the branches,
  • a skin modifier to give volume to the branches and
  • another subsurface modifier to smooth this skin.
Note that calculating these last two modifiers may take many seconds or even minutes if the tree is complex!
The thickness of the trunk and branches and the way the thickness of forking branches is combined is controlled by the Scale and Power options respectively.

Environmental influence

A final feature of this add-on that almost comes naturally with the space colonization algorithm is the ability to factor in environmental influences. For example if one side of the growing tree receives more shadow than the other side due to a wall or building, that side will grow less. We can easily mimick this by not placing any markers in a shadowed area. To accomplish this the add-on checks whether any of the markers is generates is inside any of the selected mesh objects in the scene and discards them if they are. The workflow is then:
  • select one or more objects (first image below)
  • position the 3d cursor where you want the tree to start
  • tweak any options
  • update the tree
The result (with markers) is shown in the second image below.

Note that we did not select the actual wall, but a larger duplicate (that we will not render), because the shadow influence normally extends beyond the wall and because a new branch might still pass through this exclusion zone towards markers that are above it. By chosing a wider volume we prevent those branches to pass through the actual wall.

Limitations

In this first version there will undoubtably be any number of bugs. One of the most annoying issues is that when the kill distance is chosen too small, a developing branch may terminate in a myriad of tiny segments. This will not only take an enormous amount of time when adding the skin modifier but will also cause a strange clump of hundreds of leaves at that point.
Another thing is that even when not actually generating new geometry, the user interface is sometimes slow when modifiers are selected. I have a hunch this might be related to Blender keeping track of this complicated geometry in its undo cache but I am not sure.
Of course there is also plenty of room for functional improvements: it would be nice if you could select more than one starting point for example to create hedgerows etc. and also have arbitrary objects instead of square leaves, but those are nice to haves for the future.

Some more examples


The following images show the same type of tree as the opening image of this article, but at more mature stages:

The masked leaf texture as well as the concrete and brick textures are from cgtextures.com, the latter two converted to various types of specular and bump maps with the free shadermap commandline tool. The hdri-background is Alex Hart's 'Arboretrum in Bloom'.
The most mature tree was generated with the settings shown below:

OSL leaf veins shader for Cycles

When we look at images the addition of veins greatly adds to the preceived realism of rendered leaves and in this article I present a simple veins shader that complements the leaf shader discussed previously.

Leaf veins

I forgot to update the page that describes equations.h (thanks samblerdevel for pointing that out). I just corrected that so if you had any errors complaining abot a function splinedist() that was missing, download & install equations.h and try again

The node setup used to create the leaf shape and veination in the close-up image above is relatievely complicated and presented at the end of this article. Luckily, the basic stuff of generating vein patterns is not that complicated so lets have a look at that first.

As illustrated in the images above the veins in the leaf are all represented by cubic splines, starting at the red dots on the central vein and curving to the green end points on the edge of the leaf. Their curvature is controled by the blue control points. A node setup for the image above looks like this:
The Angle and L parameters mimic the ones in the leaf shape shader and are kept the same in this case to let the endpoints of the veins coincide with the actual leaf edge. The number of veins, their distribution, width and the way they curve are controlled by the Veins, Width, Squish and Up parameters as we will see later on. Their is some randomness in the placement as well which can bee influenced by the Seed and Var parameters. The outputs consist chiefly of a Vein socket which will be one for a vein, and a Fac socket which is the square root of the distance to the center of the vein and can be used to drive displacement.

The code for this node is shown below makes use of the equations.h include discussed in the article on leaf shapes.


#include "equations.h"

shader arcuateveins(
point Pos = P,
int Veins = 7,
int Seed = 42,
float Var = 0,
float Width = 0.05,
float NWidth = 0.25, // size of the reticulated area

float Squish = 0.5, // distribution of endpoints on edge
float Squish2 = 0.5, // distribution of controlpoints
float Squish3 = 0.5, // distribution of starting points
float Up = 0.5,

float Angle1 = 70,
float L1 = 1,
float Angle2 = 70,
float L2 = 1,

output float Vein = 0,
output float Net = 0,
output float Fac = 0
){

float delta = 1.0/((float)Veins+1);
float delta2= delta/2;
float delta4= delta/4;

// calculate the four control points of the cubic spline that defines the leaf edge
float x1,y1,x2,y2;
sincos(radians(Angle1),y1,x1);
sincos(radians(Angle2),y2,x2);
point P0 = point(0 , 0 ,0);
point P1 = point(x1 , y1,0)*L1;
point P2 = point(1-x2*L2, y2*L2,0);
point P3 = point(1 , 0 ,0);

point P0q = point(P0[0],P0[1]*Up,P0[2]);
point P1q = point(P1[0],P1[1]*Up,P1[2]);
point P2q = point(P2[0],P2[1]*Up,P2[2]);
point P3q = point(P3[0],P3[1]*Up,P3[2]);

int i;
for(i=0;i < Veins;i++){

// determine the starting points of the veins
float x = (i*delta+delta2*Var*cellnoise(i+10+Seed))*Squish3;
float dx = (delta4*Var*cellnoise(i+17+Seed))*Squish3;
point P0up = point(delta2+x+dx,0,0);
point P0down = point(delta2+x,0,0);
// determine the endpoints on the leaf edge
float t=(i*delta+delta2)*Squish+1-Squish;
point P2up = cubicspline(t,P0,P1,P2,P3);
point P2down = point(P2up[0],-P2up[1],P2up[2]);
// the veins are quadratic splines, so need one additional control point
t=(i*delta+delta2)*Squish2+1-Squish2;
point P1up = cubicspline(t,P0q,P1q,P2q,P3q);
point P1down = point(P1up[0],-P1up[1],P1up[2]);

float r;
int f = splinedist(P0up, P1up, P2up, Pos, r, t);
if ( f && (r < NWidth ) ) Net = 1 ;
if ( f && (r < Width * ( 1- t) * (1-Pos[0]) ) ) { Vein = 1; Fac = sqrt(1-r/Width); break; }
f = splinedist(P0down, P1down, P2down, Pos, r , t);
if ( f && (r < NWidth ) ) Net = 1 ;
if ( f && (r < Width * ( 1- t) * (1-Pos[0]) ) ) { Vein = 1; Fac = sqrt(1-r/Width); break; }
}

// the central vein
float d = distance(point(0,0,0),point(1,0,0),Pos);
if ( d < NWidth ) Net = 1 ;
if (d < (Width * (1-Pos[0])) ) { Vein = 1; Fac = sqrt(1-d/Width);}
}

Relation to real venation patterns in leaves

The shader in its current form is able to model pinnate and arcuate venation patters and intermediate forms of these. (For an explanation of terminolgy refer to Wikipedia, especially this overview sheet). Its spline-based modelling of the veins is not based on any underlying theory of the formation of veins as it happens in nature, as these reaction-diffusion equations cannot so easily be implemented in an OSL shader (at least not at present: we wouldn't want to redo such a costly simulation again and again for each point being shaded so we would need peform the simulation before we start shading each pixel. Currently there is no facility for adding something to a shader that will be executed once beforehand, although there might be in the future. An alternative approach might be to perform the simulation, maybe in a Python add-on, and store the result in a texture. Here we opted for art before science: if it looks all right we don't care what it is based on).

Controlling the curve shape of the veins

In the following images I have illustrated how you can control the shape of the veins. How much the starting points on the central vein and the control points in the middle and the end points on the leaf edge are bunched up, is controlled by the Squish parameters. The blue control points all lie on a spline that is a copy of the spline that defines the leaf edge by scaled by the Up parameter. Some experimenting shows that is is possible to create both pinnate venation patterns as well as arcuate patterns:

Example node setup

The leaves in the image at the top of this article were created with the following node setup:

The values in the blue box simultaneously control the shape of the leaf edge both in the leaf shader and in the vein shader. The leaf coloring is controled by the nodes in the green box (leaves are both glossy and translucent) while the vein coloring is is defined by the nodes in the red box, the choice being determined by the Vein output socket of the vein shader. The yellow box provides some noisy patterns to drive both the colloration of the leaf as well as mix with the bump patern from the vein shader to drive the displacement. The exact contribution of these displacements is controlled by the purple nodes.

Room for improvement

Although the shader is already quite versatile there is ample room for imrpovement. For example, I would like it to be able to produce palmate vein patters and to control the narrowing towards the tips of the veins. On the other hand the shader is not limited to producing vein pattersn: I imagine it can be used to produce fish bones and bird feather patterns (barbs) as well. I might expand on that in the future.

A OSL leaf shape shader for Cycles

In this first part of a series I present a simple shader that can be used to generate different leaf shapes. In later articles we will add shaders that produce the veins of the leaf.

Simple leaf shape with cubic splines

In the example image we have used the IvyGen addon to generate a single limb of some climbing plant species and used the shader from this article to produce the leaf shapes The node setup for this specific material is dicussed later on. (the stone texture is from cgtextures.com and was converted to a normal map and a displacement map with Shadermap CL. The backplate and environment lighting are from the Topanga Forest B collection by Blochi as found on Sibl archive)

The leaf shape shader is essentially creates one side of a leaf from a cubic spline and mirrors that to the other side to create a symmetrical shape. The spline that is used has four controls.

It starts on the left in the direction of P1 and ends on the right coming from the direction of P2. The lenght and angles of the vectors going to P1 and P2 are inputs to the shader. Some of the shapes you can create are shown below.
Note that it is also possible to define a shape that crosses itself in which case the behavior of the shader is undefined.

The annotated code for the shader is shown below. It includes a small library of functions that will be reused by shaders that will appear on this blog in the near future and this include has its separate page where you can download it and find installation instructions.


#include "equations.h"

shader leaf(
point Pos = P,
float Angle1 = 70,
float L1 = 1,
float Angle2 = 70,
float L2 = 1,
output float Leaf = 0
){

// calculate the four control point of the cubic spline
float x1,y1,x2,y2;
sincos(radians(Angle1),y1,x1);
sincos(radians(Angle2),y2,x2);
point P0 = point(0 , 0 ,0);
point P1 = point(x1 , y1,0)*L1;
point P2 = point(1-x2*L2, y2*L2,0);
point P3 = point(1 , 0 ,0);

// to determin the y value(s) of the spline at the x position we
// are located, we want to solve spline(t) - x = 0
// we therefore gather all factors and solve the cubic equation
float tfactor[4] = { P0[0]-Pos[0],
3*P0[0]+3*P1[0],
3*P0[0]-6*P1[0]+3*P2[0],
P0[0]+3*P1[0]-3*P2[0]+P3[0] };
float t[3];
int nrealroots;
cubic(tfactor, t, nrealroots);

// at this point, the array t holds up to 3 real roots
// remove any real root that is not in range [0,1]
int i=0;
while(i < nrealroots){
if ((t[i] < 0) || (t[i] > 1)) {
int j=i;
while(j < (nrealroots-1)){
t[j]=t[j+1];
j++;
}
nrealroots--;
}
i++;
}

// note that a cubic funtion can have 3 real roots,
// but in this case we ignore such very warped curves
// TODO: w. 3 real roots w could set leaf = 1, if y < y0 OR y between y1,y2
// TODO: seration, possible by determining the closest
// distance (if inside leaf) to the spline and
// determining if w are within some periodic funtion f(t)

// we generate the shape mirrored about the x-axis
float y = Pos[1];
if(y<0) y = -y;

if(nrealroots > 0){
point Sy0 = cubicspline(t[0],P0,P1,P2,P3);
if(nrealroots > 1){
// if we have 2 roots we calculate and order the y values
// and check whether the current y values is between them
point Sy1 = cubicspline(t[1],P0,P1,P2,P3);
if ( Sy1[1] < Sy0[1] ){
if( (y > Sy1[1]) && (y < Sy0[1]) ) Leaf = 1;
}else{
if( (y > Sy0[1]) && (y < Sy1[1]) ) Leaf = 1;
}
}else{
// with a single value we check if we are below the y value
if( y < Sy0[1] ) Leaf = 1;
}
}
}

Example node setup

The node setup used to create the sample shapes look like this:

As you can see there is nothing fancy going on here. The leaves are simple squares with a reset uv-map and a mapping node is used to position the leave onto this square (in this case rotated 90 degrees). The output of the shader is then used to drive a mix shader which shows some green material where there is a leaf and a fully transparent material where there isn't.

Combining things with the Ivy Generator

The sample image at the beginning was create with the IvyGen addon. The leaves it produces are simple square faces that are not connected but nevertheless consist of a single mesh object. Because we want to orient each individual leaf a bit different we need a random number for each leaf. We therefore have to separate each face into its own object.

The workflow to achieve that then becomes:

  1. Create your ivy
  2. Assign the material shown in the noodle below to the leaf object
  3. Goto edit mode
  4. Select all
  5. Select Mesh->Vertices->Separate->By loose parts
  6. Go back to object mode.
Each leaf now is its own object we our leaf material attacthed.

Example node setup II

The noodle consists of three distinct parts:
  • The green part adds a small random rotation around the z axis to each uv map. This will be different for each individual leaf. The actual rotation is done by another OSL shader (given below) because the vector mapping node cannot be driven by inputs.
  • The red part maps the rotated uv to the correct position before handing it to our leaf shader. This mapping is necessary because the squares created by IvyGen are sort of centered on the vines and we want our leaves to protrude from the vined instead of being pierced by them.
  • The blue part is just a simple mottled green shader with some gloss.

The rotation of the uv-map arond the z-axis is performed by an OSL shader because the vector mapping node has no inputs to control the rotation and it would take a lot of vector math nodes to achieve what we want whereas thanks to OSL this rotation is a no-brainer:


shader rotate_z(
point Pos = P,
float Angle = 0,
output point Pout = P
){
Pout = rotate(Pos,radians(Angle),point(0,0,0),point(0,0,1));
}

Next steps

In a next article I will show how to add veins to the leaf shapes.