实现窗户特效的Unity Shader解析

这篇具有很好参考价值的文章主要介绍了实现窗户特效的Unity Shader解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        本文将详细介绍一种使用Unity Shader实现窗户特效的方法。通过分析代码,我们将解释每个关键部分的作用,以及如何将其组合在一起以实现逼真的窗户效果。希望本文能为Shader编程初学者和Unity开发者提供一些有用的指导。

实现窗户特效的Unity Shader解析,Unity,Shader,unity,游戏引擎

 

引言:

        在游戏和虚拟现实应用中,窗户效果经常用于增强场景的真实感。通过使用Shader,我们可以模拟光线在玻璃上的折射和反射效果,让窗户看起来更加逼真。本文将介绍一种用Unity Shader实现窗户特效的方法,并对代码逐行解析。

Shader "Unlit/Window"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}  // 主纹理
_Size("Size",float) = 1  // 大小
_T("Time",float) = 1  // 时间
_Distortion("Distortion", range(-5, 5)) = 1  // 扭曲
_Blur("Blur",range(0, 1)) = 1  // 模糊程度
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent"}  // 标签
LOD 100
    GrabPass{"_GrabTexture"}  // GrabPass命令将渲染窗口中的内容复制到纹理_GrabTexture中
    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        // make fog work
        #pragma multi_compile_fog
        #define S(a, b, t) smoothstep(a,b,t)  // 定义了计算平滑插值的宏函数
        #include "UnityCG.cginc"  // Unity内置着色器代码宏

        struct appdata
        {
            float4 vertex : POSITION;  // 顶点位置
            float2 uv : TEXCOORD0;  // 纹理坐标
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;  // 纹理坐标
            float4 grabUv : TEXCOORD1;  // 抓取窗口纹理坐标
            UNITY_FOG_COORDS(1)  // Unity内置的雾效相关宏
            float4 vertex : SV_POSITION;  // 顶点位置
        };

        sampler2D _MainTex,_GrabTexture;  // 主纹理和抓取窗口纹理
        float4 _MainTex_ST;  // 主纹理的平铺和偏移参数
        float _Size, _T , _Distortion, _Blur;  // 大小、时间、扭曲和模糊程度参数

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);  // 将顶点从对象空间转换到剪裁空间
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);  // 对纹理坐标进行平铺和偏移变换
            o.grabUv = UNITY_PROJ_COORD(ComputeGrabScreenPos(o.vertex));  // 计算抓取窗口的纹理坐标

            UNITY_TRANSFER_FOG(o,o.vertex);  // 将雾效信息传递给片段着色器
            return o;
        }

        float N21(float2 p)
        {
            p = frac(p*float2(123.34,345.45));  // 将纹理坐标乘以固定值并取小数部分
            p += dot(p,p + 34.345);  // 点乘纹理坐标并加上一定值
            return frac(p.x*p.y);  // 返回取小数部分后的乘积
        }

        float3 Layer(float2 UV,float t)
        {
            float2 aspect = float2(2,1);  // 窗口宽高比
            float2 uv = UV*_Size * aspect;  // 对纹理坐标进行平铺和偏移变换
            uv.y += t * .25;  // 根据时间进行纹理坐标的偏移
            float2 gv = frac(uv)-.5;  // 将纹理坐标取小数部分后再减去0.5的值

            float2 id = floor(uv);  // 取纹理坐标的整数部分

            float n = N21(id);  // 计算噪声值
            t += n*6.2831;  // 根据噪声值进行时间的调整

            float w = UV .y * 10;  // 根据纹理坐标的y值进行宽度调整
            float x = (n - .5)*.8;  // 根据噪声值进行x的调整
            x += (.4-abs(x)) * sin(3*w)*pow(sin(w),6)*.45;  // 根据宽度和噪声进行x的进一步调整

            float y = -sin(t+sin(t+sin(t)*.5))*.45;  // 根据时间和噪声进行y的调整
            y -= (gv.x-x)*(gv.x-x);  // 根据x与纹理坐标的偏移进行y的进一步调整

            float2 dropPos = (gv-float2(x,y)) / aspect;  // 计算扭曲的纹理坐标
            float drop= S(.05,.03,length(dropPos));  // 计算扭曲的强度

            float2 trailPos = (gv-float2(x,t * .25)) / aspect;  // 计算轨迹的纹理坐标
            trailPos.y = (frac(trailPos.y * 8)-.5)/8;  // 计算纹理坐标的小数部分并进行调整
            float trail = S(.03,.01,length(trailPos));  // 计算轨迹的强度
            float fogTrail = S(-.05,.05,dropPos.y);  // 根据扭曲的纹理坐标的y值进行雾效的调整
            fogTrail *= S(.5, y, gv.y);  // 根据y和纹理坐标的y值再次进行雾效的调整
            trail *=fogTrail;  // 综合计算轨迹的强度

            fogTrail *= S(.05, .04, abs(dropPos.x));  // 根据扭曲的纹理坐标的x值进行雾效的进一步调整

            float2 offs = drop*dropPos + trail * trailPos;  // 计算扭曲和轨迹的综合效果

            return float3(offs,fogTrail);  // 返回扭曲、轨迹和雾效混合后的结果
        }

        fixed4 frag (v2f i) : SV_Target
        {
            float t = fmod(_Time.y +_T,7200);  // 计算时间

            float4 col = 0;  // 初始化颜色

            float3 drops = Layer(i.uv,t);  // 计算扭曲、轨迹和雾效
            drops += Layer(i.uv*1.23 + 7.54,t);  // 对纹理坐标进行平铺和偏移变换并再次计算扭曲、轨迹和雾效
            drops += Layer(i.uv*1.35 + 1.54,t);  // 对纹理坐标进行平铺和偏移变换并再次计算扭曲、轨迹和雾效
            drops += Layer(i.uv*1.57 - 7.54,t);  // 对纹理坐标进行平铺和偏移变换并再次计算扭曲、轨迹和雾效

            float fade = 1-saturate(fwidth(i.uv)*60);  // 根据纹理坐标的宽度计算淡化系数

            float blur = _Blur * 7 * (1-drops.z * fade);  // 根据淡化系数和扭曲、轨迹和雾效的深度计算模糊程度

            //col = tex2Dlod(_MainTex, float4(i.uv + drops.xy * _Distortion,0,blur));

            float2 projUv = i.grabUv.xy / i.grabUv.w;  // 根据抓取窗口的纹理坐标计算投影纹理坐标
            projUv += drops.xy * _Distortion * fade;  // 根据扭曲、轨迹和雾效的深度进行投影纹理坐标的调整
            blur *= .01;  // 调整模糊的程度

            const float numSamples = 32;  // 采样次数
            float a = N21(i.uv)*6.2831*0;  // 根据纹理坐标计算角度
            for(float i = 0; i < numSamples; i++)
            {
                float2 offs = float2(sin(a),cos(a))*blur;  // 根据角度和模糊程度计算偏移量
                float d = frac(sin((i+1)*546.)*5424.);  // 根据角度计算采样步长
                d = sqrt(d);  // 开平方根
                offs *= d;  // 根据采样步长调整偏移量
                col += tex2D(_GrabTexture,projUv + offs);  // 对抓取窗口纹理进行采样
                a++;
            }
            col /= numSamples;  // 对颜色进行平均

            //col *= 0; col += fade;

            return col*.9;  // 返回最终颜色
        }
        ENDCG
    }
}
}

