how to make a shader that only shows the shadow while the rest becomes completly transparent?

Hi Everyone,

I would like to build a material that only catch shadows, for 3dsmax users this refers to the matte/shadow material.

Basically, the material is plain transparent and simply catch shadows. It might be already feasible, but I lack of experience with writing shaders...

Also, if that could work with projectors, that would be great :)

Thanks for your help,


I think this is what you want?

I know this is a necro thread and people may well flame me for replying, but I was never able to find an answer to this question anywhere else in the forum. My guess is that I’m not alone. So I wanted to link to an article that gives the full listing for a shader that will do exactly this. It also supports bump, specular, and gloss maps, opacity maps and thresholds for hair, or any other purposes that require tapering toward transparency: Dawn of the Fel: Its All Hollywoods Fault . To make something fully transparent but still cast shadows, just set _Color’s Alpha channel value to 0.

A good portion of the reason I wanted to post this is because one of the prior answers was fairly snarky in its assertion that this couldn’t be done. It was also incorrect. (FWIW, being snarky when someone asks an honest question never seems warranted to me.)

This thing works in the viewport for me- it lacks something like clearing in game mode. I don’t know how to fix it.

    Shader "UnlitShadows/ShadowCatcher" {
    Properties{ _Color("Main Color", Color) = (1,1,1,1) _MainTex("Base (RGB)", 2D) = "white" {}	_Cutoff("Cutout", Range(0,1)) = 0.5 }
    SubShader{ Pass{ Alphatest Greater[_Cutoff] SetTexture[_MainTex] }	Pass{ Blend DstColor Zero Tags{ "LightMode" = "ForwardBase" }
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"
    #pragma multi_compile_fwdbase
    #include "AutoLight.cginc"
    struct v2f {
    float4 pos : SV_POSITION; LIGHTING_COORDS(0,1) };
    v2f vert(appdata_base v) {
    v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); TRANSFER_VERTEX_TO_FRAGMENT(o);
    return o; }
    fixed4 frag(v2f i) : COLOR{
    float attenuation = LIGHT_ATTENUATION(i);
    return attenuation;
    } ENDCG } } Fallback "Transparent/Cutout/VertexLit" }

FYI, if you have a standard MeshRenderer or SkinnedMeshRenderer you can set the Lighting->Cast Shadows drop-down to “Shadows Only” and it will render only the shadows of that mesh and not draw the color.

After (properly this time) reading your answer, I can tell you this:

What is a shadow in Unity? It's an area on an object where light don't shine because it's hidden from it by another object (that's true in real life as well actually).

In other words: a shadow, on a rendered 3D object, is a bunch of pixels where the influence (lighting calculation) of a light is removed, leaving only the ambient lighting (that colour you set in Render Settings).


Wait. What does that mean for an object that is invisible? There's no light calculation in the first place! Hey, there's not even any ambient lighting at all! How could an invisible object possibly receive and display any kind of shadow at all?

Impossible. Apparently.

It's technically possible though, as one would only have to consider 'OK so, this object's shader doesn't render anything, but where shadows would be if it was visible, I'm gonna use it's base colour/texture and multiply that with the ambient lighting colour and it's gonna be the shadow. I'll also add a transparency factor 'cause it'll be fun to play with that.'

That's how one would do it... if it was possible. Unfortunately shadows calculations are done behind-the-scenes in Unity and an End-User like you or me can't access these in order to play a bit with them.

So, I'd say this is impossible. I'd like to be wrong though.