Unity URPShader:实现和PS一样的色相/饱和度调整参数效果(修复)

目录

前言:

一、问题原因

二、算法修复

三、全代码


前言:

在之前的文章我已经实现了标题所述的内容功能:Unity URPShader:实现和PS一样的色相/饱和度调整参数效果-CSDN博客

但在偶然测试的时候,发现当采样的图片为白色或者是调整的颜色为白色时,会导致最终的画面渲染为黑色,今天对其进行修复。

一、问题原因

产生这样的原因在于颜色传入时,色相算法与饱和度算法计算出的颜色都是黑色,所以导致问题出错。回到PS后,在调节色相或者是饱和度时,其中白色依然不会改变,唯有亮度参数会对其进行效果改变。

二、算法修复

只需要判断输入的颜色是否时白色即可,以下时算法调整的地方:

复制代码
  half isWhite = saturate(floor(color.r * color.g * color.b));
                if (isWhite < 0.5)
                {
                    //Hue
                    half3 hsv = RGB2HSV(color.rgb);
                    hsv.x = frac(hsv.x + _Hue / 360.0);
                    color.rgb = HSV2RGB(hsv);
                    //Saturation
                    color.rgb = Saturation(color.rgb, _Saturation);
                }

三、全代码

复制代码
Shader "Background_Custom_HSV"
{
    Properties
    {
        _PatternTex ("贴图", 2D) = "black" { }
        [Header(BaseColor)]
        [Space]
        [HDR]_Color0 ("颜色", Color) = (1, 1, 1, 1)
 
        [Header(HSL)]
        [Space]
        _Hue ("Hue", Range(-180, 180)) = 0.0
        _Saturation ("Saturation", Range(-100, 100)) = 0.0
        _Lightness ("Lightness", Range(-100, 100)) = 0.0
 
    }
    SubShader
    {
        Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True" }
 
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
            Cull Back
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
 
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 
 
            TEXTURE2D(_PatternTex);
            SAMPLER(sampler_PatternTex);
 
            CBUFFER_START(UnityPerMaterial)
                half3 _Color0;
                float _Hue;
                float _Saturation;
                float _Lightness;
            CBUFFER_END
 
            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 texcoord : TEXCOORD0;
            };
 
            struct Varyings
            {
                float4 positionHS : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
 
     
            // RGB转HSV/HSB
            half3 RGB2HSV(half3 c)
            {
                half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
                half4 P = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
                half4 Q = lerp(half4(P.xyw, c.r), half4(c.r, P.yzx), step(P.x, c.r));
                half D = Q.x - min(Q.w, Q.y);
                half E = 1e-10;
                return half3(abs(Q.z + (Q.w - Q.y) / (6.0 * D + E)), D / (Q.x + E), Q.x);
            }
            
            // HSV/HSB转RGB
            half3 HSV2RGB(half3 c)
            {
                half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
                half3 P = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
                return c.z * lerp(K.xxx, saturate(P - K.xxx), c.y);
            }
 
 
            half3 Saturation(half3 color, float saturation)
            {
                half rgbMax = max(color.r, max(color.g, color.b));
                half rgbMin = min(color.r, min(color.g, color.b));
                half delta = rgbMax - rgbMin;
                // if (delta > 0)
                // {
                //     half value = rgbMax + rgbMin;
                //     half L = value * 0.5;
                //     half S = lerp(delta / value, delta / (2.0 - value), step(0.5, delta));
                //     half percent = saturation * 0.01;
                //     half alpha = 0;
                //     half3 final_color = 0;
                //     if (percent >= 0)
                //     {
                //         if (percent + S >= 1)
                //             alpha = S;
                //         else
                //             alpha = 1 - percent;
                //         alpha = 1 / alpha - 1;
                //         final_color = color + (color - half3(L, L, L)) * alpha;
                //     }
                //     else
                //     {
                //         alpha = percent;
                //         final_color = L + (color - half3(L, L, L)) * (1 + alpha);
                //     }
                
                //     return final_color;
                // }
                // else
                //     return color;
                half value = rgbMax + rgbMin;
                half L = value * 0.5;
                half S = lerp(delta / value, delta / (2.0 - value), step(0.5, delta));
                half percent = saturation * 0.01;
                half3 final_color = lerp(L + (color - L.xxx) * (1 + percent),
                color + (color - L.xxx) * (1.0 / (lerp(1.0 - percent, S, step(1.0, percent + S))) - 1.0),
                step(0.0, percent));
 
                final_color = lerp(color, final_color, ceil(delta));
                return final_color;
            }
            
            Varyings vert(Attributes v)
            {
                Varyings o;
                o.positionHS = TransformObjectToHClip(v.positionOS.xyz);
                o.uv = v.texcoord;
                return o;
            }
 
            half4 frag(Varyings i) : SV_Target
            {
                half4 color = SAMPLE_TEXTURE2D(_PatternTex, sampler_PatternTex, i.uv);
                color.rgb *= i.colors.rgb;

                half isWhite = saturate(floor(color.r * color.g * color.b));
                if (isWhite < 0.5)
                {
                    //Hue
                    half3 hsv = RGB2HSV(color.rgb);
                    hsv.x = frac(hsv.x + _Hue / 360.0);
                    color.rgb = HSV2RGB(hsv);
                    //Saturation
                    color.rgb = Saturation(color.rgb, _Saturation);
                }
                //Value
                half value = _Lightness * 0.01;
                // if (value > 0)
                //     color.rgb = (1 - value) * color.rgb + half3(1.0, 1.0, 1.0) * value;
                // else if (value < 0)
                //     color.rgb = color.rgb * (1.0 + value);
                color.rgb = lerp(color.rgb * (1.0 + value), lerp(color.rgb, half3(1.0, 1.0, 1.0), value), step(0.0, _Lightness));
                color.rgb = saturate(color.rgb);

                return color;
            }
            ENDHLSL
        }
    }
 
    FallBack "Hidden/Universal Render Pipeline/FallbackError"
}
相关推荐
bryant_meng10 小时前
【Game】Powerful——Pets(4.4)125~135
游戏·幻唐志·墨虎·贪狼·蚩尤武魂
bryant_meng12 小时前
【Game】Powerful——Pets(4.3)75~115
游戏·幻唐志·瑶光·赤炎童子·罗刹女
WarPigs12 小时前
Unity在Create菜单添加创建自定义脚本模板选项
unity
郝学胜-神的一滴15 小时前
C++ Templates 01:拨开迷雾,读懂C++模板经典著作
开发语言·c++·程序人生·游戏·游戏引擎·软件构建
Martina_032116 小时前
AI生成3D场景第一次进入总卡一下?用6步排查Shader编译、纹理上传与预加载
图像处理·人工智能·游戏·3d·ai·自然语言处理·游戏策划
淡海水16 小时前
02-01-原理篇-Mark-Sweep与变种算法
算法·unity·c#·游戏引擎·.net·gc
babywang017 小时前
Unity笔记--塔防游戏中的ECS架构:从原理到实战的全面解析
unity·ecs架构
茉莉玫瑰花茶18 小时前
OpenGL [ 纹理 ]
开发语言·c++·opengl
开开心心_Every19 小时前
文件夹批量创建工具支持同级和多层级
运维·服务器·游戏·jupyter·智能手机·pdf·postman
可爱系程序猿1 天前
键鼠都正常、只有手柄映射才提示 dinput8.dll?DirectInput 接口和游戏目录怎么对齐
程序人生·游戏·电脑