技术细节解析:

  1. Shader属性定义: 在这段代码中,我们定义了几个可在Inspector面板上调节的Shader属性。其中包括_MainTex(纹理)、_Size(大小)、_T(时间)、_Distortion(扭曲度)和_Blur(模糊度)等。这些属性可以根据需要进行调整,以获得最佳效果。

  2. 顶点函数(vert): 顶点函数是Shader的顶点转换函数。它将输入的顶点位置和纹理坐标进行转换和处理,并将输出传递给片段函数(frag)使用。

  3. 片段函数(frag): 片段函数是Shader的主要计算部分。在该函数中,我们使用一系列噪声函数和数学函数来模拟窗户特效的各个方面,比如光线折射、光影效果、水滴效果等。最后,我们通过采样_GrabTexture来获取最终的纹理颜色值。

  4. 主循环处理: 在frag函数中,我们通过多个Layer函数的叠加来模拟窗户上的各种效果。每个Layer函数都表示窗户上的一种特效,比如水滴、光线、模糊等。通过调节主循环中的参数可以控制各个特效的强度和效果。

结论:

        通过使用Unity Shader编写的这个窗户特效,可以使游戏场景更加逼真且具有交互性。通过对Shader属性的调整,我们可以轻松地定制窗户的效果,以适应不同的场景需求。

总结:

        本文详细介绍了如何使用Unity Shader实现窗户特效,并对代码进行了逐行解析。通过对Shader属性和函数的说明,读者可以更好地理解窗户特效的实现原理,并在自己的项目中进行应用。

提示:

        在实际写博客时,可以根据需要添加更多的细节和示例代码,以便读者更好地理解并自己尝试实现窗户特效。希望本文对学习Shader编程和Unity开发有所帮助。文章来源地址https://www.toymoban.com/news/detail-525585.html

