‘Unlit Cast Shadow’ Shader useful for Photogrammetry

In this article, I will show how to adjust the 3D model created with Photogrammetry to cast shadows on the objects in your Scene.

Unlitだけど影を落とすシェーダーを使ったサザエ

A turban shell with the ‘Unlit Cast Shadow’ Shader

What is Photogrammetry?

By using Photogrammetry, you can generate mesh data and texture data without Polygonal modelling or Digital Sculpting.

 

 

Images taken with a camera will be affected by sunlight or lighting unless you use a studio with professional lighting system, so you probably set an Unlit-type Shader for Material in most cases.

 

When you use Unity’s Standard Shader, it doesn’t look natural because the light shades the textures, which have already been shaded.

Standardシェーダーを使用したサザエ

A turban shell with Standard Shader

What is Unlit Shader?

Unlit Shader is ‘a Shader not affected by light’.

It’s not shaded by light and does not cast shadows on other objects, either.

Unlit/Textureシェーダーを使用したサザエ

A turban shell with the ‘Unlit/Texture’ Shader

 

It draws the set Color and Texture as they are, so, in game programming, it’s used to create UI that doesn’t need to be affected by light or produce a flat-shading appearance.

If a UI is overexposed unnaturally, apply ‘Unlit/Texture Shader‘ to it.

In addition, it is the lightest Shader as it doesn’t calculate the effect of lights at all.

Make an object cast shadow

Contrary to Unlit Shader, Unity’s Standard Shader is affected by lights.

 

When using a Shader that is affected by lights, you can toggle whether you cast shadows on other objects by turning on/off ‘Cast Shadows’ in the ‘Mesh Renderer’ component attached to the 3D model.

それぞれオンオフ切り替えることができます

You can turn on/off ‘Cast Shadows’ for each object

 

And, you can also switch whether the object receives shadows by checking the ‘Receive Shadows‘ box.

Cast ShadowsとReceive Shadowsを切り替える

Switch on/off ‘Cast Shadows’ and ‘Receive Shadows’

 

This time, the goal is ‘to cast shadows on other objects without shading the 3D model by Photogrammetry itself’, so we implement ‘Unlit CastShadow Shader’, which is an Unlit-type Shader with the ‘Cast Shadow’ function.

Unlit Cast Shadowシェーダーを適用した状態

How it looks with the ‘Unlit Cast Shadow’ Shader

Program code for the ‘Unlit Cast Shadow’ Shader

The program code for the ‘Unlit Cast Shadow’ Shader is shown below.

Shader "Custom/Unlit/CastShadow" 
{
	Properties 
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	
	SubShader 
	{
		Tags {"RenderType"="Opaque" }
		LOD 100
		
		// Pass to render object without lighting and shading
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
		
		// Pass to render object as a shadow caster
		Pass 
		{
			Name "CastShadow"
			Tags { "LightMode" = "ShadowCaster" }
	
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_shadowcaster
			#include "UnityCG.cginc"
	
			struct v2f 
			{ 
				V2F_SHADOW_CASTER;
			};
	
			v2f vert( appdata_base v )
			{
				v2f o;
				TRANSFER_SHADOW_CASTER(o)
				return o;
			}
	
			float4 frag( v2f i ) : COLOR
			{
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG
		}
	}
}

Create a new Shader file

In the Project window, create a new Shader file by selecting ‘Create > Shader > Unlit Shader‘.

シェーダーファイルに「UnlitCastShadow」とつけます

Rename the Shader file ‘UnlitCastShadow’

Add the Pass for CastShadow

Initially, the created Unlit Shader is implemented as a ‘1Pass’ Shader.

Add a Pass for ‘CastShadow’ to make the Shader into a ‘2Pass’ Shader.

	// Pass to render object as a shadow caster
		Pass 
		{
			Name "CastShadow"
			Tags { "LightMode" = "ShadowCaster" }
	
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_shadowcaster
			#include "UnityCG.cginc"
	
			struct v2f 
			{ 
				V2F_SHADOW_CASTER;
			};
	
			v2f vert( appdata_base v )
			{
				v2f o;
				TRANSFER_SHADOW_CASTER(o)
				return o;
			}
	
			float4 frag( v2f i ) : COLOR
			{
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG
		}

 

Now, I explain each code.

Set LightMode to ShadowCaster to render the object onto the shadow map.

Tags { "LightMode" = "ShadowCaster" }

 

By using Macro available in Unity, you can cast shadows on objects without programming for lightings or shadows from scratch.

Macros are pre-defined values and expressions, which will be replaced with the relevant codes when compiling.

This time, we use the Macros (expressions) prepared already.

  • V2F_SHADOW_CASTER
  • TRANSFER_SHADOW_CASTER(o)
  • SHADOW_CASTER_FRAGMENT(i)
struct v2f 
{ 
	V2F_SHADOW_CASTER;
};
	
v2f vert( appdata_base v )
{
	v2f o;
	TRANSFER_SHADOW_CASTER(o)
	return o;
}
	
float4 frag( v2f i ) : COLOR
{
	SHADOW_CASTER_FRAGMENT(i)
}

 

Please note that the Shader with multiple ‘Pass’ is called ‘Multi-pass Shader‘ and it impacts on the performance, for example, disabling Draw Call Batching. So code shaders as ‘1Pass’ whenever possible.

Draw Call Batching – Unity – Manual

Apply the ‘Unlit Cast Shadow’ Shader to 3D model data

Apply the ‘Unlit Cast Shadow’ Shader to the ‘turban shell’ 3D model generated by Photogrammetry.

By using the ‘Unlit Cast Shadow’ Shader, you can make it cast shadows on other objects, keeping Unlit-like appearance. So the object blends in with the VR space more.

 

Unlit Cast Shadowシェーダーを使用したサザエ

A turban shell with the ‘Unlit Cast Shadow’ Shader

 

If the shadows were not adjusted properly, the overall appearance could look like a 3D game in its early days or a low-quality made-up image. 

Unlit Cast Shadowシェーダーを使用しない合成画像のようなサザエ

If the ‘Unlit Cast Shadow’ Shader is not applied, a turban shell looks like a ‘made-up’ image.

Upload to STYLY

By uploading the object with the Material generated by a custom Shader, you can use it in STYLY’s Scene.

Read the following article to learn more about how to upload the 3D model by Photogrammetry that has the Material generated by the ‘Unlit Cast Shadow’ Shader.

 

 

By understanding the characteristics of Shaders, you can appropriately make an object cast shadows so that you enhance its presence. So, it is important to adjust the lightings.