菜鸡shader:L13 渐隐渐显的UV动画

文章目录

  • SD部分
  • Shader代码部分

呃呃,这是目前我学习庄懂AP01课程的最后一节了,我看了一下21集之后的内容是关于LightingMap,目前感觉还用不到,加上之前参与过一个项目里面也有用到LightingMap,也算了解过,就暂时先放到待办列表里。

下面也是简单记录一下课上的东西,其实整节课似懂非懂,感觉难度很大,也很能体会到老师的清晰逻辑,感叹一下,以后能成为这样的大神吗。这节课内容更多是简单记录,有些地方我也不是很懂,下面就直接开始吧。

SD部分

SD部分我就没有跟,因为打算后面再找门网课系统地学习一下。
在这里插入图片描述

  • 模型需要顶点色,因为底座不需要变化,所以顶点色全为黑,变化的是底座上面地部分,所以全为白。
  • 还需要两张UV,第一张UV用来普通地采样主纹理、法线、高光和自发光等的贴图。而第二章UV则是为后续的特效做准备。
    在这里插入图片描述
    在这里插入图片描述
  • 制作UV网格图,这部分就是将模型导入sd里,然后进行烘培,获得UV网格图。
    在这里插入图片描述

并且要在SD里获得两张图:

  • _EffMap01。这张用来存储网格、面随机灰度以及面上坡度(面上的灰度渐变)。
    在这里插入图片描述

  • _EffMap02。这张用来存储噪声,后面的特效需要用到。
    在这里插入图片描述

  • 为什么不把这个灰度塞到上面红绿图的A通道里呢?
    涉及到优化问题,RGB与RGBA的图片,这两种图在Unity里压缩的尺寸不是多1/4,而是多了一倍。所以一张图能不加alpha就不加alpha,看起来多了一个通道,其实内存占用多了很多。

