原文链接: http://blog.csdn.net/u011047171/article/details/47255233

广告牌(Billboard)材质

Billboard概述

Billboard技术在游戏引擎中占有很重要的地位,一般用在粒子效果或者光晕效果上,让粒子面片z轴朝向摄影机。Unity里面也不例外 ,在Unity的粒子系统中的render面板的render mode中就四中billboard模式可选,这些模式都是面对摄影机的,只是轴向的约束不同;另外Unity的Terrain系统里也有Billboard技术的使用;但是如果我们使用自己做的模型或者预设,要使它朝向摄影机的话,则得自己写脚本或者写相应的shader实现,在这里将拿shadowgun里面的一个写得不错的shader(MADFINGER/Transparent/Blinking GodRays Billboarded)做例子实现billboard功能(如下图:),原来的例子中有一些与billboard无关的效果(如闪烁,根据距离渐隐等)我将它去掉了,只讲述billboard的实现。

模型在3d软件中的准备

在这个shader里面,为了获得面片的中心,将一些数据存在顶点颜色和UV2里面,在顶点颜色R通道和G通道里面存储一个单位面片(长宽为1的面片)的坐标,即四个顶点的顶点色(0,0,0),(255,0,0),(255,255,0),(0,255,0),而在UV2里面存下这个面片的长宽值(6,8),需要注意的是要保证单位为米,方便匹配unity的单位;如下图本例使用的面片:四个顶点的顶点色如下图所示,长宽为6和8,四个顶点的UV2如下图所示,记录长宽的单位6和8。

shader实现

这个shader是一个可以约束Y轴的billboard效果,因此在属性里我们需要定义一个参数,来控制轴向约束的开关:

[csharp] view plaincopy print?
  1. _VerticalBillboarding("Vertical Restraints", Range(0,1)) = 1

接下来主要工作是在vert函数里修改面片模型的顶点,进行顶点位置的计算,首先我们先获得面片中心到摄影机位置的向量;这个时候我们存在模型顶点颜色和uv2的数据就可以起作用了,下面的计算都是在object space下计算的。

[csharp] view plaincopy print?
  1. float3  centerOffs  = float3(float(0.5).xx - v.color.rg,0) * v.texcoord1.xyy;//利用事先存在模型顶点色和UV2的数据获得每个顶点相对与中心的偏移量
  2. // float3   centerOffs  = float3(float(0.5).xx - v.color.rg,0) * v.color.bbb*255;
  3. float3  centerLocal = v.vertex.xyz + centerOffs.xyz;//将顶点坐标偏移到中心位置
  4. float3  viewerLocal = mul(_World2Object,float4(_WorldSpaceCameraPos,1));//获得观察点在object space下的坐标
  5. float3  localDir    = viewerLocal - centerLocal;//获得面片中心到观察点的方向向量
  6. localDir.y =localDir.y * _VerticalBillboarding;//如果_VerticalBillboarding为0,则面片则绕y轴旋转

然后将得到的方向向量正则化,并将该方向向量作为Z轴,重构出面片中心面对视角的右手方向向量rightLocal和向上方向向量upLocal;

[csharp] view plaincopy print?
  1. float3  rightLocal;
  2. float3  upLocal;
  3. CalcOrthonormalBasis(normalize(localDir) ,rightLocal,upLocal);//localDir的正则化很重要!

这里使用了CalcOrthonormalBasis(float3 dir,out float3 right,out float3 up),该函数作用就是根据dir重构出右手方向和向上方向up;这个函数是需要自己定义的 ,原型如下:

[csharp] view plaincopy print?
  1. void CalcOrthonormalBasis(float3 dir,out float3 right,out float3 up)
  2. {
  3. up    = abs(dir.y) > 0.999f ? float3(0,0,1) : float3(0,1,0);
  4. right = normalize(cross(up,dir));
  5. up    = cross(dir,right);
  6. }

从上述原型可以看出dir,right,up是相互垂直的向量,从而构建出一个在坐标系统;在这里我们的输入时归一化后的localDir向量,因此得到一个在object space下的以localDir作为Z轴,rightLocal做X轴,upLocal做Y轴的新的坐标系,而localDir视线方向,所以rightLocal和upLocal 所构成的平面与视线垂直;最后我们根据这两个单位向量将之前偏移到面片中心的顶点坐标centerLocal重新按偏移量centerOffs偏移回去,构成一个垂直于视线的新的平面;

