先晒晒收到的Havok 活动抱枕
进入正题
本人首发于http://www.anarchy.cn/ 本人博客 http://www.dreamfairy.cn 转载请著名出处
很多人都见过 RPG Sample 中的 XRay 透视效果, 像这样
英雄在被铁链遮挡的部位会呈现透视的效果,而不是被遮挡。
这个效果需要2个Pass
即一个用来呈现被遮挡时的表现
一个用来呈现未被遮挡时的表现
首先来创建我们的ShaderLib
在PA中点击菜单 View ->Panels -> Shader Libary 打开着色器库面板。 点击创建一个 ShaderLib 名字就取名叫 TestShader。
然后左侧空白处右键 Add Effect 取名 MixColorTech , 之后在 Effect 上右键 Add Techquine 取名 MixColorEffect.
之后创建我们的2个Pass
在右侧空白处创建遮挡用Shader 取名 OCCShader, 然后再创建一个正常渲染用Shader 取名 DiffuseShader 把这2个Shader 拉到 MixColorEffect下。
最后结构如图
之后编写 Shader代码, 打开 View->Panels->Shader Code Edior. 然后在 Shader Libary 上点击Shader OCCSHader 开始编写它
顶点着色器代码如下
#include <Shaders/VisionCommon.inc> float4x4 matMV : register(c0); float4x4 matMVP : register(c8); #if defined(_VISION_GLES2) float4 FuckColor : register(c0); #else float4 FuckColor; #endif struct Test_In { float4 VectPos : POSITION; float3 Normal : NORMAL; }; struct Test_Out { float4 ProjPos : SV_POSITION; float4 COLOR : COLOR; }; Test_Out vs_main( Test_In In ) { Test_Out output; output.ProjPos = mul(matMVP, In.VectPos); float3 vNormal = normalize( mul( (float3x3)matMV, In.Normal )); float3 vVertexDir = -normalize(mul(matMV, In.VectPos).xyz); float vDir = (1.0 - dot(vNormal, vVertexDir)); output.COLOR = FuckColor; output.COLOR.a *= vDir; return output; }
然后加入了 NORMAL 语义词,让着色器编译的时候填充模型的法线信息
然后把参数 FuckColor 定义到顶点中。 实际上能提高部分性能,毕竟顶点数量是远小于像素数量的。
重点解释3行代码
float3 vNormal = normalize( mul( (float3x3)matMV, In.Normal )); //将模型法线转换到世界坐标系下,并归一化(区间 -1 ~ 1)
float3 vVertexDir = -normalize(mul(matMV, In.VectPos).xyz); //将模型顶点转换到世界坐标系下,归一化后成为顶点方向
float vDir = (1.0 – dot(vNormal, vVertexDir)); //点乘顶点和法线的向量,求出它们的夹角,然后用1.0 减去这个夹角,因为都是单位向量,因此减法后刚好可以当作 0~1.0 的透明度值用。
然后是着色器代码
[cc language=”cpp”]
#include <Shaders/VisionCommon.inc>
sampler2D BaseTexture : register(s0);
struct Test_In
{
float4 ProjPos : SV_POSITION;
float4 COLOR : COLOR;
};
float4 ps_main( Test_In In ) : SV_Target
{
return In.COLOR;
}
[/cc]
FuckColor 是一个参数,可以在PA中设置它的颜色参数。
现在对这个Shader进行属性设置,打开面板 Shader Properties
在 Shader Libary 选中 MixColorTech 然后看 属性面板里的 Effect Properties 添加一个对应的参数 FuckColor 这一步可以将PA中的参数设置和Shader进行绑定
之后是实现透视的重点了。
选中 OCCShader 然后在 Shader Properties面板中 打开 Depth and Stencil 标签 在这里进行深度和模板缓存设置。同时不写入深度,
设置下面3个属性
DepthTestEnabled : false //让需要透视的物体像素不进行深度检测
DepthWriteEnabled : false //这样位于透视物体前的物体也无法进行像素深度检测
DepthComparisionFunction : Grater //比较条件为深度大于源深度
透视的Shader搞定后,编写正常渲染的Shader
点击 DiffuseShader 然后在 Shader Code Editor 中输入代码
顶点代码
[cc language=”cpp”]
#include <Shaders/VisionCommon.inc>
float4x4 matMV : register(c0);
float4x4 matMVP : register(c8);
struct Test_In
{
float4 VectPos : POSITION;
float4 UV : TEXCOORD0;
};
struct Test_Out
{
float4 ProjPos : SV_POSITION;
float4 UV : TEXCOORD0;
};
Test_Out vs_main( Test_In In )
{
Test_Out output;
output.ProjPos = mul(matMVP, In.VectPos);
output.UV = In.UV;
return output;
}
[/cc]
像素代码
[cc language=”cpp”]
#include <Shaders/VisionCommon.inc>
sampler2D BaseTexture : register(s0);
struct Test_In
{
float4 ProjPos : SV_POSITION;
float4 UV : TEXCOORD0;
};
float4 ps_main( Test_In In ) : SV_Target
{
return vTex2D(BaseTexture, BaseTextureSampler, In.UV);
}
[/cc]
最后运行项目,会发现表现的效果和原来一样,还是白白的一片,没有XRay的感觉,这是因为混合模式设置的问题,导致透明度无效
选中OCCShader 打开 Shader Properties ,选中 Blending 标签
修改下列的属性如图
这还不够,因为我们还需要设置导入法线数据流,否则Normal默认为空,在General标签页下设置 Tracking中 StreamMask选项
设置为 VertexPosition, Normals
之后编译这个lib,在pa中将 FuckColor 设置为红色就大功告成了。
至于混合模式的知识,由于篇幅有限且到处都有文档(主要是我懒),诸位自己百度吧
直接上成品图