平面漩涡Shader

本文介绍了一种使用Unity Shader创建平面漩涡效果的方法。通过调整背景处理和纹理实时旋转,实现了广告牌效果与图片矩阵旋转结合的视觉效果。文中详细展示了Shader代码,包括如何设置旋转参数和处理透明度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近进入了一家“养老”公司,公司节奏比之前慢了非常多,好处是心情比较轻松,做到哪算哪,但是没有高手在身边了,就没有什么学习的机会了,学习只有靠自觉了。

下面是一个平面漩涡效果:
在这里插入图片描述

其实说白了就是一个广告牌效果加上一个图片的矩阵旋转。网上随便找了一长渲染的图片:
在这里插入图片描述
然后参数是这样子的:
在这里插入图片描述

修改的部分有两处:

一个是对黑色背景的处理:

fixed4 c = tex2D (_MainTex, uv);
				//只取中间的部分
				float d =length(float2(uv.x-0.5,uv.y-0.5));
				if(d>0.5)clip(-1);
				//非线色部分透明
				c.a = c.rgb.r;
				c.r*=1.5;
				c.rgb = _Color.rgb*c.r;

二是对文理实时进行旋转:

float Rote = (-_Time.y*100 * 3.1415926)/180;
				float sinNum = sin(Rote);
				float cosNum = cos(Rote);

				float2 di = float2(_CenterX,_CenterY);
				float2 uv = mul(float3(i.uv - di,1),float3x3(1,0,0,0,1,0,_OffsetX,_OffsetY,1)).xy;
				uv = mul(uv,float2x2(cosNum,-sinNum,sinNum,cosNum))+di;

下面是完整代码:

Shader "Custom/GuangaopaiRota" {
	Properties {
		_MainTex ("Main Tex", 2D) = "white" {}
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_VerticalBillboarding ("Vertical Restraints", Range(0, 1)) = 1 
		
		_CenterX("旋转中点x",Float) = 0.5
		_CenterY("旋转中点y",Float) = 0.5
		_OffsetX("平移x",float) = 0
		_OffsetY("平移y",float) = 0
	}
	SubShader {
		//这里主要是关闭批处理
		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
		
		Pass { 
			Tags { "LightMode"="ForwardBase" }
			
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			Cull Off
		
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			
			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
			fixed _VerticalBillboarding;

			float _CenterX;
			float _CenterY;
			float _OffsetX;
			float _OffsetY;
			
			struct a2v {
				float4 vertex : POSITION;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};
			
			v2f vert (a2v v) {
				v2f o;
				
				float3 center = float3(0, 0, 0);
				float3 viewer = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos, 1));
				
				float3 normalDir = viewer - center;
				normalDir.y =normalDir.y * _VerticalBillboarding;
				normalDir = normalize(normalDir);
				float3 upDir = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0);
				float3 rightDir = normalize(cross(upDir, normalDir));
				upDir = normalize(cross(normalDir, rightDir));
				
				float3 centerOffs = v.vertex.xyz - center;
				float3 localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;
              
				o.pos = UnityObjectToClipPos(float4(localPos, 1));
				o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target {
				//计算旋转部分
				float Rote = (-_Time.y*100 * 3.1415926)/180;
				float sinNum = sin(Rote);
				float cosNum = cos(Rote);

				float2 di = float2(_CenterX,_CenterY);
				float2 uv = mul(float3(i.uv - di,1),float3x3(1,0,0,0,1,0,_OffsetX,_OffsetY,1)).xy;
				uv = mul(uv,float2x2(cosNum,-sinNum,sinNum,cosNum))+di;//

				

				fixed4 c = tex2D (_MainTex, uv);
				//只取中间的部分
				float d =length(float2(uv.x-0.5,uv.y-0.5));
				if(d>0.5)clip(-1);
				//非线色部分透明
				c.a = c.rgb.r;
				c.r*=1.5;
				c.rgb = _Color.rgb*c.r;

				return c;
			}
			
			ENDCG
		}
	} 
	FallBack "Transparent/VertexLit"
}
<think>我们使用HLSL编写一个在椭圆区域内实现漩涡旋转效果的Shader。主要思路如下:1.定义椭圆区域:通过椭圆方程判断当前UV是否在椭圆内。2.在椭圆区域内,将UV坐标转换为极坐标,然后根据半径和旋转参数调整角度,实现漩涡效果(内圈旋转快,外圈旋转慢)。3.将处理后的极坐标转换回直角坐标系,并采样纹理。4.椭圆区域外的UV保持不变。具体步骤:-首先,将UV坐标平移到以椭圆中心为中心。-计算椭圆方程的值,用于生成椭圆遮罩(1表示在椭圆内,0表示在椭圆外)。-对于椭圆内的点,计算极坐标(半径和角度),然后根据时间、漩涡强度和半径计算旋转角度(旋转角度随半径减小而增大,实现内快外慢)。-应用旋转角度,得到新的极坐标,再转换回直角坐标系。-使用椭圆遮罩混合原始UV和旋转后的UV。注意:我们使用smoothstep来实现椭圆边界的平滑过渡。参数:-_Center:椭圆中心(例如(0.5,0.5))-_RadiusX:椭圆在x方向的半径-_RadiusY:椭圆在y方向的半径-_RotationSpeed:基础旋转速度-_VortexStrength:漩涡强度(控制内圈比外圈多旋转多少)-_EdgeSmoothness:边界平滑度(用于smoothstep)代码结构:1.顶点着色器:标准全屏四边形处理。2.片段着色器:实现上述漩涡效果。下面给出完整的HLSL代码(基于UnityShaderLab):</think>以下是一个使用 HLSL 实现的椭圆区域内漩涡旋转效果的 Shader 代码,包含详细注释和参数说明: ```hlsl Shader "Custom/EllipseVortex" { Properties { _MainTex ("Texture", 2D) = "white" {} _Center ("Center", Vector) = (0.5, 0.5, 0, 0) _RadiusX ("X Radius", Range(0.1, 0.5)) = 0.3 _RadiusY ("Y Radius", Range(0.1, 0.5)) = 0.2 _RotationSpeed ("Rotation Speed", Float) = 2.0 _VortexStrength ("Vortex Strength", Float) = 30.0 _EdgeSmoothness ("Edge Smoothness", Range(0.001, 0.1)) = 0.02 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #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; float2 _Center; float _RadiusX; float _RadiusY; float _RotationSpeed; float _VortexStrength; float _EdgeSmoothness; 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 { // 计算相对于椭圆中心的UV坐标 float2 centeredUV = i.uv - _Center; // 计算椭圆方程值:$\frac{x^2}{a^2} + \frac{y^2}{b^2}$ float ellipseValue = pow(centeredUV.x / _RadiusX, 2) + pow(centeredUV.y / _RadiusY, 2); // 创建椭圆遮罩(带平滑过渡) float mask = smoothstep(1.0 - _EdgeSmoothness, 1.0, 1.0 - ellipseValue); // 计算极坐标 float radius = length(centeredUV); float angle = atan2(centeredUV.y, centeredUV.x); // 计算漩涡旋转角度(内圈旋转更快) // 公式:$\theta = \text{time} \times \text{speed} + \text{strength} \times (1 - \text{radius})$ float vortexRotation = _Time.y * _RotationSpeed + _VortexStrength * (1 - radius); // 应用旋转 float2 rotatedUV; rotatedUV.x = cos(angle + vortexRotation) * radius; rotatedUV.y = sin(angle + vortexRotation) * radius; // 转回原始坐标系 rotatedUV += _Center; // 混合原始UV和旋转后的UV float2 finalUV = lerp(i.uv, rotatedUV, mask); // 采样纹理 fixed4 col = tex2D(_MainTex, finalUV); return col; } ENDCG } } } ``` ### 关键参数说明: 1. **椭圆控制参数**: - `_Center`:椭圆中心坐标(0-1范围) - `_RadiusX`:X轴半径(椭圆宽度) - `_RadiusY`:Y轴半径(椭圆高度) - `_EdgeSmoothness`:边界平滑度(值越大过渡越柔和) 2. **漩涡效果参数**: - `_RotationSpeed`:基础旋转速度(值越大整体旋转越快) - `_VortexStrength`:漩涡强度(值越大内圈旋转越快) ### 使用说明: 1. 将此 Shader 应用到材质并赋给平面对象 2. 调整参数实现不同效果: - 设置 `_RadiusX = _RadiusY` 可获得圆形漩涡 - 增大 `_VortexStrength` 使内圈旋转更快 - 减小 `_EdgeSmoothness` 获得锐利边界 - 增大 `_EdgeSmoothness` 获得柔和过渡边界 ### 效果原理: 1. **椭圆区域计算**: - 使用椭圆方程 $\frac{x^2}{a^2} + \frac{y^2}{b^2} \leq 1$ 定义区域 - `smoothstep` 实现边界平滑过渡[^1] 2. **漩涡旋转**: - 将 UV 转换为极坐标 $(r, \theta)$ - 旋转角度计算:$\theta_{new} = \theta + \Delta t \times \omega + k \times (1 - r)$ - 其中 $k$ 控制内圈加速效果[^1] 3. **动态混合**: - 使用 `lerp` 在椭圆内外区域平滑过渡 - 椭圆内部使用旋转 UV,外部使用原始 UV ### 性能优化建议: 1. 如需移动设备使用: - 将 `smoothstep` 替换为 `step` 减少计算量 - 降低 `_VortexStrength` 值 - 使用预计算旋转矩阵 2. 复杂场景优化: ```hlsl // 简化的旋转计算(减少三角函数调用) float cosRot = cos(vortexRotation); float sinRot = sin(vortexRotation); rotatedUV = float2( centeredUV.x * cosRot - centeredUV.y * sinRot, centeredUV.x * sinRot + centeredUV.y * cosRot ) / max(radius, 0.001) * radius + _Center; ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小盖子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值