Unity HSVColor Shader

这篇博客介绍了如何通过设置HSL(亮度、饱和度、色调)属性,用Shader代码实现UI元素颜色的实时调节。教程详细讲解了Shader编写过程和使用步骤,适合UI设计师和开发者了解和应用。

通过设置H(亮度)、S(饱和度)、V(色调)调节颜色的Shader

Shader 代码:

Shader "UI/ImageHSVColor"
{
	Properties
	{
		_MainTex("Albedo (RGB)", 2D) = "white" {}
		_Brightness("Brightness", Float) = 1
		_Saturation("Saturation", Float) = 1
		_Contrast("Contrast", Float) = 1
	}

	SubShader
	{
		Blend SrcAlpha OneMinusSrcAlpha
		Pass
		{
			ZTest Always Cull Off ZWrite Off
			CGPROGRAM

			sampler2D _MainTex;
			half _Brightness;
			half _Saturation;
			half _Contrast;

			//vert和frag函数
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"

			//从vertex shader传入pixel shader的参数
			struct v2f
			{
				float4 pos : SV_POSITION; //顶点位置
				half2 uv : TEXCOORD0; //UV坐标
			};

			//vertex shader
			//appdata_img:带有位置和一个纹理坐标的顶点着色器输入

			v2f vert(appdata_img v)
			{
				v2f o;
				//从自身空间转向投影空间
				o.pos = UnityObjectToClipPos(v.vertex);
				//uv坐标赋值给output
				o.uv = v.texcoord;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				//从_MainTex中根据uv坐标进行采样
				fixed4 renderTex = tex2D(_MainTex, i.uv);
				//brigtness亮度直接乘以一个系数,也就是RGB整体缩放,调整亮度
				fixed4 finalColor = renderTex * _Brightness;
				//saturation饱和度:首先根据公式计算同等亮度情况下饱和度最低的值:
				fixed gray = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
				fixed4 grayColor = fixed4(gray, gray, gray, renderTex.a);
				//根据Saturation在饱和度最低的图像和原图之间差值
				finalColor = lerp(grayColor, finalColor, _Saturation);
				//contrast对比度:首先计算对比度最低的值
				fixed4 avgColor = fixed4(0.5, 0.5, 0.5, renderTex.a);
				//根据Contrast在对比度最低的图像和原图之间差值
				finalColor = lerp(avgColor, finalColor, _Contrast);
				//返回结果,alpha通道不变
				return fixed4(finalColor);
			}
			ENDCG
		}
	}
		FallBack Off
}

使用方式:

创建一个材质球,设置上面的shader文件。把材质球拖到所需调节的节点上,然后设置三个参数值,调节饱和度、亮度和色掉。

