当前位置: 首页 > news >正文

【Unity】URP管线Shader编程实例详解 (1) : 漩涡效果shader

作者说

  1. 本系列教程适用于有编程基础和图形学基础知识的读者.
  2. 如果对您有所帮助,请点个免费的赞和关注,您的支持就是我更新最大的动力!
  3. 如果你有任何想看的内容欢迎评论区留言!
  4. 本系列教程Github : https://github.com/Sky0Master/Unity-URP-Shader-Tutorial

效果预览

Before
在这里插入图片描述


准备工作

在Unity Assets文件夹里右键新建一个Unlit Shader
在这里插入图片描述

命名之后,再右键这个shader,create -> material
在这里插入图片描述
接着随便把这个材质应用到一个Renderer上就行,我这里应用到了一个Sprite Renderer上


动手写代码!

现在我们来实现一个对纹理施加漩涡效果的shader,其实这个效果的原理就是在fragment着色器中对uv坐标进行绕中心旋转的变换,使用变换后的uv坐标去采样。(如果对【采样】和【uv坐标】的概念比较熟悉的话应该能理解
每一行代码我都进行了详细的注释,如果对其中有任何不明白的地方请在评论区留言,我会据此对注释进行补充,感谢!

Shader "Unlit/SwirlEffect"
{
    Properties {
        _MainTex ("Base Texture", 2D) = "white" {}    // 基础纹理输入,用于最终颜色输出
        _Angle ("Rotation Angle", Range(0,10)) = 2    // 控制旋转强度的参数, Range(0,10)限制调节范围避免过度扭曲
        _Radius ("Effect Radius", Range(0,1)) = 0.5   // 效果作用半径,控制漩涡中心到边缘的衰减范围
    }
    SubShader
    {
        Tags { 
            "RenderType"="Transparent" //着色器替换标签,这个部分建议参考https://docs.unity3d.com/cn/current/Manual/SL-ShaderReplacement.html
            "Queue"="Transparent"	//设置渲染队列为透明层级
            "RenderPipeline"="UniversalPipeline"  //声明使用的渲染管线
        }
        
        Pass
        {
        	Blend SrcAlpha OneMinusSrcAlpha // 使用标准透明度混合 读者可以尝试注释掉这行会发生什么
            HLSLPROGRAM //使用URP标准的HLSL语法
            #pragma vertex vert // 声明顶点着色器
            #pragma fragment frag  // 声明片段着色器
            
            //#pragma multi_compile_fog //开启雾效支持
            
            //URP专用
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes { //输入数据结构 (URP命名规范)
                float4 positionOS : POSITION; //物体空间的顶点坐标
                float2 uv : TEXCOORD0;  //初始纹理坐标
            };

            struct Varyings {   //输出数据结构 (URP命名规范)
                float4 positionCS : SV_POSITION; //裁剪空间坐标(SV_前缀)
                float2 uv : TEXCOORD0;  //传递纹理坐标
            };

            TEXTURE2D(_MainTex);    //在HLSL中,TEXTURE2D是一个宏,用于声明纹理资源, 这行代码告诉Shader存在一个名为_MainTex的2D纹理,供后续采样使用
            SAMPLER(sampler_MainTex); //SAMPLER宏声明采样器状态,与纹理绑定。URP中,纹理和采样器通常是分开的,这样可以更灵活地重用采样器设置
            float _Angle;   //自定义的属性,在Properties块中声明后,需要在HLSL代码中再次声明,以便在着色器中使用. 这样可以在Properties和HLSL中同步变量,确保参数传递正确
            float _Radius;

            Varyings vert(Attributes IN) {
                Varyings OUT;
                OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); // URP坐标变换
                OUT.uv = IN.uv;   // 直接传递UV
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target {
                // 计算中心偏移
                float2 centerOffset = IN.uv - float2(0.5,0.5);
                float distance = length(centerOffset);
                
                // 动态旋转计算
                float rotation = _Angle * saturate(1 - distance/_Radius); //基于自定义半径的衰减计算
                float sinRot, cosRot;   
                sincos(rotation, sinRot, cosRot); //性能优化,同时计算旋转角度的sin和cos而不是分开计算
                
                // UV变换矩阵
                float2x2 rotMatrix = float2x2(cosRot, -sinRot, sinRot, cosRot); //旋转矩阵构造
                float2 distortedUV = mul(rotMatrix, centerOffset) + 0.5;    //应用矩阵变换

                // 采样纹理
                half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, distortedUV); //使用变换后的uv坐标去采样纹理
                
                // 边缘淡化
                float fade = smoothstep(_Radius, _Radius * 0.8, distance); //边缘过渡优化
                return half4(color.rgb, color.a * fade);    //透明度混合
            }
            ENDHLSL
        }
    }
}

相关文章:

  • 10道Redis常见面试题速通
  • 网卡与网口全解析:从基础到Linux高级管理
  • 基于GO语言的车牌识别api技术-港澳车牌文字识别
  • 【JavaScript Day23】jQuery事件绑定及动画
  • 深度学习进阶:构建多层神经网络
  • 从零开始:在 MacOS 中通过 Docker 部署跨平台 Redis 服务(支持 Ubuntu 迁移)
  • 基于Redis 的分布式 session 图解
  • 计算重建dMRI与GrondTruth之间的角度误差图(AAE)代码实现(pytorch)
  • Java 网络协议面试题答案整理,最新面试题
  • B站pwn教程笔记-3
  • 记录锁,间隙锁,Next-Key Lock
  • 2025数学建模竞赛汇总,错过再等一年
  • 2025-02-25 学习记录--C/C++-用C语言实现删除字符串中的子串
  • ollama无法通过IP:11434访问
  • 第9章 机器学习与统计模型
  • 《OpenCV》—— 背景建模
  • 精美登录注册UI,登录页面设计模板
  • 微信小程序面试题
  • 分治算法、动态规划、贪心算法、分支限界法和回溯算法的深度对比
  • 开源堡垒机 JumpServer 社区版实战教程:发布机的配置与Website资产配置使用