http://dev.arinchina.com/unity3dwz/ar6298/6298/
在 AR 制作过程中,添加阴影及浮现能够增强 AR 的效果。
从网上学习了这两种效果的实现方法并分享给大家。
添加阴影
在 Unity 中我们通常给物体添加阴影来增加真实感。
但是我们直接这么做的话会在画面中也看到一个白色的平面。所以我们需要一个透明的平面,但能够接收阴影。为了达到这个目的,我们需要一个自定义的着色器。--- Shader "FX/Matte Shadow"
Shader "FX/Matte Shadow" { 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 {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"} LOD 200 Blend Zero SrcColor CGPROGRAM #pragma surface surf ShadowOnly alphatest:_Cutoff fixed4 _Color; struct Input { float2 uv_MainTex;}; inline fixed4 LightingShadowOnly (SurfaceOutput s, fixed3 lightDir, fixed atten){ fixed4 c; c.rgb = s.Albedo*atten; c.a = s.Alpha; return c;} void surf (Input IN, inout SurfaceOutput o) { fixed4 c = _Color; o.Albedo = c.rgb; o.Alpha = 1; } ENDCG } Fallback "Transparent/Cutout/VertexLit" }
Shader "FX/Matte Shadow" {
//语法: Shader "名字" {[Properties] Subshaders [Fallback]} []--可选项目
// Properties Shader可以有多个属性(properties),每一个属性都显示在Unity的inspector. 如颜色,贴图,或者任意值
Properties {
//Color Color Color-value 在顶点光照打开时,选用的顶点颜色
_Color ("Main Color", Color) = (1,1,1,1)
//即使用名叫red的材质,如果有其他也可叫其名字
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
//中断值(cutoff value) 做透明效果
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
/*
Subshaders & Fallback
每个shader包含多个子shader, 至少包含有一个。当加载shader时,
Unity会遍历所有子shader.从上往下选择第一个可以支持的。 如果没有可以支持的, Unity会试着用Fallback shader.
*/
SubShader {
/*
SubShader { [Tags] [CommonState] Passdef [Passdef ...] }
一个SubShader可以定义一组渲染通道,可选设置共同状态针对所有通道,也可以指定标签
当Unity确实使用那个SubShader时,
它会用该Subshader每个通道一一给对象进行渲染,每一次渲染是一个比较昂贵的操作。尽可能的少用通道。
打开Alpha测试。
加入IgnoreProjector标签来忽略投影机的作用
"Transparent":绝大部分透明的物体、包括粒子特效都使用这个;
LOD 200,200是个代号,设成此的目的就是限制shader级别只到200为止,高过200的不采用,即使显卡支持,也不会使用高过200的shader级别的渲染方式
// Blend mode values
我们选择混合的选项的过程是通过以下面的等式来进行RGBA颜色的计算的:
float4 result = SrcFactor * fragment_output + DstFactor * pixel_color;
*/
Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
LOD 200
Blend Zero SrcColor
/*
1.CG代码必须用
CGPROGRAM
。。。
ENDCG括起来
*/
CGPROGRAM
#pragma surface surf ShadowOnly alphatest:_Cutoff
fixed4 _Color;
struct Input {
float2 uv_MainTex;
};
inline fixed4 LightingShadowOnly (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
fixed4 c;
c.rgb = s.Albedo*atten;
c.a = s.Alpha;
return c;
}
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = _Color;
o.Albedo = c.rgb;
o.Alpha = 1;
}
ENDCG
}
Fallback "Transparent/Cutout/VertexLit"
}
使用 Matte Shadow 制作材质球,再将它拖拽到我们的平面上,就得到了我们期望的效果。注意如果没看到阴影的话,很可能是 Scale 或者 Project Quality 设置的问题。
从识别对象中浮现
要实现这个效果,我们需要使用 Depth Shader。原理是我们将使用一个透明但看不到内部的盒子将低于物料的物体隐藏起来。
在透明盒子上加上 DepthMask.shader,将 SetRenderQueue.cs 加在需要影藏的物体上。最终我们获得视频中的效果。