自言自语
根据“精要”实践billboard 虽然实际商业项目中并不这么使用billboard 但作为学习练习,自己尝试过后有所理解,但却法线一个问题。。。就是当相机以quad以Y方向进行旋转超过180度的时候,quad就会发生颠倒 具体请看效果
效果
Shader部分
Shader "TNShaderPractise/ShaderPracitise_billboard"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_VerticalScale("UpDirFix",Range(0,1.0))=1.0
}
SubShader
{
Tags { "RenderType"="Opaque" "DisableBatching"="Ture" }
Pass
{
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _VerticalScale;
v2f vert (appdata v)
{
v2f o;
//建立三个标准正交基 进行顶点方向转换 首先要有一个轴心 设定为000
float3 center = float3 (0,0,0);
//此时我们需要根据是否模型法线正对相机 要引入一个Y轴约束来进行设置 当然所有计算都放在模型空间进行计算
//第一步 转换视角方向到模型空间
float3 viewDir = mul (unity_WorldToObject,float4(_WorldSpaceCameraPos,1)) ;
//利用矢量减法原则 得到 模型面向视角方向的法线 中心点指向相机方向
float3 normalDir = viewDir - center;
//将法向量的Y分量乘以一个Y轴约束系数
normalDir.y *= _VerticalScale;
//归一化法线方向
normalDir = normalize(normalDir);
//三元运算 粗略约定Y轴方向 当Y分量=1 (由于浮点精度运算我们设置为大于0.999) 则说明normalDir 已经指向正上方 则upDir 就要指向前方 否则 upDir指向正上方,
//但是这么计算的结果是 当相机翻转180度是 其Y轴朝向也会翻转180度 并不是我想要的billboard 不知道有什么好的方法没
float3 upDir = abs(normalDir.y)>0.999?float3 (0,0,1):float3(0,1,0);
//根据叉乘原理 计算出 向右方向 左手坐标系
float3 rightDir = normalize(cross(upDir,normalDir));
//再根据左手坐标系 用叉乘算出精确的upDir
upDir = normalize(cross(normalDir,rightDir));
//之后算出顶点与轴心的偏移距离
float3 offset = v.vertex.xyz - center;
//根据偏移距离 对顶点方向进行相应分量的修正 补齐齐次坐标空间的w分量 1 因为是点, 所以有位置信息 因此分量w为 1;
float4 localpos = float4 (offset.x*rightDir+offset.y*upDir+offset.z*normalDir,1);
//将调整后的顶点转换到裁剪空间 准备输出
o.pos = UnityObjectToClipPos(localpos);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
总结
尝试用相机y方向 与 upDir 统一一致 结果还是一样。 然后直接使用乐乐女神给的原版shader也是一样的。。。 因此比较难受。。
虽然在大佬们看来应该是小问题 但我学习过程中还是要弄明白的 现在不明白就记录下来 日后回顾看能否解决