菜鸡shader:L6 人物材质基础模型以及三种透明特效AC、AB和AD

news2024/12/23 5:27:20

文章目录

  • 人物材质基础模型
    • unity练练看实现
    • 代码实现
    • 最后效果
  • 透明特效
    • AC
      • 效果展示
    • AB
      • 效果展示
    • AD
      • 效果展示
    • 自定义混合模式
      • 效果展示

人物材质基础模型

在这里插入图片描述

  • 这里是老师布置的作业,要求把之前学过的所有模型都组合起来,组成一个基本的人物材质模型。
  • 这里在上作业课的时候,老师是用了好几张贴图,我这边没用,美术方面的能力还不够(可恶啊!) 后面还是得找些教程再深入学习一下美术方面的东西,至少画贴图这方面得学会。

unity练练看实现

下面放一下unity的连连看吧:
首先是法线贴图的处理,他要作为后续的法线使用:
在这里插入图片描述

然后是光源部分漫反射和镜面反射部分,需要加上投影部分:
在这里插入图片描述

  • 这里需要解释一下,其实环境光是不会有光照衰减一说的,我们用shader forge练练看出来的材质看起来是有阴影的,应该是因为shader forge生成的代码写了两个pass,一个pass是我们的材质实现,另一个pass就是单纯为了实现模型的阴影。
  • 看了12课,说好像是因为在第二个pass中加了fallback,并且目前也只有双pass的做法才能给直接光照射的物体加上投影。
    在这里插入图片描述

然后是环境光的漫反射部分,也就是三色环境光模型:
在这里插入图片描述
然后是环境光的镜面反射部分,也就是之前学的cubemap部分,需要加上fresnel部分:
在这里插入图片描述

最后是光照和环境两个部分的连连看处理:
在这里插入图片描述

代码实现

自己实现的代码:

Shader "shader forge/L10_OldSchoolWithCubemap"
{
    Properties
    {
        //_MainTex ("Base Texture", 2D) = "white" {}
        [Header(Texture)]
        _AO_Tex ("AO_Tex", 2D) = "white" {}
        _normal ("normal", 2D) = "bump" {}
        _cubemap ("cubemap", Cube) = "_Skybox" {}

        [Header(Lighting)]
        _L_Lambert_Color ("L_Lambert_Color", Color) = (0.5,0.5,0.5,1)
        _L_Specular_Color ("L_Specular_Color", Color) = (0.5,0.5,0.5,1)
        _Light_Color ("Light_Color", Color) = (0.5,0.5,0.5,1)

        [Header(Diffuse)]
        _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)]
        _mipmap_level ("mipmap_level", Range(0, 7)) = 0
        _fresnel_exp ("fresnel_exp", Range(0, 90)) = 0.6956522
        _Env_SpecInt ("Env_SpecInt", Range(0, 5)) = 0.7826087
        _Phong_Int ("Phong_Int", Range(0, 90)) = 5
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            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;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;                
                float4 pos : SV_POSITION;
                float4 posWorld : TEXCOORD1;
                float3 nDirWS : TEXCOORD2;
                float3 tDirWS : TEXCOORD3;
                float3 biDirWS : TEXCOORD4;
                LIGHTING_COORDS(5,6)
            };

            //Texture
            uniform sampler2D _AO_Tex;
            uniform sampler2D _normal;
            uniform samplerCUBE _cubemap;
            //Lighting
            uniform float4 _L_Lambert_Color;
            uniform float4 _L_Specular_Color;
            uniform float4 _Light_Color;
            //Diffuse
            uniform float4 _E_Lambert_UpColor;
            uniform float4 _E_Lambert_DownColor;
            uniform float4 _E_Lambert_MidColor;
            //Specular
            uniform float _mipmap_level;
            uniform float _fresnel_exp;
            uniform float _Env_SpecInt;
            uniform float _Phong_Int;


            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv0 = v.uv0;
                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;
                float AO_R = tex2D(_AO_Tex,i.uv0);            

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

                //中间量准备
                /*下面是光照的漫反射和镜面反射部分*/
                //diffuse
                float NoL = max(0.0,dot(lightDir,nDirWS_FT));
                float3 L_diff = NoL * _L_Lambert_Color;

                //specular
                float NoH = max(0.0,dot(nDirWS_FT,halfDir));
                float3 L_spec = pow(NoH * _L_Specular_Color,_Phong_Int);

                //光衰部分
                float attenuation = LIGHT_ATTENUATION(i);
                //UNITY_LIGHT_ATTENUATION(attenuation, i, i.posWorld.xyz);
                float3 attenColor = attenuation * _LightColor0.xyz;

                /*下面是环境光的漫反射部分,也就是三色环境光*/
                //上层光
                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;

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

                //fresnel
                float NoV = max(0.0,dot(nDirWS_FT,viewDir));
                float OneMinusNoV = 1 - NoV;
                float fresnel = pow(OneMinusNoV,_fresnel_exp);

                //光照模型
                /*光照的漫反射和镜面反射*/
                float3 light_all = (L_diff + L_spec) * _Light_Color * attenColor;

                /*环境光的漫反射部分  三色环境光*/
                float3 env_diff_all = clamp(upColor + downColor + midColor,0.0,1.0);

                /*环境光的镜面反射部分  cubemap和fresnel部分*/
                float3 env_spec_all = cubemap_color * fresnel * _Env_SpecInt;

                /*环境光的漫反射和镜面反射的总和*/
                float3 env_all = clamp(env_diff_all + env_spec_all,0.0,1.0) * AO_R;

                float3 finalColor = clamp(env_all + light_all,0.0,1.0);

                //后处理

                //返回值
                return float4(finalColor,1.0);

                //return float4(0.0,1.0,0.0,1.0);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

