Shader for displaying self-shadow without rendering the actual object.

Hello!

I’d like to show how object is shadowed, but without rendering the actual shader.

How can this problem be approached?

thanks

Can you better explain what you want, perhaps with a reference picture or drawing?

here it is

414704--14366--$shader_example1.jpg
414704--14367--$shader_example2.jpg

Oops.
By “but without rendering the actual shader” I really meant “but without rendering the actual object”

up

I’ve found this 2.x shader in a similar topic.

Is it possible to convert it to surface shader for 3.0?

Shader "FX/Matte Shadow" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
	
}

Category {
	
	Tags {"Queue"="Geometry+500"}
	LOD 200
	Alphatest Greater 0
	ZWrite Off
	AlphaToMask True
	ColorMask RGB
	Fog { Color [_AddFog] }
	Blend DstColor Zero
	
	SubShader {
		
		Pass {	
			Tags { "LightMode" = "Pixel" }

CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"

struct v2f {
	V2F_POS_FOG;
	LIGHTING_COORDS
	float2	uv;
	float3	normal;
	float3	lightDir;
};

uniform float4 _MainTex_ST;

v2f vert (appdata_base v)
{
	v2f o;
	PositionFog( v.vertex, o.pos, o.fog );
	o.normal = v.normal;
	o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
	o.lightDir = ObjSpaceLightDir( v.vertex );
	TRANSFER_VERTEX_TO_FRAGMENT(o);
	return o;
}

uniform sampler2D _MainTex;
uniform float4 _Color;

float4 frag (v2f i) : COLOR
{
	half4 c = _Color * 4 * LIGHT_ATTENUATION(i);
	c.a = (1-LIGHT_ATTENUATION(i));
	return c;
}
ENDCG

		}
	}
}

Fallback "Transparent/Cutout/VertexLit", 2

}

I suppose this is the most important part:

half4 c = _Color * 4 * LIGHT_ATTENUATION(i);
	c.a = (1-LIGHT_ATTENUATION(i));
	return c;

but I’m not yet sure how to attempt to use LIGHT_ATTENUATION in a surface shader :slight_smile:

I’m interested in this as well.

This doesn’t work if placed against skybox (probably can be fixed).
And I think it will work only with forward rendering (because custom lighting model for deferred rendering is not specified). But what is actually important that it works :smile:.

Testing and comments are appreciated. Thanks.

Shader "MatteShadowCustModel" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
	_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}

SubShader {
	Tags {"IgnoreProjector"="True" "RenderType"="TransparentCutout"}
	LOD 200
	
CGPROGRAM
#pragma surface surf SimpleLambert alphatest:_Cutoff

sampler2D _MainTex;
float4 _Color;

struct Input {
	float2 uv_MainTex;
};

 half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
          half NdotL = dot (s.Normal, lightDir);
          half4 c;
          c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2); //half3(atten, atten, atten);//
          c.a = s.Alpha;
          return c;
      }

void surf (Input IN, inout SurfaceOutput o) {
	half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = 0.25;
	
}
ENDCG
}

Fallback "Transparent/Cutout/VertexLit"
}

Can’t you use some “Grab image pass” and then apply the computed texture in screenspace UV on your mesh ?
so the mesh won’t be visible…

http://unity3d.com/support/documentation/Components/SL-GrabPass.html

it is often use for “Predator camouflage style” effect or diffraction glass effect.
hope this can help…

Yeah, I know about GrabPass.

I am not sure how performant it is + I also need a shade on the object (not only the shadow produced by it).

(and I suppose the shader in my previous post is almost what I need)

thanks).

Nice job!
It would be great if it worked against a skybox.
Another thing, disabling the receive shadow option seems to be ignored by the shader.

Thanks for the feedback!
One more interesting thing to check is if this shader can receive a shadow cast by another object.

Yes it does receive shadows casted by other objects. However, it can’t stop receiving shadows since disabling the receive shadow option is ignored by this shader.

Also, would it be possible to have the shader render a true matte, without any shading?

However, it can’t stop receiving shadows since disabling the receive shadow option is ignored by this >shader.
I am going to add an option in shader properties for that.

Also, would it be possible to have the shader render a true matte, without any shading?
I am not sure I understand what you mean :wink:

Nevermind, my mistake :wink:

How about getting it to work against a skybox, would that be possible to add?

Here’s a bit simplified version (works the same way).

Still thinking about skybox.

Shader "MatteShadowCustModel2" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	
	_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}

SubShader {
	Tags {"IgnoreProjector"="True" "RenderType"="TransparentCutout"}
	LOD 200
	
CGPROGRAM
#pragma surface surf SimpleLambert alphatest:_Cutoff


float4 _Color;

struct Input {
	float2 uv_MainTex;
};

 half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
          
          half4 c;
          c.rgb = s.Albedo;
          c.a = 0;
          
          return c;
      }

void surf (Input IN, inout SurfaceOutput o) {
	
	o.Albedo = _Color.rgb;
	o.Alpha = 0.25;
	
}
ENDCG
}

Fallback "Transparent/Cutout/VertexLit"
}

Ok, I think it may be possible to use this shader with skybox made of an inverted cube.
I don’t know how to make it work with the standard skybox ).

I also haven’t found a way to disable receiving shadows, so this shader (from GrabPass page of the manual) can be used instead:

Shader "Shadow" {
 Properties {
  _MainTex ("Base (RGB)", 2D) = "white" {}
 }
 SubShader {
 
    Tags { "Queue" = "Transparent" }
 
   // Grab the screen behind the object into _GrabTexture, using default values
        GrabPass { }

        // Render the object with the texture generated above.
        Pass {
            SetTexture [_GrabTexture] { combine texture }
        }

 }
 FallBack "Diffuse"
}

I haven’t tested the performance of it yet.

you can have somthing like that with the grabPass and a simple shader: (cf attached file)

here is the simple code:

Shader "matShadow" {
	Properties {
        _Color ("Main Color", Color) = (1,1,1,0)
	}
		
		
    SubShader {

        // Grab the screen behind the object into _GrabTexture, using default values
        GrabPass { }

        // Render the object with the texture generated above.
        Pass {
		Material {
                Diffuse [_Color]

               }
		
	      Lighting On
	      SetTexture [_GrabTexture] {
                Combine texture * primary DOUBLE, texture * primary
              }
       }
		
    }

	FallBack "Diffuse"
}

you can enance it by limiting the effect of ligthning adding some coef to remove the “diffuse effect” keeping only the shadow darkening (but i think you must do it in cg.)

Hi there,

So right now object A is invisible, but you see its shadow being projected on object B. Nice!
But would it also be possible that if object A casts a shadow on object B, you won’t see object B itself, but only the shadow which is being cast upon it?

This link (also mentioned before in this thread) http://forum.unity3d.com/threads/14438-Matte-Shadow?highlight=matte+shadow does what I try to describe, but only for Unity 2.x

Why not just using the same shader on object B then? :face_with_spiral_eyes: