【着色器实现RoundWave圆形波纹效果_Shader效果第六篇】

本文详细介绍了如何在Unity游戏引擎中利用着色器技术实现RoundWave圆形波纹效果,包括关键算法和技术美术的应用。
摘要由CSDN通过智能技术生成

效果如下

请添加图片描述

属性栏如下

在这里插入图片描述

属性块:

关于属性的内容可以看这篇:【Unity Shader 中Properties 相关介绍】

    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
		_Color("Main Color", Color) = (1,1,1,1)
		_RoundWaveStrength("Wave Strength", Range(0, 1)) = 0.7
		_RoundWaveSpeed("Wave Speed", Range(0, 5)) = 2
    }
  • Properties块定义了可以在材质编辑器中调整的属性。

SubShader块:

    SubShader
    {
        Tags {"Queue" = "Transparent" "RenderType"="Opaque" "IgnoreProjector" = "True" }        
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Cull Off
  • 定义了一个子着色器。
  • Tags定义了渲染队列、渲染类型和投影忽略标记。
  • Blend定义了混合模式。
  • ZWriteCull控制深度写入和剔除。

CGPROGRAM:

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
  • 定义了一个渲染通道。
  • 使用了CGPROGRAM和相关指令来指定顶点和片段着色器。

appdata:

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
				half4 color : COLOR;
            };
  • 定义了顶点着色器的输入结构。

v2f:

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
				half4 color : COLOR;
            };
  • 定义了顶点着色器的输出结构。

声明采样:

            sampler2D _MainTex;
            half4 _MainTex_ST, _MainTex_TexelSize, _Color;
            float _RandomSeed;
            half _RoundWaveStrength, _RoundWaveSpeed;
属性声明详细解释如下
名称注释
sampler2D _MainTex;声明了一个名为_MainTex的2D纹理采样器。这通常用于存储和采样主纹理图像。
名称注释
half4 _MainTex_ST, _MainTex_TexelSize, _Color;声明了三个half4类型的属性:
_MainTex_ST通常用于存储纹理的平铺(tiling)和偏移(offset)参数。
_MainTex_TexelSize存储纹理的像素尺寸,这有助于进行像素级的纹理操作。
_Color一个颜色值,用于修改或混合纹理的颜色。
名称注释
half这是一个数据类型,通常用于着色器语言中。half代表一个16位的浮点数,它比标准的32位浮点数(即float类型)占用更少的内存和带宽,但精度较低。在图形渲染中,使用half类型可以减少内存使用,尤其是在处理大量数据时,比如纹理坐标、顶点属性等。
_RoundWaveStrength这是一个变量名。在着色器语言中,变量名通常以下划线_开头,表示这是一个私有变量,仅在当前着色器中使用。RoundWaveStrength这个名字暗示这个变量可能用于控制某种“圆形波纹”效果的强度。
_RoundWaveSpeed这同样是一个变量名,以下划线_开头。RoundWaveSpeed这个名字暗示这个变量可能用于控制“圆形波纹”效果的移动速度。

v2f vert顶点着色器函数:

            v2f vert (appdata v)
            {
                v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.color = v.color;
                return o;
            }
  • 顶点着色器函数,转换顶点坐标和纹理坐标。

片段着色器结构体:

            half4 frag (v2f i) : SV_Target
            {
				// 片段着色器代码,负责生成扭曲轮廓效果
				// ...
            }
            ENDCG
        }
    }
  • 片段着色器函数,负责渲染最终像素颜色。
  • ENDCG标记CGPROGRAM代码块的结束。

片段着色器代码

            half4 frag (v2f i) : SV_Target
            {
				float2 uvRect = i.uv;
				half xWave = ((0.5 * _MainTex_ST.x) - uvRect.x);
				half yWave = ((0.5 * _MainTex_ST.y) - uvRect.y) * (_MainTex_TexelSize.w / _MainTex_TexelSize.z);
				half ripple = -sqrt(xWave*xWave + yWave* yWave);
				i.uv += (sin((ripple + (_Time.y + _RandomSeed) * (_RoundWaveSpeed/10.0)) / 0.015) * (_RoundWaveStrength/10.0)) % 1;
				half4 col = tex2D(_MainTex, i.uv) * i.color;
				col *= _Color;
                return col;
            }