最后效果

在这里插入图片描述

透明特效

在这里插入图片描述

  • AC : Alpha Test(Alpha Cutout)
  • AB : Alpha Blend
  • AD : Additive
  • 自定义混合方法:把混合方式都列在属性面板上,让使用者自己挑选并试验效果。

AC

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

  • 透明剪切,alpha cutout,也叫做alpha test,也是AC。左边的我们看出边缘比较柔,右边的锯齿比较多,alpha blend前后是错乱的,alpha test前后是正确的,AC用途如PPT所示。
  • Alpha Test非常直接,就是判断一个片元的Alpha值是否满足我们给定的阈值,不满足条件则直接discard这个片元,不参与后续的tests。Alpha Test的结果是一个片元要么完全不透明,要么被discard以至于完全看不到。
  • 所以它的其实不算正经的透明效果,它只是把不符合条件的片元给舍弃掉,造成只显示一部分片元的效果。

代码实现:

Shader "shader forge/L13_AC"
{
    Properties
    {
        _MainTex ("Base Color With A", 2D) = "white" {}
        _CutOff ("CutOff",Range(0.0,1.0))  = 0.5	//透明度阈值

    }
    SubShader
    {
        Tags {
            "RenderType"="TransparentCutout" 
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;	//我们的贴图偏移选项
            uniform float _CutOff;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv0 = TRANSFORM_TEX(v.uv0, _MainTex);    //加上贴图偏移            
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 var_MainTex = tex2D(_MainTex, i.uv0);
                //这是我们要做的主要步骤,如果贴图的透明度不大于我们的阈值,就直接裁剪抛弃掉
                clip(var_MainTex.a - _CutOff);	
                return var_MainTex;
            }
            ENDCG
        }
    }
}

效果展示

在这里插入图片描述

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

AB

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

  • 与之对比的是ab,虽然是有排序问题(如图所示,是错乱的),经常用于不考虑中间细节并且有复杂轮廓的物体使用。
  • 在特效上非常常用,作为打底。经常的一个套路,用ab打一层底,再用ad去提亮一层。

代码实现:

Shader "shader forge/L13_AB"
{
    Properties
    {
        _MainTex ("Base Color With A", 2D) = "white" {}
    }
    SubShader
    {
    	//主要做的
        Tags {
            "Queue"="Transparent" 
            "RenderType" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }

        Blend SrcAlpha OneMinusSrcAlpha		//主要做的

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	//我们的贴图偏移选项

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv0 = TRANSFORM_TEX(v.uv0, _MainTex);		//加上贴图偏移
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 var_MainTex = tex2D(_MainTex, i.uv0);
                return var_MainTex;
            }
            ENDCG
        }
    }
}

效果展示

在这里插入图片描述

  • 跟上面的AC对比一下会发现这个模型的边缘会更加柔和。