[csharp] view plaincopy print?
  1. float3  BBLocalPos = centerLocal - (rightLocal * centerOffs.x + upLocal * centerOffs.y);

当然这个新的平面是在object space下的,还需要转换到屏幕投影空间;

[csharp] view plaincopy print?
  1. o.pos   = mul(UNITY_MATRIX_MVP, float4(BBLocalPos,1));//w分量设为1表明float4(BBLocalPos,1)是一个顶点

VF版本代码01

[csharp] view plaincopy print?
  1. Shader "PengLu/Billboard/UnlitAddVF" {
  2. Properties {
  3. _MainTex ("Base texture", 2D) = "white" {}
  4. _VerticalBillboarding("Vertical Restraints", Range(0,1)) = 1
  5. }
  6. SubShader {
  7. Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
  8. Blend One One
  9. Cull Off Lighting Off ZWrite Off Fog { Color (0,0,0,0) }
  10. LOD 100
  11. CGINCLUDE
  12. #include "UnityCG.cginc"
  13. sampler2D _MainTex;
  14. float _VerticalBillboarding;
  15. struct v2f {
  16. float4  pos : SV_POSITION;
  17. float2  uv  : TEXCOORD0;
  18. };
  19. void CalcOrthonormalBasis(float3 dir,out float3 right,out float3 up)
  20. {
  21. up    = abs(dir.y) > 0.999f ? float3(0,0,1) : float3(0,1,0);
  22. right = normalize(cross(up,dir));
  23. up    = cross(dir,right);
  24. }
  25. v2f vert (appdata_full v)
  26. {
  27. v2f o;
  28. float3  centerOffs  = float3(float(0.5).xx - v.color.rg,0) * v.texcoord1.xyy;
  29. //float3    centerOffs  = float3(float(0.5).xx - v.color.rg,0) * v.color.bbb*256;
  30. float3  centerLocal = v.vertex.xyz + centerOffs.xyz;
  31. float3  viewerLocal = mul(_World2Object,float4(_WorldSpaceCameraPos,1));
  32. float3  localDir    = viewerLocal - centerLocal;
  33. localDir.y =localDir.y * _VerticalBillboarding;
  34. float3  rightLocal;
  35. float3  upLocal;
  36. CalcOrthonormalBasis(normalize(localDir) ,rightLocal,upLocal);
  37. float3  BBNormal   = rightLocal * v.normal.x + upLocal * v.normal.y;
  38. float3  BBLocalPos = centerLocal - (rightLocal * centerOffs.x + upLocal * centerOffs.y);
  39. o.uv    = v.texcoord.xy;
  40. o.pos   = mul(UNITY_MATRIX_MVP, float4(BBLocalPos,1));
  41. return o;
  42. }
  43. ENDCG
  44. Pass {
  45. CGPROGRAM
  46. #pragma vertex vert
  47. #pragma fragment frag
  48. #pragma fragmentoption ARB_precision_hint_fastest
  49. fixed4 frag (v2f i) : COLOR
  50. {
  51. return tex2D (_MainTex, i.uv.xy);
  52. }
  53. ENDCG
  54. }
  55. }
  56. }

VF版本代码01效果:

