在Havok Project Anarchy 中创建透视效果

先晒晒收到的Havok 活动抱枕

h1h2

进入正题

本人首发于http://www.anarchy.cn/ 本人博客 http://www.dreamfairy.cn 转载请著名出处
很多人都见过 RPG Sample 中的 XRay 透视效果, 像这样

h3

英雄在被铁链遮挡的部位会呈现透视的效果,而不是被遮挡。

这个效果需要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下。
最后结构如图

h4

之后编写 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进行绑定h4

之后是实现透视的重点了。
选中 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 标签
修改下列的属性如图

h6

这还不够,因为我们还需要设置导入法线数据流,否则Normal默认为空,在General标签页下设置 Tracking中 StreamMask选项

h5

设置为 VertexPosition, Normals

之后编译这个lib,在pa中将 FuckColor 设置为红色就大功告成了。
至于混合模式的知识,由于篇幅有限且到处都有文档(主要是我懒),诸位自己百度吧

直接上成品图
h7

发表评论

电子邮件地址不会被公开。 必填项已用*标注