Ever since I started exploring procedural wood shaders, I’ve wanted to then use those to make wooden planked floors. As I mentioned in a previous post, a wooden log is cut into boards by slicing it along the long axis of the trunk, moving outwards from the center.
There are several ways to cut a log, but basically since I have a nice cylindrical chunk of wood I should be able to make “boards” out of it by simply moving the texture coordinates around. So, if I can get a repeated pattern across a flat plane, and move the coordinates in that pattern by random amounts, that’s a wood floor. Simple!
Well, it has eluded me for some time now. This post isn’t a detailed tutorial on creating a wood floor, but it does explain some of the process I went through to get to a shader I was happy with.
Anyway, I noticed that the Brick shader in Blender can give a nice random brick pattern with different colors in the bricks, so I thought, that’s just what I need! I can set the colors of the shader to black and white, and that will give me various shades of gray and I can use those as the offsets. Let’s see, a Brick node on a Plane:
Nailed it:
So if we just add those gray values to the mapping vector of our wood texture, we should be in business. Since those gray values are only in the range 0 to 1, we can probably multiply it by something like 10 to get a bigger range of movement for our wood. Let’s see what happens if we use the Add node to add the output of the brick node to the Vector coming out of the main Mapping node in our Red Oak shader:
Well, that didn’t work at all. It’s hard to even see, but it looks like it’s still one big piece of wood but with parts of it moved around a little.
It occurred to me that the shader we’ve been building uses the Object mapping mode, so the texture coordinates are based on the entire object as if it were solid. Since it’s not UV-mapped across the surface you can’t really warp it any way you want like you could with UVs.
Perhaps I needed a different mode. In Generated mode, the coordinates are mapped from 0 to 1 across the surface of an object, and you can move them around just like UV coordinates, so in theory, that should give me more flexibility.
Initial results are pretty similar to before. I think what is needed is to reset the coordinates to <0, 0, 0> for every brick, and THEN add the gray value for an offset. I tried many things but couldn’t figure out how to get the coordinates to map the way I wanted.
When you are stuck on something Blender-related, a great place to go for help is Blender StackExchange. I found some similar questions but none quite what I wanted, so I posted my own question:
How can I create a staggered repeating procedural pattern?
This is one of the images from the answer:
That looks perfect, if I can just swap out the wood for the colored Voronoi there.
To make a long story a bit shorter, I quickly realized that the problem with this solution was that the pattern repeats perfectly, so while it sort of worked, every single plank looked exactly the same. I spent a long time struggling with how to manipulate each plank so that it looked differently, when I suddenly hit on a solution: I needed to combine BOTH my original idea and this new solution. The brick pattern gave me the different values per plank, and the Blender StackExchange solution gave me the method to reset the coordinates for each plank.
So here’s the Blender StackExchange solution with a simple Voronoi pattern:
I tweaked the settings of a Brick Texture node so that it lined up perfectly with the pattern:
Then I add the values of the Brick Texture to the Z-vector of the StackExchange node:
…and it works!
Plugging in the Red Oak texture with some tweaks, and it’s actually doing the right thing:
I did a lot more tweaking of the numbers, and added a bunch of nodes so that I could use slight shader variations based on the values of the Brick Textures, and I got a result I liked:
Awesome! I won’t post the whole network as it’s a bit messy, but the full shader is available on BlendSwap here. Feel free to download it and dissect it to see this all in detail. I’ll explain how I did the variations of the planks in another post on another day, but in the meantime, here’s a room I used the shader in:
Happy Blending!
Thanks for the tutorials, I’ve learned a lot.
The color/grain pattern on your floor looks great, and it works for a floor with a polyurethane finish. Have you thought much about wood with a thinner oil or wax finish? I’m looking to used the grain pattern to control gloss/roughness ( should be easy).
I’d also like to control the surface normals, so that one part of the grain is slightly raised, with smooth changes to the normals in the transitions between sections of the grain ( should be much harder). I’ve seen this used to great effect for wood created with image textures and their associated bump maps. But I’m working with carved wood, so need the 3d grain that can only be gotten with a procedural texture.
( I’m working on things for game development, so all my procedural results would then be baked into texture maps.)
Thanks for any thoughts
Hi Eric,
Thanks for the kinds words, and I’m glad you’ve found my tutorials educational! Of course it depends on the type of wood as to what the correct effect should be, but in the case of oak, the only part that is really noticeably indented is the grain. In red oak it’s actually little hollow tubes, so when sliced that’s why you get the indentations, and so in the tutorials I connected that part to the Displacement output of the shader so it ought to effect the roughness/glossiness. In fact in the room image above you can see the grain in the reflection of the windows because that part isn’t as glossy as the rest of the floor. Rather than using Displacement, you could certainly use just the grain as a specular map. Also, for the second part of your question, you can run a black-and-white image through a “Bump” node and use the “Normal” output to get a normal map, so you could cut out the Color Ramps and use a grayscale version of the wood for that. I hope this makes sense. If not, let me know and I’d be happy to explain it more or do a blog post about this.