UnityShader实例10:广告牌(Billboard)材质相关推荐

  1. 实例10:四足机器人运动学逆解可视化与实践

    实例10: 四足机器人运动学逆解单腿可视化 实验目的 了解逆运动学的有无解.有无多解情况. 了解运动学逆解的求解. 熟悉逆运动学中求解的几何法和代数法. 熟悉单腿舵机的简单校准. 掌握可视化逆向运动学 ...

  2. 第二波:HTML+CSS+JavaScript数据可视化大屏平台模板实例10大通用模板,面向各行各业

    第二波:HTML+CSS+JavaScript数据可视化大屏平台模板实例10大通用模板,面向各行各业. HTML+CSS+JS数据可视化大屏平台模板实例11-设备监控 HTML+CSS+JS数据可视化 ...

  3. 第一波:HTML+CSS+JavaScript数据可视化大屏平台模板实例10大通用模板,面向各行各业

    HTML+CSS+JavaScript数据可视化大屏平台模板实例10大通用模板.欢迎关注: HTML+CSS+JS数据可视化大屏平台模板实例1 HTML+CSS+JS数据可视化大屏平台模板实例2-视频 ...

  4. Python实例10:文本词频统计

    Python实例10:文本词频统计 6.6.1 问题分析 在英文中文中,出现哪些词,出现多少次? 6.6.2 hamlet英文词频统计 CalHamletV1.py 6.6.3 三国演义人物出场统计 ...

  5. UnityShader实例12:屏幕特效之马赛克(Mosaic)材质

    马赛克(Mosaic)材质 概述 马赛克(Mosaic),估计是大伙平时很常见最讨厌的图片处理手段,嘿嘿,没错我说的就是"打码".好了,正经点,马赛克指现行广为使用的一种图像(视频 ...

  6. UnityShader实例08:溶解消融(Dissolve)材质

    溶解消融(Dissolve)材质 在不少3D游戏中,角色死亡后会有一个溶解消融的特效,这个除了粒子特效以外还需要shader的配合.下面就是本例实现的一个效果,当然没有例子配合看起来是搓搓的,不过效果 ...

  7. UnityShader实例05:Toon(卡通)材质

    卡通材质 卡通着色也叫Non-photorealisticrendering非真实渲染,通常一些3D游戏用来做一些卡通风格的游戏,一般来说特点主要有两点,一是描边,二是风格化着色,表现为明暗渐变过渡为 ...

  8. Unityshader实例01:冰块材质

    简单版本 效果如下 原理 使用法线贴图扭曲透明颜色贴图的uv值 Shader 代码1 Shader"PengLu/normal/iceTrans" { Properties {_C ...

  9. python爬虫实例-10个python爬虫入门实例

    昨天带伙伴萌学习python爬虫,准备了几个简单的入门实例 涉及主要知识点: web是如何交互的 requests库的get.post函数的应用 response对象的相关函数,属性 python文件 ...

最新文章

  1. 关于Nikon Ai AF 28mm F1.4D遮光罩的问题
  2. 【SpringCloud】配置中心简介及其搭建
  3. 彩票假设 (Lottery Ticket Hypothesis) 在CV、NLP和OOD领域的应用
  4. Android四大组件之——Activity的生命周期(图文详解)
  5. PHP+jquery 树状菜单
  6. idea连接sqlserver及数据库操作
  7. vue3.x 自定义事件 emits
  8. 再这样下去,团队半年内就要散了。。
  9. MYSQL数据丢失讨论
  10. 用opencv进行图像处理-之用matplotlib显示
  11. 使用KELI调试单片机代码时,一定要用Open Project的方式打开。
  12. 转载:技术大停滞——范式春梦中的地球工业文明1:文明与技术
  13. 基于大疆dij_irp.exe进行红外测温
  14. 星淘惠:现在做跨境电商还有优势吗?跨境电商发展怎么样
  15. Packet Tracer – 配置OSPF
  16. 【个人研究】21世纪西方运用脑电(EEG)的音乐研究动向分析(一)
  17. Hive的安装与配置
  18. 浙里办APP对接常见问题
  19. Web 挖掘技术总结 (参考太多,都没列出来)
  20. [JavaWeb]谁是卧底游戏制作(网络游戏)

热门文章

  1. JAVA学习脚印10:解惑java 中UTF-16与char
  2. 第2章第12节:标题设计技巧:制作漂亮的虚线描边文字 [PowerPoint精美幻灯片实战教程]
  3. CSS3扇形动画菜单 鼠标滑过扇形展开动画
  4. 纸鸢|物联网领域常见的11种网络类型
  5. windows10强制删除文件_二合一平板电脑的痛点要被解决:Windows 10开始改善触摸操作体验...
  6. 如何在公众号添加QQ链接
  7. 可爱的Python_课后习题_CDay−2 完成核心功能
  8. android 模拟器 ryzen,锐龙安卓模拟器多开:是否开启虚拟化,结果是天上地下
  9. poi java表格标题高度_如何使用java中的apache poi降低word中表行的默认高度
  10. mysql数据库插入数据显示Extracted SQL state class '22' from value '22001'解决办法