Shader代码部分

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Shader "shader forge/L21_OldSchoolPlusWithMeshAnim"
{
    Properties
    {
        [Header(Texture)]
        _MainTex ("Main Tex   RGB:Base Color  A:EnvMask", 2D) = "white" {}        
        _normal ("normal", 2D) = "bump" {}
        _SpecTex ("Spec Tex   RGB:Spec Color  A:Spec Pow", 2D) = "white" {}
        _EmittTex ("Emitt Tex   RGB:Env Tex", 2D) = "black" {}
        _cubemap ("cubemap", Cube) = "_Skybox" {}
       
        [Header(Diffuse)]
        _MainCol ("Main Color", Color) = (0.5,0.5,0.5,1.0)
        _EnvDiffInt ("Env Diff Int", Range(0, 1)) = 0.2
        _E_Lambert_UpColor ("E_Lambert_UpColor", Color) = (0.8679245,0.5444998,0.5444998,1)
        _E_Lambert_DownColor ("E_Lambert_DownColor", Color) = (0.4400143,0.6626909,0.9056604,1)
        _E_Lambert_MidColor ("E_Lambert_MidColor", Color) = (0.4800081,0.8962264,0.4016109,1)

        [Header(Specular)]
[PowerSlider(2)]        _SpecPow ("Spec Pow", Range(1, 90)) = 30        
        _EnvSpecInt ("Env_SpecInt", Range(0, 5)) = 0.7826087
        _fresnel_exp ("fresnel_exp", Range(0, 90)) = 0.6956522
        _mipmap_level ("Env Mipmap", Range(0, 7)) = 0

        [Header(Emission)]
        _EmittInt ("Emitt Int", Range(1,10)) = 1

        [Header(Clock)]
        _EffMap01 ("Effect Tex1", 2D) = "gray" {}
        _EffMap02 ("Effect Tex2", 2D) = "gray" {}
        _EffCol ("Effect Color", color) = (0.0,0.0,0.0,0.0)
        _EffParams ("Wave Prop  X:Int  Y:Speed  Z:ChaosInt  W:FadeInt", vector) = (0.03,3.0,0.3,2.5)
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent"
            "RenderType"="Transparent" 
        }
        LOD 100

        Pass
        {
            Name "FORWARD"
            Tags{
                "LightMode" = "ForwardBase"
            }
            Blend One OneMinusSrcAlpha      //AB

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
             #include "AutoLight.cginc"
            #include "Lighting.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
                float2 uv1 : TEXCOORD1;         //特效网格UV信息
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float4 color : COLOR;               //顶点色信息
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                float4 pos : SV_POSITION;
                float4 posWorld : TEXCOORD2;
                float3 nDirWS : TEXCOORD3;
                float3 tDirWS : TEXCOORD4;
                float3 biDirWS : TEXCOORD5;
                float4 effectMask : TEXCOORD6;
                LIGHTING_COORDS(7,8)            //投影相关
            };

            //Texture
            uniform sampler2D _MainTex;            
            uniform sampler2D _normal;
            uniform sampler2D _SpecTex;
            uniform sampler2D _EmittTex;
            uniform samplerCUBE _cubemap;           
            //Diffuse
            uniform float3 _MainCol;
            uniform float _EnvDiffInt;
            uniform float3 _E_Lambert_UpColor;
            uniform float3 _E_Lambert_DownColor;
            uniform float3 _E_Lambert_MidColor;
            //Specular
            uniform float _SpecPow;            
            uniform float _EnvSpecInt;            
            uniform float _fresnel_exp;
            uniform float _mipmap_level;
            //Emitt
            uniform float _EmittInt;
            //Effect
            uniform sampler2D _EffMap01;
            uniform sampler2D _EffMap02;
            uniform float3 _EffCol;
            uniform float4 _EffParams;

            #define TWO_PI 3.1415926*2
            //动画方法 inout顶点信息 返回effect相关遮罩
            float4 CyberpunkAnim(float noise, float mask, float3 normal, inout float3 vertex){
            //生成锯齿波Mask
                float baseMask = abs(frac(vertex.y * _EffParams.x - _Time.x * _EffParams.y) - 0.5) *2.0; 
                //float baseMask1 = abs(frac(vertex.y) - 0.5) * 2.0;
                //让白色的时间更多,黑色的时间更少
                baseMask = min(1.0, baseMask * 2.0);
                //用Noise偏移锯齿波,noise的取值范围为0到1,减去0.5使其有正有负
                baseMask += (noise - 0.5) * _EffParams.z;
                //smoothstep算出各级Mask
                float4 effectMask = float4(0.0,0.0,0.0,0.0);
                effectMask.x = smoothstep(0.0,0.9,baseMask);
                effectMask.y = smoothstep(0.2,0.7,baseMask);
                effectMask.z = smoothstep(0.4,0.5,baseMask);
                //将顶点色遮罩存入effectMask
                effectMask.w = mask;
                //计算顶点动画
                vertex.xz += normal.xz * (1.0 - effectMask.x) * _EffParams.w * mask;
                //返回effectMask
                return effectMask;
                //return float4(baseMask1,baseMask1,baseMask1,1.0);
            }

            v2f vert (appdata v)
            {
                //采样纹理
                float noise = tex2Dlod(_EffMap02, float4(v.uv1, 0.0, 0.0)).r;
                //float noise = tex2Dlod(_EffMap02,v.uv1).r;
                v2f o;
                o.effectMask = CyberpunkAnim(noise, v.color.r, v.normal.xyz, v.vertex.xyz);
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv0 = v.uv0;
                o.uv1 = v.uv1;
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                o.nDirWS = UnityObjectToWorldNormal(v.normal);
                o.tDirWS = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0.0)).xyz);
                o.biDirWS = normalize(cross(o.nDirWS,o.tDirWS) * v.tangent.w);
                TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //贴图采样
                float3 nDirTS = UnpackNormal(tex2D(_normal,i.uv0)).rgb;

                //向量准备
                float3x3 TBN_Matrix = float3x3(i.tDirWS,i.biDirWS,i.nDirWS);
                float3 nDirWS_FT = normalize(mul(nDirTS, TBN_Matrix));
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 lrDirWS = normalize(reflect(-lightDir, nDirWS_FT));
                float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float3 halfDir = normalize(lightDir + viewDir);
                float3 vrDir = normalize(reflect(-viewDir,nDirWS_FT));

                //准备点积结果
                float NoL = max(0.0,dot(lightDir,nDirWS_FT));
                float NoH = max(0.0,dot(nDirWS_FT,halfDir));
                float NoV = max(0.0,dot(nDirWS_FT,viewDir));
                float VoR = max(0.0,dot(viewDir, lrDirWS));

                //采样纹理
                float4 var_MainTex = tex2D(_MainTex,i.uv0);
                float4 var_SpecTex = tex2D(_SpecTex,i.uv0);
                float3 var_EmitTex = tex2D(_EmittTex,i.uv0);

                //光照模型(直接光照部分)
                float3 baseCol = var_MainTex.rgb * _MainCol;
                float lambert = max(0.0,NoL);
                float specCol = var_SpecTex.rgb;
                float specPow = lerp(1, _SpecPow,var_SpecTex.a);
                float phong = pow(max(0.0, lrDirWS), specPow);
                float shadow = LIGHT_ATTENUATION(i);
                float3 dirLighting = (baseCol * lambert + specCol * phong) * _LightColor0 * shadow;

                //光照模型(环境光照部分)

                //使用3Col环境色方法
                /*下面是环境光的漫反射部分,也就是三色环境光*/
                //上层光
                float upNor = clamp(nDirWS_FT.g,0.0,1.0);
                float3 upColor = upNor * _E_Lambert_UpColor;
                //下层光
                float downNor = clamp(nDirWS_FT.g * -1,0.0,1.0);
                float3 downColor = downNor * _E_Lambert_DownColor;
                //中层光
                float midNor = clamp(1 - upNor - downNor,0.0,1.0);
                float3 midColor = midNor * _E_Lambert_MidColor;
                /*环境光的漫反射部分  三色环境光*/
                float3 env_diff_all = clamp(upColor + downColor + midColor,0.0,1.0);

                /*下面是环境镜面反射光部分*/
                //cubemap
                float3 cubemap_Dir = vrDir;
                float3 cubemap_color = texCUBElod(_cubemap,float4(cubemap_Dir,_mipmap_level));

                //fresnel
                float OneMinusNoV = 1 - NoV;
                float fresnel = pow(OneMinusNoV,_fresnel_exp);

                float occlusion = var_MainTex.a;
                float3 envLighting = (baseCol * env_diff_all * _EnvDiffInt + cubemap_color * fresnel * _EnvSpecInt * var_SpecTex.a) * occlusion;

                //光照模型(自发光部分)
                float3 emission = var_EmitTex * _EmittInt * (sin(_Time.z) * 0.5 + 0.5);

                //特效部分
                //采样EffMap01
                float3 _EffMap01_var = tex2D(_EffMap01,i.uv1).xyz;
                float meshMask = _EffMap01_var.x;               //网格遮罩
                float faceRandomMask = _EffMap01_var.y;   //面上的随即灰度遮罩
                float faceSlopeMask = _EffMap01_var.z;        //面上的坡度(灰度渐变)遮罩
                //获取EffectMask
                float smallMask = i.effectMask.x;
                float midMask = i.effectMask.y;
                float bigMask = i.effectMask.z;
                float baseMask = i.effectMask.w;
                //计算Opacity
                float midOpacity = saturate(floor(min(faceRandomMask, 0.999999) + midMask));
                float bigOpacity = saturate(floor(min(faceSlopeMask, 0.999999) + midMask));
                float opacity = lerp(1.0, min(bigOpacity, midOpacity), baseMask);
                //叠加自发光
                float meshEmitInt = (bigMask - smallMask) * meshMask;
                meshEmitInt = meshEmitInt * meshEmitInt;
                emission += _EffCol * meshEmitInt * baseMask;

                ///返回结果
                float3 finalRGB = dirLighting + envLighting + emission;
                return float4(finalRGB * opacity, opacity);              
                //return bigOpacity;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/50253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习】【Image Inpainting】Generative Image Inpainting with Contextual Attention