Shader "Custom/EnhancedHoloRoundedQuad" { Properties { [Header(基础设置)] _Color ("主颜色", Color) = (0.2, 0.8, 1.0, 1) _Radius ("圆角半径", Range(0,0.5)) = 0.1 [Header(发光设置)] _GlowColor ("辉光颜色", Color) = (0.5, 1.0, 1.0, 1) _GlowIntensity ("辉光强度", Range(1,10)) = 3 _NightGlowMultiplier ("夜间辉光倍增", Range(1,5)) = 3 [Header(动态效果)] _ScanSpeed ("扫描速度", Range(0,20)) = 8 _EdgeSpeed ("边缘流速", Range(0,5)) = 2.0 _NoiseScale ("噪波缩放", Range(0,1)) = 0.2 [Header(自发光)] _EmissionColor ("自发光颜色", Color) = (0,0.8,1,1) } float _EdgeSpeed, _NightGlowMultiplier; float4 _EmissionColor; SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent" } Blend SrcAlpha One 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; }; float4 _Color, _GlowColor; float _Radius, _ScanSpeed, _GlowIntensity, _NoiseScale; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } // 改进的SDF计算 float roundedBoxSDF(float2 uv, float radius) { uv = abs(uv * 2 - 1) - (1 - radius); float d = length(max(uv, 0)) + min(max(uv.x, uv.y), 0); return d - radius; } // 简单噪声函数 float noise(float2 uv) { return frac(sin(dot(uv, float2(12.9898,78.233))) * 43758.5453); } fixed4 frag (v2f i) : SV_Target { // 距离场计算保持不变 float d = roundedBoxSDF(i.uv, _Radius); // 辉光增强(3层叠加) float glowCore = saturate(1 - d / _Radius * 4); float glowMid = saturate(1 - d/_Radius * 2.5); float glowOuter = saturate(1 - d / _Radius * 1.5); float3 glow = (_GlowColor * pow(glowCore,8) + _GlowColor * pow(glowMid,4) * 0.8 + _GlowColor * pow(glowOuter,1.5) * 0.3) * _GlowIntensity * _NightGlowMultiplier; // 动态扫描线(带色相变化) float scanWave = sin(i.uv.y * 600 + _Time.y * _ScanSpeed * 10) * 0.2; float scanHue = frac(_Time.y * 0.3); float3 hsvColor = float3(scanHue, 0.8, 1); float3 scanColor = lerp(_GlowColor, hsv_to_rgb(hsvColor), 0.7); float scan = saturate(scanWave * (noise(i.uv*_NoiseScale) + 0.5) * 2); // 边缘流动(动态方向) float2 flowDir = float2(sin(_Time.y), cos(_Time.y*0.7)); float flow = sin(dot(i.uv, flowDir)*40 + _Time.y*_EdgeSpeed) * 0.15; // 自发光计算 float emission = pow(1 - alpha, 3) * _EmissionColor.a; // 最终合成(夜间增强版) float3 finalColor = _Color.rgb * alpha + // 基础色 glow * (1 - alpha) + // 三层辉光 scanColor * scan * 0.7 + // 变色扫描线 flow * _GlowColor.rgb * 2 + // 动态边缘流 _EmissionColor.rgb * emission; // 自发光 return fixed4(finalColor, saturate(alpha + length(glow)*0.5)); } ENDCG } } }我给复制成这样了,材质还是有错误
最新发布
03-22
Shader "Custom/EnhancedHoloRoundedQuad" { Properties { _Color ("主颜色", Color) = (0.2, 0.8, 1.0, 1) _Radius ("圆角半径", Range(0,0.5)) = 0.1 _GlowColor ("辉光颜色", Color) = (0.5, 1.0, 1.0, 1) _ScanSpeed ("扫描速度", Range(0,20)) = 8 _GlowIntensity ("辉光强度", Range(1,10)) = 3 _NoiseScale ("噪波缩放", Range(0,1)) = 0.2 } SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent" } Blend SrcAlpha One 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; }; float4 _Color, _GlowColor; float _Radius, _ScanSpeed, _GlowIntensity, _NoiseScale; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } // 改进的SDF计算 float roundedBoxSDF(float2 uv, float radius) { uv = abs(uv * 2 - 1) - (1 - radius); float d = length(max(uv, 0)) + min(max(uv.x, uv.y), 0); return d - radius; } // 简单噪声函数 float noise(float2 uv) { return frac(sin(dot(uv, float2(12.9898,78.233))) * 43758.5453); } fixed4 frag (v2f i) : SV_Target { // 精确距离场计算 float d = roundedBoxSDF(i.uv, _Radius); // 动态抗锯齿(根据屏幕分辨率自适应) float pixelSize = fwidth(d) * 1.5; float alpha = smoothstep(-pixelSize, pixelSize, -d); // 多层辉光叠加 float glowCore = saturate(1 - d / _Radius * 4); float glowOuter = saturate(1 - d / _Radius * 1.5); float3 glow = (_GlowColor * pow(glowCore, 6) + _GlowColor * pow(glowOuter, 2) * 0.5) * _GlowIntensity; // 动态扫描线(带噪声扰动) float scanWave = sin(i.uv.y * 600 + _Time.y * _ScanSpeed * 10) * 0.2; float scanNoise = noise(i.uv * _NoiseScale + _Time.x); float scan = saturate(scanWave * scanNoise + 0.5); // 边缘流动特效 float flow = sin((i.uv.x + i.uv.y) * 20 + _Time.y * 5) * 0.1; // 最终颜色合成 float3 finalColor = _Color.rgb * alpha; finalColor += glow * (1 - alpha); finalColor += scan * glow * 0.5; finalColor += flow * _GlowColor.rgb * (1 - alpha); return fixed4(finalColor, saturate(alpha + length(glow) * 0.5)); } ENDCG } } }这个材质在夜晚的时候没有高科技效果,我这个场景是夜晚,能优化一下吗
03-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值