AD

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

  • AD是特效的灵魂,经常表达发光体,特效经常使用多个透明片叠加,这样每一个像素要进行好几次的计算,会造成性能的拉跨。
  • 注意防止多层透明片叠加,同时AD也可以逐渐用后处理+bloom来替代。

代码实现:

Shader "shader forge/L13_AD"
{
    Properties
    {
        _MainTex ("Base Color With A", 2D) = "white" {}
    }
    SubShader
    {
    	//主要做的
        Tags {
            "RenderType"="Transparent" 
            "Queue" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        
        Blend One One	//主要做的

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	//我们的贴图偏移选项

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);	//加上贴图偏移
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 var_MainTex = tex2D(_MainTex, i.uv);
                return var_MainTex;
            }
            ENDCG
        }
    }
}

效果展示

在这里插入图片描述

  • 一和一叠加,直接变得更亮了。

自定义混合模式

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

  • 这次我们要实现的上图左边的样子。

在这里插入图片描述

  • [Enum(枚举类型)],这行定义意思是在属性面板画出下拉列表,列表中的内容就是枚举类型中的内容。
  • 在这个shader里算出来的结果,就是源src。
  • 在这个shader开始算的之前的背景,就是目标src。

代码实现:

Shader "shader forge/L13_BlendMode"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        [Enum(UnityEngine.Rendering.BlendMode)]
        _BlendSrc ("Blend source factor",int) = 0
        [Enum(UnityEngine.Rendering.BlendMode)]
        _BlendDst ("Blend destination factor",int) = 0
        [Enum(UnityEngine.Rendering.BlendOp)]
        _BlendOp ("Blend Operation", int) = 0
    }
    SubShader
    {
    	//主要做的
        Tags {
            "RenderType"="Transparent" 
            "Queue" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        
        //下面两行是主要做的
        BlendOp [_BlendOp]
        Blend [_BlendSrc] [_BlendDst]

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	//我们的贴图偏移选项

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);	//加上贴图偏移
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 var_MainTex = tex2D(_MainTex, i.uv);
                return var_MainTex;
            }
            ENDCG
        }
    }
}

效果展示

代码做出来的属性面板:
在这里插入图片描述

模型展示:

  • 算子是srcalpha和OneMinusSrcAlpha:
    在这里插入图片描述
  • 算子是One和OneMinusSrcAalpha:
    在这里插入图片描述
  • 算子是One和One:
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于安卓的接的快接单平台/基于Android的快的接单平台

【摘要】 随着互联网的趋势的到来,各行各业都在考虑利用互联网将自己的信息推广出去,最好方式就是建立自己的平台信息,并对其进行管理,随着现在智能手机的普及,人们对于智能手机里面的应用接的快接单平台也在不断的使用…

设计模式学习之模板方法模式

设计模式系列往期文章 设计模式学习之策略模式设计模式学习之策略模式在前端的应用设计模式学习之简单工厂模式设计模式学习之工厂方法模式设计模式学习之抽象工厂模式设计模式学习之策略模式和简单工厂模式的对比设计模式学习之观察者模式 模板方法模式是行为型设计模式的一…

获取Alibaba Nacos控制台管理权限

人活着,就得随时准备经受磨难。他已经看过一些书,知道不论是普通人还是了不起的人,都要在自己的一生中经历许多磨难。 磨难使人坚强。 漏洞复现 访问漏洞url 输入默认账号密码:nacos/nacos 成功获取Alibaba Nacos控制台管理权…

全面揭秘!火山引擎边缘 IaaS 混合部署架构实践

2023年6月16日-17日 51CTO WOT全球技术创新大会在北京成功举办。在快速发展的数字化时代,云计算和边缘计算作为科技领域的两大核心驱动力,正引领着全球技术变革的潮流。为了探讨云时代基础设施在科技发展中的关键作用,推动边缘云行业的进一步…

【夏虫语冰】Office操作技巧汇总

文章目录 1、Word技巧1.1 添加题注 2、Visio技巧2.1 快捷键2.2 格式刷 结语 1、Word技巧 1.1 添加题注 在 Word 中添加、删除标题或设置其格式: 可以为图表、公式或其他对象添加题注。 题注是带编号的标签,可将其添加到图表、表格、公式或其他对象。 …

springboot+echarts +mysql制作数据可视化大屏(四图)

