We won't attempt to model the phenomena behind these variations, but we can simulate them as random processes. In computer graphics, "random" usually doesn't mean completely random, because truly random values would introduce horrible artifacts. Instead, we use a source of randomness called Perlin noise. This is an effect that varies a random value (or vector) smoothly in space. A 2D slice of Perlin noise looks a lot like the surface of a cloud; indeed, the Blender Perlin noise texture is called "Clouds." We can access a cloud texture using the generated coordinates from our 3D timber objects, and we can also use any other value we wish to noisify, such as distance from the center of the trunk or tree age, to do a look-up in the cloud texture.
The first new variation we will introduce is to the shape of the trunk. We want to slowly change from circular rings at the center of the tree to something that might be quite distorted at the outside. After some experimentation, I've found that it works best to scale the radial distance, which use as the input to the age calculation, by a factor based on the angular position around trunk. We implement this by normalizing the radial vector to a unit circle, doing a lookup in the cloud texture, scaling the noise value down quite a bit to a value near 1, and multiplying our radius value by this. Here is the modified material node network:
Next, we will vary the distance between rings with a similar node setup that scales the output of our age calculation:
After putting the two effects together and reducing the amplitude of the radial variations, we get this:
The final node network is fairly complicated:
So, that's our wood grain material. You can download the blend file here and play with it yourself. Time to do some more carpentry illustrations!