Generative Image Inpainting with Contextual Attention DeepFillv1 (CVPR’2018) 论文:https://arxiv.org/abs/1801.07892 论文代码:https://github.com/JiahuiYu/generative_inpainting 论文摘录 文章目录 效果一览摘要介绍论文贡献相关工作Image…

Unity XML1——XML基本语法

一、XML 概述 ​ 全称:可拓展标记语言(EXtensible Markup Language) ​ XML 是国际通用的,它是被设计来用于传输和存储数据的一种文本特殊格式,文件后缀一般为 .xml ​ 我们在游戏中可以把游戏数据按照 XML 的格式标…

23款奔驰GLS450加装原厂香氛负离子系统,清香宜人,久闻不腻

奔驰原厂香氛合理性可通过车内空气调节组件营造芳香四溢的怡人氛围。通过更换手套箱内香氛喷雾发生器所用的香水瓶,可轻松选择其他香氛。香氛的浓度和持续时间可调。淡雅的香氛缓缓喷出,并且在关闭后能够立刻散去。车内气味不会永久改变,香氛…

maven编译报错

参考链接:mvn打包No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK_51CTO博客_mvn打包命令 在执行 yum install -y java-1.8.0-opensdk命令后,使用maven去编译打包,结果报错, …

STM32MP157驱动开发——按键驱动(工作队列)

文章目录 “工作队列”机制:内核函数work_struct 结构体定义 work使用 work :schedule_workworkqueue 其他函数 工作队列方式的按键驱动程序(stm32mp157)编程思路button_test.cgpio_key_drv.cMakefile修改设备树文件编译测试 “工作队列”机制&#xff1…

找不到vcruntime140.dll无法继续执行代码怎么办?(详解)

1.vcruntime140.dll是什么?有什么作用? vcruntime140.dll是Windows操作系统中的一个动态链接库文件,它属于Microsoft Visual C Redistributable的一部分。DLL是Dynamic Link Library的缩写,它包含了一系列函数和资源,…

Linux 系列 常见 快捷键总结