作者水平低,如有错误,恳请指正!谢谢!!!!! 项目简单,适合大学生参考 分类专栏还有其它的可视化博客哦! 专栏地址:https://blog.csdn.net/qq_559…

C++类和对象——(对象的赋值拷贝构造函数)

目录 对象的赋值 目录 对象的赋值 1、提出问题: 2、解决办法: 拷贝构造函数 1、拷贝构造函数的原型: 2、调用机制: 3、使用例程代码 总代码工程: 对象的赋值 1、提出问题: 能否使用一个已经构造…

Java——《面试题——网络篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 Java——《面试题——SpringBoot篇》 Java——《面试题——MySQL篇》​​​​​​ Java——《面试题——SpringCloud》 Java…

Java——《面试题——设计模式篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 Java——《面试题——SpringBoot篇》 Java——《面试题——MySQL篇》​​​​​​ Java——《面试题——SpringCloud》 Java…

QThread

QThread的执行从run()函数的执行开始; 在Qt中建立线程的主要目的就是为了用线程来处理那些耗时的后台操作,从而让主界面能及时响应用户的请求操作。 QThread的使用 链接 work对象 1,继承Qobject; 2,dowork(); 使…

(stm32)Unix时间戳

时间戳计时系统和常用的年月日时分秒计时系统有很大差别 时间戳:只计算从1970年1月1日0点整为0秒,只用最基本的秒来计时,用不进位。 常用计时系统:60秒进位1分钟,60分钟进位1小时,24小时进位1天&#xff…

Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库

介绍 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式&a…

电子器件系列44:IGBT的内部电容

对两款igbt进行比较,确定两者是否可以互换 A: B: 一、 从电路图上分析,在启动的时候,电路会提供一个15v的电压,两者都能顺利导通,可以替换 二、 开关时间 从实际使用电路上分析,这些参数对于本电路的功能…

随机数检测(二)

随机数检测(二)- 扑克检测、重叠子序列、游程总数、游程分布 3.4 扑克检测方法3.5 重叠子序列检测方法3.6 游程总数检测3.7 游程分布检测 3.4 扑克检测方法 扑克检测方法如下图。 以下实现代码供参考。 def alterOffsetBit(m, offset, listSub:list)…

HoloLens2与Unity的Socket通信踩坑日记

最近想让Hololens中获取电脑中更新的数据,打算使用套接字的方式进行通信,明明在unity中模拟测试可以进行正常通信,但是将软件部署到HoloLens上通信总是失败,找了很久的原因,找了很久的原因,终于能够正常通信…

国产自研开源大数据管理平台DataSophon

【背景】 几天在朋友圈看到开源社区Datavane发布了一个新开源项目DataSophon;一个致力于快速实现部署、管理、监控以及自动化运维大数据云原生平台,帮助快速构建起稳定、高效、可弹性伸缩的大数据云原生平台;从介绍内容来看非常优秀&#xff…

事务管理-@TransActional

事务 概念:一组操作集合,是一个不可分割的单位,这些操作要么同时成功,要么同时失败 事务操作 开启事务(一组操作开始前,开启事务):start transaction / begin;提交事务(操作全部成…

AutoSAR系列讲解(入门篇)4.8-BSW的OS功能

一、OS架构和术语解释 OS: 操作系统。就仅仅位于系统服务层,由于OS是需要直接操作硬件的一些功能的,所以系统服务层才会贯穿三层结构至达硬件。AutoSAR OS是基于OSEK OS开发出来的,OSEK也是早期ECU上的OS标准了,现在也…

matplotlib 区域填充

import matplotlib.pyplot as plt import numpy as npx np.linspace(0, 8 * np.pi, 1000) siny np.sin(x) cosy np.cos(x / 2) / 2 plt.plot(x, siny, cskyblue, labelsin-X) plt.plot(x, cosy, corangered, label1/2 cos 1/2x )# 填充颜色 plt.fill_between(x, cosy, siny,…

TiDB 多租户方案和原理

作者: li_zhenhuan 原文来源: https://tidb.net/blog/a55c1d14 使用多租户 有很多文章介绍技术上如何使用多租户,在这里简单说明: CREATE RESOURCE GROUP rg_oltp RU_PER_SEC4000; ALTER USER app1 RESOURCE GROUP "r…