具体的代码注释如下:

片段着色计算注释
half4 frag (v2f i) : SV_Target定义了一个片段着色器函数frag,它接收一个从顶点着色器传递过来的结构体v2f i,输出颜色为SV_Target
float2 uvRect = i.uv;这行代码声明了一个名为uvRectfloat2类型变量,并将传入的i.uv赋值给它。i.uv通常是纹理坐标,表示纹理图像在屏幕空间中的位置。
half xWave = ((0.5 * _MainTex_ST.x) - uvRect.x);这里计算了波纹效果在x方向的偏移量。_MainTex_ST.x是纹理的缩放因子,uvRect.x是当前纹理坐标的x分量。通过从0.5(纹理坐标的中心)减去uvRect.x,可以得到相对于纹理中心的偏移量。
half yWave = ((0.5 * _MainTex_ST.y) - uvRect.y) * (_MainTex_TexelSize.w / _MainTex_TexelSize.z);这行代码计算了波纹效果在y方向的偏移量。_MainTex_ST.y是纹理的垂直缩放因子,uvRect.y是当前纹理坐标的y分量。通过将(0.5 * _MainTex_ST.y) - uvRect.y的结果乘以_MainTex_TexelSize.w / _MainTex_TexelSize.z,可以调整波纹的幅度。
half ripple = -sqrt(xWave*xWave + yWave* yWave);计算波纹的“波峰”位置。这里使用平方根函数sqrt计算xWaveyWave平方和的平方根,然后取负值。这将创建一个从中心向外扩散的波纹效果。
i.uv += (sin((ripple + (_Time.y + _RandomSeed) * (_RoundWaveSpeed/10.0)) / 0.015) * (_RoundWaveStrength/10.0)) % 1;这行代码将波纹效果应用到纹理坐标上。首先计算波纹的正弦值,其中ripple是波峰位置,_Time.y是当前时间,_RandomSeed是一个随机种子,_RoundWaveSpeed是波纹速度。通过将这些值相加并乘以_RoundWaveStrength,可以调整波纹的强度。最后,使用% 1确保纹理坐标在0到1的范围内循环。
half4 col = tex2D(_MainTex, i.uv) * i.color;使用修改后的纹理坐标i.uv从纹理_MainTex中采样颜色,并将其与传入的颜色i.color相乘。tex2D是采样纹理的函数,half4是一个包含四个半精度浮点数的颜色值。
col *= _Color;将采样得到的颜色与一个全局颜色_Color相乘,这可以用于调整最终颜色的亮度或色调。
return col;返回最终计算得到的颜色值。
返回
	Fallback "Sprites/Default"
}

完整代码

Shader "RoundWave"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
		_Color("Main Color", Color) = (1,1,1,1)
		_RoundWaveStrength("Wave Strength", Range(0, 1)) = 0.7
		_RoundWaveSpeed("Wave Speed", Range(0, 5)) = 2
    }

    SubShader
    {
        Tags {"Queue" = "Transparent" "RenderType"="Opaque" "IgnoreProjector" = "True" }        
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Cull Off
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
            half4 _MainTex_ST, _MainTex_TexelSize, _Color;
            float _RandomSeed;
            half _RoundWaveStrength, _RoundWaveSpeed;

            v2f vert (appdata v)
            {
                v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.color = v.color;
                return o;
            }

            half4 frag (v2f i) : SV_Target
            {
				float2 uvRect = i.uv;
				half xWave = ((0.5 * _MainTex_ST.x) - uvRect.x);
				half yWave = ((0.5 * _MainTex_ST.y) - uvRect.y) * (_MainTex_TexelSize.w / _MainTex_TexelSize.z);
				half ripple = -sqrt(xWave*xWave + yWave* yWave);
				i.uv += (sin((ripple + (_Time.y + _RandomSeed) * (_RoundWaveSpeed/10.0)) / 0.015) * (_RoundWaveStrength/10.0)) % 1;
				half4 col = tex2D(_MainTex, i.uv) * i.color;
				col *= _Color;
                return col;
            }
            ENDCG
        }
    }
	Fallback "Sprites/Default"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴走约伯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值