In this article, I will show how to adjust the 3D model created with Photogrammetry to cast shadows on the objects in your Scene.
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.
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.
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.
And, you can also switch whether the object receives shadows by checking the ‘Receive Shadows‘ box.
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.
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‘.
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.
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.
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.