(提示:只看代码请跳过这里)
情况是这样的。。。在学习一位大佬的全息shader时出了意外
大佬文章链接,作者:晨蓝fk
就算是将代码全部复制过来,也无法复原大佬原文图里的效果。
查了一下资料,可能是因为没有对ComputeScreenPos()函数返回值的结果做齐次除法运算?(该函数返回的结果是屏幕空间下顶点的齐次坐标,需要除以w分量或用tex2Dproj函数来采样纹理)
尝试的结果要么扫描线不动要么扫描线移动方式很奇怪(如图)
因为扫描线的原理主要依靠采样纹理后的结果做一次片元剔除,再加上没有原博主的纹理图我无法确定原文的纹理采样结果,就会剔除掉不应该剔除的片元。
同时,扫描线的流向和粗细也不好控制,以飞机模型为例,虽然都是y轴上从低到高,但从头看和从飞机顶上向下看扫描线流向是不一样的(因为原文是计算模型顶点在屏幕空间的位置,流向会随着视角的改变而发生改变,尽管代码上都是uv.y值升高)
就这样改了半天,最后发觉直接放弃在屏幕空间计算顶点的思路,改用模型UV来实现的效果。。。居然还可以?
正文开始
OK,将思路改为用模型UV采样动画纹理
上代码!
Shader "Unlit/HolographicShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_LightTex ("全息贴图",2D) = "white"{
}
_NoiseTex ("噪音贴图",2D) = "white"{
}
[HDR]_Color ("主颜色",Color) = (1,1,1,1)
[HDR]_RimColor ("边缘光",Color) = (1,1,1,1)
_Alpha ("透明度",Range(0,1)) = 0
_Speed ("扫描线速度",Range(0,15)) = 1
_RandomSpeed("闪一闪的速度",float) = 1
_CutOut ("阙值",Range(0,1.1)) = 0.1
}
SubShader
{
Tags {
"RenderType"="Transparent" "Queue" = "Transparent" "IgnoreProjector" = "true"}
//这个Pass只负责深度写入,看过冯乐乐的《入门精要》就明白
//如果没有单独的深度写入就会让渲染出来的模型顶点前后顺序出错
Pass
{
ZWrite on
ColorMask 0
}
Pass
{
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _LightTex;
float4 _LightTex_ST;
sampler2D _NoiseTex;
float4 _NoiseTex_ST;
fixed4 _Color;
fixed4 _RimColor;
half _Alpha;
half _Speed;
half _RandomSpeed;
half _CutOut;
//顶点着色器部分没什么新鲜事
v2f vert (a2v