强制停止 Ctrl C 退出程序、退出登录 Ctrl D 等价 exit 查看历史命令 history !命令前缀,自动匹配上一个命令 (历史命令中:从最新——》最老 搜索) ctrl r 输入内去历史命令中检索 # 回车键可以直接执行 ctrl a 跳到命令开头 …

【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?

文章目录 前言声明和初始化扩容时机源码分析go1.17go1.18内存对齐 总结 前言 在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice)。 切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装…

springboot+mybatis-plus+vue+element+vant2实现短视频网站,模拟西瓜视频移动端

目录 一、前言 二、管理后台 1.登录 2.登录成功,进入欢迎页 ​编辑 3.视频分类管理 4. 视频标签管理 5.视频管理 6.评论管理 ​编辑 7.用户管理 8.字典管理 (类似于后端的枚举) 9.参数管理(富文本录入) 10.管…

第12章 Linux 实操篇-Linux磁盘分区、挂载

12.1 Linux 分区 12.1.1 原理介绍 (1) Linux来说无论有几个分区,分给哪一目录使用,它归根结底就只有一个根目录,一个独立且唯一的文件结构, Linux中每个分区都是用来组成整个文件系统的一部分。 (2) Linux采用了一种叫“载入”的处理方法,…

LeetCode 75 第十三题(1679)K和数对的最大数目

题目: 示例: 分析: 给一个数组,两个和为K的数为一组,问能凑成几组。 既然一组是两个数,那么我们可以使用双指针分别指向数组首尾,然后再判断能否凑成和为K的组. 在使用双指针寻找之前,我们应当先将数组排序(升序降序都无所谓),…

Python Web开发技巧VII

目录 装饰器inject_serializer 装饰器atomic rebase git 清理add的数据 查看git的当前工作目录 makemigrations文件名称 action(detailTrue, methods["GET"]) 如何只取序列化器的一个字段进行返回 Response和JsonResponse有什么区别 序列化器填表和单字段如…

红黑树与平衡二叉树

文章目录 前言一、平衡二叉树二、红黑树区别 前言 数据库的底层用到了多种树结构,这里简单记录一下红黑树与平衡二叉树。 一、平衡二叉树 满足二叉树。任何节点的两个子树的高度最大差为1。如果对平衡二叉树进行删除和新增,那么会破坏平衡,…

JavaSE - Sting类

目录 一. 字符串的定义 二. String类中的常用方法 1. 比较两个字符串是否相等(返回值是boolean类型) 2. 比较两个字符串的大小(返回值是int类型) 3. 字符串查找 (1)s1.charAt(index) index:下标&…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK获取相机当前实时帧率(C#)

Baumer工业相机堡盟工业相机如何通过BGAPISDK里函数来计算相机的实时帧率(C#) Baumer工业相机Baumer工业相机的帧率的技术背景Baumer工业相机的帧率获取方式CameraExplorer如何查看相机帧率信息在BGAPI SDK里通过函数获取相机帧率 Baumer工业相机通过BGA…

剑指 Offer 26. 树的子结构

思路: 先统计B数的非空节点数countB。然后前序遍历A,当遇到A的值和B的第一个值相等时,则进行统计左右结构和值都相等的节点数和sum,如果sum countB,则true。 /*** Definition for a binary tree node.* public class…

CSS 高频按钮样式

矩形与圆角按钮 正常而言&#xff0c;我们遇到的按钮就这两种 -- 矩形和圆角&#xff1a; 它们非常的简单&#xff0c;宽高和圆角和背景色。 <div classbtn rect>rect</div><div classbtn circle>circle</div>.btn {margin: 8px auto;flex-shrink: 0;…

网络设备中的配置文件管理

建立强大网络的第一步是为灾难和网络中断做好准备&#xff0c;许多企业在中断期间遭受损失&#xff0c;因为他们缺乏备份计划并且配置管理不达标&#xff0c;使用配置文件管理工具进行适当的配置文件管理不仅有助于处理网络中断&#xff0c;还有助于优化网络性能。 使用配置文…

Redis 集群部署

Redis 3.0 版本后正式推出 Redis 集群模式,该模式是 Redis 的分布式的解决方案,是一个提供在多个 Redis 节点间共享数据的程序集,且 Redis 集群是去中心化的,它的每个 Master 节点都可以进行读写数据,每个节点都拥有平等的关系,每个节点都保持各自的数据和整个集群的状态…

QT控件通过qss设置子控件的对齐方式、大小自适应等

一些复杂控件&#xff0c;是有子控件的&#xff0c;每个子控件&#xff0c;都可以通过qss的双冒号选择器来选中&#xff0c;进行独特的样式定义。很多控件都有子控件&#xff0c;太多了&#xff0c;后面单独写一篇文章来介绍各个控件的子控件。这里就随便来几个例子 例如下拉列…