Unity shaderlab 为 Shader 效果添加不透明度

问题描述 投票:0回答:0

提醒一下:我对着色器语言的经验很少,所以如果这是一个微不足道的问题,请原谅。

我从这个博客得到了一个 SoftLight 着色器:https://www.elopezr.com/photoshop-blend-modes-in-unity/
(存档:https://web.archive.org/web/20221218204941/https://www.elopezr.com/photoshop-blend-modes-in-unity/) 它使用 SoftLight 混合模式将给定的精灵混合在背景上,而不使用 GrabPass,因为我在不支持的地方使用 URP。

我想给它添加一个不透明度参数,这样我就可以调整叠加图像的强度和可见性,就像您在 Photoshop 中调整柔光层的不透明度一样。 我有一个附带的脚本,它通过 MaterialPropertyBlock 设置

_Opacity
的值。

但是我无法让它正常工作,颜色会变得过于饱和或太暗。

如何正确调整不透明度?

这是来源,评论的东西是我到目前为止所尝试的。

  1. 通过不透明度预乘源图像的 alpha 的新通道。
  2. 在混合之前乘以纹理的 alpha。
  3. 在最后一次传递中乘以纹理的 alpha(不知道具体是做什么的)。
Shader "PhotoShop/SoftLight" 
{
    Properties 
    {
        _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
        
        [HideInInspector] _Opacity("__opacity", Float) = 1.0
    }
    
    SubShader
    {       
        Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
        ZWrite Off Lighting Off Cull Off Fog{ Mode Off }
        LOD 110
        
//      Pass
//      {
//          BlendOp Add
//          Blend DstColor DstColor
//
//          CGPROGRAM
//          #pragma vertex vert
//          #pragma fragment frag
//          #pragma fragmentoption ARB_precision_hint_fastest
//          #include "UnityCG.cginc"
//
//          sampler2D _MainTex;
//
//          float _Opacity;
//          struct vin
//          {
//              float4 vertex : POSITION;
//              float2 texcoord : TEXCOORD0;
//              float4 color : COLOR;
//          };
//
//          struct v2f
//          {
//              float4 vertex : POSITION;
//              float2 texcoord : TEXCOORD0;
//              float4 color : COLOR;
//          };
//
//          v2f vert(vin v)
//          {
//              v2f o;
//              o.vertex = UnityObjectToClipPos(v.vertex);
//              o.texcoord = v.texcoord;
//              o.color = v.color;
//              return o;
//          }
//
//          fixed4 frag(v2f i) : COLOR
//          {   
//              float4 color = tex2D(_MainTex, i.texcoord);
//
//              color *= _Opacity;
//              return color;
//          }
//          
//          ENDCG
//      }

        Pass
        {
            BlendOp Add
            Blend DstColor DstColor

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float _Opacity;

            struct vin
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float4 color : COLOR;
            };

            struct v2f
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float4 color : COLOR;
            };

            v2f vert(vin v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = v.texcoord;
                o.color = v.color;
                return o;
            }

            fixed4 frag(v2f i) : COLOR
            {   
                float4 color = tex2D(_MainTex, i.texcoord);

                // color.a *= _Opacity;
                
                float3 desiredValue = 2.0 * color.rgb * color.a / (1.0 - 2.0 * color.rgb * color.a);
                float3 backgroundValue = (1.0 - color.a) / ((1.0 - 2.0 * color.rgb * color.a) * max(0.001, color.a));

                color.rgb = desiredValue + backgroundValue;
                return color;
            }
            
            ENDCG
        }

        Pass
        {
            BlendOp Add
            Blend DstColor Zero

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float _Opacity;

            struct vin
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float4 color : COLOR;
            };

            struct v2f
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float4 color : COLOR;
            };

            v2f vert(vin v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = v.texcoord;
                o.color = v.color;
                return o;
            }

            fixed4 frag(v2f i) : COLOR
            {   
                float4 color = tex2D(_MainTex, i.texcoord);
                color.rgb *= i.color.rgb;
                color.a *= i.color.a;// * _Opacity;
                color.rgb = (1.0 - 2.0 * color.rgb * color.a) * max(0.001, color.a);
                return color;
            }
            
            ENDCG
        }
    }
}

要混合的图像:

结果:

unity3d shader opacity fragment-shader urp
© www.soinside.com 2019 - 2024. All rights reserved.