[unity3d] 模型XRay效果实现
2017-09-17 15:37
375 查看
XRay效果常常用来显示被墙体及其它物体遮挡的物体的轮廓,效果一般如下图所示,如人物身上的蓝色部分。
算法原理:
使用两个Pass对人物进行绘制,其它第一个Pass正常对人物进行绘制,第二个pass使用半透明模式根据Z-Test绘制被遮挡的部分。引擎对不透明物体(Opaque)和半透明物体进行分开绘制,并且一定是先绘制Opaque物体,然后再绘制半透明物体,所以可以在第二Pass中根据已经绘制Opaque物体的Z值来判断物体的某一部分是否需要再次绘制,只有Z-Buffer中的值大于当前的Z值才说明该部分被遮挡。判断条件为:
ztest greater
Shader制作:
1,创建一个Surface Shader, 命名XrayEffect。
2,在XRayEffect的基础上增加一个pass, 代码如下:
3,将模型的shader替换成XRayEffect,效果如下,明显感觉到效果不对,由于在编辑器模式下该模型并未被其它物体遮挡,但是还是绘制出了Xray效果,显然这不并是我们需要的,这是由于模型自身部分的遮挡导致的。
4,为了去除上一步看到的部分,我们使用Stencil进行过滤,该Shader的第一个Pass中我们向Stencil Buffer中写入一个值254,在Xray的pass中,如果stencil的值为254,则不再绘制效果如下:
附完整Shader代码:
Shader "Custom/XRayEffect" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Stencil {
Ref 254
Comp Always
Pass Replace
ZFail Keep
}
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_CBUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_CBUFFER_END
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
pass{
Blend SrcAlpha OneMinusSrcAlpha
zwrite off
ztest greater
Stencil {
Ref 254
Comp NotEqual
Pass Keep
ZFail Keep
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
struct v2f{
float4 pos:POSITION;
};
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
return o;
}
float4 frag(v2f IN):color{
float4 col=float4(0,0,1,0.5f);
return col;
}
ENDCG
}
}
FallBack "Diffuse"
}
算法原理:
使用两个Pass对人物进行绘制,其它第一个Pass正常对人物进行绘制,第二个pass使用半透明模式根据Z-Test绘制被遮挡的部分。引擎对不透明物体(Opaque)和半透明物体进行分开绘制,并且一定是先绘制Opaque物体,然后再绘制半透明物体,所以可以在第二Pass中根据已经绘制Opaque物体的Z值来判断物体的某一部分是否需要再次绘制,只有Z-Buffer中的值大于当前的Z值才说明该部分被遮挡。判断条件为:
ztest greater
Shader制作:
1,创建一个Surface Shader, 命名XrayEffect。
2,在XRayEffect的基础上增加一个pass, 代码如下:
pass{ Blend SrcAlpha OneMinusSrcAlpha zwrite off ztest greater CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" struct v2f{ float4 pos:POSITION; }; v2f vert(appdata_base v){ v2f o; o.pos=UnityObjectToClipPos(v.vertex); return o; } float4 frag(v2f IN):color{ float4 col=float4(0,0,1,0.5f); return col; } ENDCG }
3,将模型的shader替换成XRayEffect,效果如下,明显感觉到效果不对,由于在编辑器模式下该模型并未被其它物体遮挡,但是还是绘制出了Xray效果,显然这不并是我们需要的,这是由于模型自身部分的遮挡导致的。
4,为了去除上一步看到的部分,我们使用Stencil进行过滤,该Shader的第一个Pass中我们向Stencil Buffer中写入一个值254,在Xray的pass中,如果stencil的值为254,则不再绘制效果如下:
附完整Shader代码:
Shader "Custom/XRayEffect" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Stencil {
Ref 254
Comp Always
Pass Replace
ZFail Keep
}
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_CBUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_CBUFFER_END
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
pass{
Blend SrcAlpha OneMinusSrcAlpha
zwrite off
ztest greater
Stencil {
Ref 254
Comp NotEqual
Pass Keep
ZFail Keep
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
struct v2f{
float4 pos:POSITION;
};
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
return o;
}
float4 frag(v2f IN):color{
float4 col=float4(0,0,1,0.5f);
return col;
}
ENDCG
}
}
FallBack "Diffuse"
}
相关文章推荐
- Unity3D 加载fbx模型,实现简单的方向控制
- Unity3D 游戏引擎之脚本实现模型的平移与旋转(六)
- Unity3D For iPhone游戏引擎之使用脚本实现模型平移与模型旋转(六)
- Unity3D实现闪光灯效果
- 004-Vuforia实现AR产品中模型颜色的渐变效果
- Unity3D NGUI蒙版效果实现方法
- 在Unity3D中实现条带(ribbon)效果
- 游戏模型模糊高亮边缘效果实现shader
- 怎样实现一个3D模型漂浮,上下浮动的效果
- unity3d实现一个放大缩小视角左右旋转视角的效果
- Unity3D 游戏引擎之脚本实现模型的平移与旋转(六)
- (浮动+盒模型+无序列表)实现切换图片效果
- Unity3D Shader 模型流光效果
- Unity3D 实现爆炸效果的函数
- Unity3D 实现类似“纪念碑谷”扭曲物体的效果
- [Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述
- 基于CPU的Bank BRDF经验模型,实现各向异性光照效果!
- Unity3d 一个简单的玻璃效果实现!
- [置顶] Java Web学习(33): 阶段小项目使用MVC模型实现购物车效果
- [置顶] Unity3d 实现物体一闪一闪的效果