公司动态

【unity shader】误打误撞做出来了一个简单全息投影shader。。。

📅 2026/9/2 13:31:31
【unity shader】误打误撞做出来了一个简单全息投影shader。。。
(提示:只看代码请跳过这里)情况是这样的。。。在学习一位大佬的全息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{ZWriteonColorMask0}Pass{ZWrite off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM#pragmavertex vert#pragmafragment frag#include"UnityCG.cginc"structa2v{float4vertex:POSITION;float3normal:NORMAL;float2uv:TEXCOORD0;};structv2f{float2uv:TEXCOORD0;float3worldPos:TEXCOORD1;float3worldNormal:TEXCOORD2;float4vertex: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;//顶点着色器部分没什么新鲜事v2fvert(a2vv){v2fo;o.vertex=UnityObjectToClipPos(v.