IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【unity shader】误打误撞做出来了一个简单全息shader。。。 -> 正文阅读

[游戏开发]【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
		{
			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 v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.worldNormal = UnityObjectToWorldNormal(v.vertex);
				o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				//计算边缘光,如果不需要边缘光可省略这一段
				float3 normalDir = normalize(i.worldNormal);
				float3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));				
				float3 rimLight = 1.0 - saturate(dot(normalDir,viewDir));
				rimLight *= _RimColor;

				//关键部分,实现全息扫描线效果
				float2 scrPos = TRANSFORM_TEX(i.uv.xy,_LightTex);
                scrPos.y += _Time.w * _Speed;
				float4 scrcol = tex2D(_LightTex,scrPos);
				clip(scrcol - _CutOut);

				//用噪音贴图模拟全息数据传输不稳定效果
				float speed = _RandomSpeed * _Time.y;
				float Random = tex2D(_NoiseTex,float2(speed,speed));

				//没什么好说的,注意Alpha通道
				float4 maincol = tex2D(_MainTex,i.uv);
				return fixed4(maincol.rgb * scrcol + _Color + rimLight,_Alpha * Random);
            }
            ENDCG
        }
    }
}

动画纹理
使用的动画纹理
在这里插入图片描述
使用的噪音纹理

演示出来的最终效果:
在这里插入图片描述
无边缘光

在这里插入图片描述
有边缘光

结个尾

这个方案优点是简单易理解。但缺点嘛。。。
受模型UV的影响,你会发现扫描线不是完全按照整个机身扫描下去。。
如图,驾驶舱的扫描线就是横着扫过去的,机身是竖着扫的。
如果要解决,一个思路就是上文大佬的屏幕空间计算方案,可以让整个模型扫描线顺畅。。。但问题又绕回去了。

那么就先写到这,等路过的大佬看看我

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-07-05 20:29:10  更:2021-07-05 20:29:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 20:13:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计