到了这里,关于实现窗户特效的Unity Shader解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity游戏demo – 😶‍🌫️版本: Unity2021 😶‍🌫️适合人群:Unity初学者进阶 😶‍🌫️学习目标:3D赛车游戏的基础制作 😶‍🌫️技能

    2024年02月09日
    浏览(62)
  • unity数列帧播放特效Shader怎么能放有光晕的特效能光晕清晰点

    怎么能放有光晕的特效能光晕清晰点 Shader \\\"Series/CRLuo_Teaching_Tex_Amin_G\\\" {     Properties     {         [NoScaleOffset]         _MainTex (\\\"Texture\\\", 2D) = \\\"white\\\" {}         _X_Sum(\\\"across\\\",float) = 3         _Y_Sum(\\\"vertical\\\",float) = 3         _ShowID(\\\"ID\\\",float) = 0          [Toggle(_AutoPlay_Key)] _Auto

    2024年01月16日
    浏览(55)
  • Unity游戏图形学 Shader结构

    openGL:SLG跨平台 =GLSL:openGL shaderlauguge DX:微软开发,性能很好,但是不能跨平台 =HLSL:high level shader language CG:微软和Nvidia公司联合开发,跨平台,基于c语言开发,性能很好 openGL、dx、cg都包含 CG和HLSL包括在 CGPROGRAM...ENDCG 语法快内 GLSL包括在 GLSLPROGRAM...ENDGLSL 语法快内 自己

    2024年02月01日
    浏览(41)
  • Unity3D教程:2D游戏技能特效

    在我们的2D图形游戏中不可缺少大量的光影、技能特效,像Diablo II中的魔法效果的实现,幸好我们拥有强大的CPU来为我们实现Alpha混合与色彩饱和混合,接下来让我们来讨论一下如何用这些方法来实现我们游戏中所需要的技能特效。     一、Alpha混合特效     Alpha混合可以让我

    2024年02月01日
    浏览(54)
  • 【毕业论文】| 基于Unity3D引擎的冒险游戏的设计与实现

    📢博客主页:肩匣与橘 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 肩匣与橘 编写,首发于 CSDN 🙉 📢生活依旧是美好而又温柔的,你也是✨  基于Unity3D引擎的冒险游戏的设计与实现 📢前言 摘要 Abstract 1 绪论 1.1 选题背景 1.2 研究目的及意义 2 开发工具

    2024年02月05日
    浏览(62)
  • Unity3D 实现基于物理引擎的绳子关节解析详解

    在游戏开发中,有时候我们需要实现绳子关节效果,比如在射击游戏中射击绳子,或者在平衡游戏中使用绳子作为支撑。本文将详细介绍如何使用Unity3D的物理引擎实现绳子关节效果。 对惹,这里有一 个游戏开发交流小组 ,希望大家可以点击进来一起交流一下开发经验呀 首

    2024年02月21日
    浏览(87)
  • Unity中Shader的BRDF解析(二)

    我们在这篇文章中,继续来继续解析BRDF中的高配置情况( UNITY_PBS_USE_BRDF1)下,迪士尼的漫反射计算 Unity中Shader的BRDF解析(一) 在上篇文章中,我们解析到了BRDF的具体计算 我们在该函数的最后能找到与迪士尼BRDF原则对应的程序: // Specular term // HACK: theoretically we should divi

    2024年02月04日
    浏览(39)
  • Unity中Shader的BRDF解析(一)

    在上篇文章中,我们解析了Standard的GI实现,这篇文章我们来解析一下Standard的PBS计算。 Unity中Shader的Standard材质解析(二) 上篇文章中,主要解析了这个公式 GI漫反射 和 GI镜面反射 LightingStandard1(o, worldViewDir, gi); 在该函数中,主要进行了如下计算: s.Albedo = DiffuseAndSpecularF

    2024年02月04日
    浏览(38)
  • Unity中Shader的BRDF解析(三)

    在上篇文章中,我们解析了BRDF的漫反射项,这篇文章我们继续解析BRDF中的镜面反射 Unity中Shader的BRDF解析(二) 我们返回 specular ,看一下高光效果: return fixed4(specular,1); //镜面反射中的DV项的计算 //最后乘以PI的原因是因为计算 漫反射 时,等式右边没有除以PI。 //导致算出的

    2024年02月01日
    浏览(37)
  • Unity中Shader指令优化(编译后指令解析)

    我们先读懂Shader编译后代码,才能对Shader进行合理的优化 我们目前先只编译到 D3D 平台 这是编译后的代码(我们来逐步分析):

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包