I’m gonna assume that this beyond what a single shader can do, but I figured I’d post here anyways.
I’ve been studying the foliage in The Witness and trying to figure out how to recreate the effect in Unity (if at all).
Here’s a screenshot of The Witness if you haven’t seen it before.
If you haven’t played it, the game appears to use a mix of baked and realtime lighting. The direct sunlight casts a shadow, but things like GI appear to be baked.
The foliage has a very “soft” feel to it. Obviously the solid colors and low contrast in the leaf textures are a big part of it, but there’s a lot more to it.
Ignoring the leaf textures, the tree leaves have the following qualities:
Leaf normals are not flat (search: normal thief)
Are affected by both realtime direct sunlight and baked GI
Cast realtime shadows
Contribute to global illumination (see wall near pink tree)
Use soft-edge cutout it seems (not possible in Deferred IIRC)
Leaf polygons fade out the more parallel the camera is with them
Subtle vertex animations to simulate light wind blowing
Here’s what I’ve got, using the Standard (Specular) shader and a simple bush model with corrected normals:
Not bad for my first foliage asset, if I do say so myself.
It works like a charm, until you want to make it static:
It’s using custom lightmap properties to allow GI to pass through, but that doesn’t seem to be helping too much on the bush itself.
I’m not really sure what to do about the dark shadows on the bush itself, but I have some ideas:
When light hits a polygon, instead of blocking all light, allow a bit to pass through
Increase the bounced light intensity on the bush objects only
Pretty sure the above two ideas are impossible.
I would love to hear your guys’ thoughts on how to approach this.
You probably don’t want actual shadows on it. And fading out the parallel facing triangles will also help a lot.
To improve things, it might be enough to just change the normals as if the object was actually a sphere. And removing shadows and adding fading.
For standard shadows, you can’t let a bit pass through. You could use fake self-shadowing that you blend based on the distance the light has to travel through the tree.
The Witness uses alpha to coverage (AlphaToMask in Unity) for it’s trees, grass, and bushes. To use it requires MSAA to be enabled, which means you can’t be using Unity’s deferred or HDR rendering. Alpha to coverage allows for properly depth sorted transparency by abusing MSAA coverage samples, effectively doing alpha test dithering on a sub pixel level. In more simple terms with 4x MSAA you get 4 levels of depth sorted transparency.
For Unity you’ll probably just want to stick to cutout like you’re doing.
Would you mind elaborating on this? Also another Idea I got for the self-shadowing is to use light wrapping in combination with light probes (and just keep the bush not static). Then I could use an invisible static tree for the baked shadow casting.
EDIT: Slight update to code
Here’s the progress I’ve made on the polygon fade:
It’s almost where I want, with the only problem being that the alpha of each polygon doesn’t stack onto the alpha of the polygons behind it. Below is the shader code:
Cutoff and blend are essentially mutually exclusive. You can “fake it” with a two pass shader where you render once with alpha test and again with blend enabled. Here’s a shader I original wrote for another thread that shows this off.