I spent a while making some improvements to my tree editor. Mostly just workflow cleanup, but I also added a few new features. One involved more control over which leaf textures are used for particular leaves, and the other involves removing triangles where the texture is completely transparent. You can see that in the following palm tree: the rectangular leaf grids have their corners chopped off where there are no opaque pixels.
I used these improvements as I was creating a new definition for a palm tree. Here’s a scene with 4 of the generated models:
I’m still not super- satisfied with the lighting on these, but I’m not sure what is missing.
One thing I had been neglecting for a while were specular maps for vegetation. I didn’t think the improvement in visual quality was sufficient enough to incur the cost of an extra texture sample.
Could I squeeze it into one of the color channels? I recall someone told me they had done something similar with their terrain. They discarded the blue channel for actual color, and used it and and the alpha channel to store a normal map. Blue was calculated based on the red and green channels. Since most ground textures are green or brown, very little information is lost.
I figured the same was true for vegetation, so I added support for that to the shader and model processing pipeline. I can now replace the blue channel of the diffuse texture with a monochrome specular map. Can you tell the difference?
The tree on the (highlight to read ->) right has no information in its blue channel. We calculate the blue channel based on the red and green channels and a shader constant that is determined at compile time when we analyze the texture.
The original texture is on the left. The specular map is in the middle. The texture on the right is actually what gets used. The blue channel has been replaced with the specular component.
To calculate the actual diffuse color in the shader, we just do:
float4 diffuse = tex2D(DiffuseSampler, texCoords); ... diffuse.b = dot(diffuse.rgb, BlueFromColor);
BlueFromColor is a float3, because the same shader is used for when there is no specular map stashed in the diffuse – in that case, BlueFromColor is (0, 0, 1). When we do have a specular map, the third component will be zero, and the first two will be non-zero.