I’m experimenting with shaders and I’m currently working on a fur shader that adds fur to an object by rendering it in several passes, each time more extruded and with a lower alpha cutoff value. It’s working as intended unlit, but without lighting the visual lacks depth. There are also shimmering pixels at the tip of the fur (because you’re looking at an extruded surface at an extreme angle).
To give the fuzzy model more depth and to take your eyes away from the shimmering pixels, I want to add lighting and hopefully shadows. Problem is, it seems you must have at least 2 passes for lighting, and another 2 for shadows each time you draw the mesh.
My question is this: I’m already using 10-20 passes for unlit fur, is there any way to add lighting and shadows without an obscene number of additional passes? (not looking for hand-holding, just wondering if it’s possible and if there are any good resources)
I’m using vertex/fragment programs, a surface shader will not do.
I was working on this a fair bit recently, through surface shaders (I know, not the greatest idea). But something I would recommend doing is using the cutoff texture for occlusion per layer. This gives the right perception of depth. As for lighting and shadows, I found that cutoff was way more power intensive and worse looking than alpha fading, and so do not have shadows in my main one.
Thanks for the tip, that actually gives me a few other ideas.
Unfortunately right now I have no lighting meaning my model is completely unlit, even from ambient light, and occlusion masks only work for ambient light.
No lighting is a huge problem because you can’t see depth without it. You can’t even see the furs that are facing the camera.
This was mine (it’s actually meant to be a grass shader, but uses the same techniques as fur shading so can be used either way). I would recommend using Unity5’s ambient lighting system as a basis
But for a start, you could try using the occlusion to multiply the colour output of the fragment shader. This would also work for depth. Something else I did for my shader, is modify the texel size of the cutoff texture by a secondary “wind” texture (the clouds render from Photoshop), which makes the fur look less uniform, and allows for animation within the shader.
Good stuff! I’ll play around with some of the functionality in AutoLight.cginc, but I wish there were some better documentation on it like there is for UnityCG.cginc
EDIT: wait a minute… ShadeSH9(…) seems to be in UnityCG.cginc, but isn’t documented at all. I am so confused, I don’t know what lighting functions are available and there’s no documentation saying what these functions even do when you find them. Even when I track down the source code, it uses a whole bunch of uniforms that Unity sets automatically, so I don’t even know what those values represent. WTF
Finally got direction lights working, thanks for the help!
Now back to answer my original question: I have 20 extrusion levels. I can render the furball lit by 1 direction light using 1 “ForwardBase” pass per extrusion level. To add any more lights, I will need 1 “ForwardAdd” pass per extrusion level per light… so adding 1 light adds 20 passes. so the answer is that fur is too expensive to light in realtime forward rendering, unless you only use 1 direction light. Deferred rendering can probably get away with more lights.
I was a bit ignorant on that part. I am one of those people that only works in deferred shading (because most of my stuff relies on heavy lighting, etc). I would recommend having very cheap lighting on all but the top layer. In saying this, (I haven’t tested it) you might be able to get away with a single additive lighting pass at the end. What I’ll do (more because I’m kind of interested to see how this turns out) is convert mine to a fragment shader, and try out some stuff for forward rendering.
You’re right, but it doesn’t say much. I believe ShadeSH9 will only give you shadows out of a baked shadow map, and may not help with the non-shadow part of lighting at all. It also seems to need light probes to work.
The only documentation that really ended up helping me is the Lighting section of the built-in shader value manual page. Important detail that isn’t given there is that the light data will refer to the first direction light in the “ForwardBase” pass, and it will refer to a point or spot light in all “ForwardAdd” passes (1 pass per light). You can only have 1 direction light, but there usually isn’t a need for more anyway.