unity-game-engine - 力场着色器展开纹理不起作用

标签 unity-game-engine glsl hlsl

我从某个地方得到了这个着色器,我忘记了,默认情况下仅使用纯色来达到效果。所以我尝试修改它以使其也支持盾牌纹理。

Shader "TFTM/FX/Shield2" {
     Properties {
         _Position ("Collision", Vector) = (-1, -1, -1, -1)        
         _MaxDistance ("Effect Size", float) = 40        
         _ShieldColor ("Color (RGBA)", Color) = (0.7, 1, 1, 0)
         _EmissionColor ("Emission color (RGBA)", Color) = (0.7, 1, 1, 0.01)        
         _EffectTime ("Effect Time (ms)", float) = 0
         _MainTex ("Texture (RGB)", 2D) = "white" {}
     }

 SubShader {
     Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
     LOD 2000
     Cull Off

     CGPROGRAM
       #pragma surface surf Lambert vertex:vert alpha
       #pragma target 3.0

      struct Input {
          float customDist;
          float2 uv_MainTex;
       };

       sampler2D _MainTex;
       float4 _Position;          
       float _MaxDistance;          
       float4 _ShieldColor;
       float4 _EmissionColor;          
       float _EffectTime;

       float _Amount;

       void vert (inout appdata_full v, out Input o) {
           o.customDist = distance(_Position.xyz, v.vertex.xyz);
           o.uv_MainTex = v.texcoord;
       }

       void surf (Input IN, inout SurfaceOutput o) {
         o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;//_ShieldColor.rgb;
         o.Emission = _EmissionColor;

         if(_EffectTime > 0)
         {
             if(IN.customDist < _MaxDistance){
                   o.Alpha = _EffectTime/500 - (IN.customDist / _MaxDistance) + _ShieldColor.a;
                   if(o.Alpha < _ShieldColor.a){
                       o.Alpha = _ShieldColor.a;
                   }
               }
               else {
                   o.Alpha = _ShieldColor.a;
               }
           }
           else{
               o.Alpha = o.Alpha = _ShieldColor.a;
           }
       }

       ENDCG
 } 
 Fallback "Transparent/Diffuse"
}

我在这里用纹理替换颜色

o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;//_ShieldColor.rgb;

但它不起作用,它显示为一种单一颜色,而不是周围的纹理。

enter image description here enter image description here

最佳答案

问题出在 o.Aplha 上。在您发布的着色器中,无论纹理如何,surf都会返回Alpha,因此您需要更改surf方法以根据纹理设置输出Alpha。

可以这样做:

1) 替换

o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;//_ShieldColor.rgb;

// Read texture and set it to vector4
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;

2) 插入

o.Alpha *= c.a;

之后

else {
    o.Alpha = o.Alpha = _ShieldColor.a;
}

结果看起来像这样:

enter image description here

完整的结果着色器代码:

Shader "TFTM/FX/Shield2" {
    Properties {
        _Position("Collision", Vector) = (-1, -1, -1, -1)
        _MaxDistance("Effect Size", float) = 40
        _ShieldColor("Color (RGBA)", Color) = (0.7, 1, 1, 0)
        _EmissionColor("Emission color (RGBA)", Color) = (0.7, 1, 1, 0.01)
        _EffectTime("Effect Time (ms)", float) = 0
        _MainTex("Texture (RGB)", 2D) = "white" {}
    }

    SubShader {
        Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
        LOD 2000
        Cull Off

    CGPROGRAM
    #pragma surface surf Lambert vertex:vert alpha
    #pragma target 3.0

    struct Input {
        float customDist;
        float2 uv_MainTex;
    };

    sampler2D _MainTex;
    float4 _Position;
    float _MaxDistance;
    float4 _ShieldColor;
    float4 _EmissionColor;
    float _EffectTime;

    float _Amount;

    void vert(inout appdata_full v, out Input o) {
        o.customDist = distance(_Position.xyz, v.vertex.xyz);
        o.uv_MainTex = v.texcoord;
    }

    void surf(Input IN, inout SurfaceOutput o) {
        half4 c = tex2D(_MainTex, IN.uv_MainTex);
        o.Albedo = c.rgb;//_ShieldColor.rgb;
        o.Emission = _EmissionColor;

        if (_EffectTime > 0)
        {
            if (IN.customDist < _MaxDistance) {
                o.Alpha = _EffectTime / 500 - (IN.customDist / _MaxDistance) + _ShieldColor.a;
                if (o.Alpha < _ShieldColor.a) {
                    o.Alpha = _ShieldColor.a;
                }
            }
            else {
                o.Alpha = _ShieldColor.a;
            }
        }
        else {
            o.Alpha = o.Alpha = _ShieldColor.a;
        }
        o.Alpha *= c.a;
    }

    ENDCG
    }
    Fallback "Transparent/Diffuse"
}

关于unity-game-engine - 力场着色器展开纹理不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41456478/

相关文章:

c++ - 片段着色器中的 GLSL 翻译未按预期工作

c++ - GLSL C++ glVertexAttribPointer & glDrawElements 返回 GL_INVALID_OPERATION

arrays - 将数组从 HLSL 顶点着色器传递到像素着色器

c# - 让玩家自由旋转游戏对象

javascript - 在接近零之前,我可以将一个数字乘以小数/分数多少次

android - 无法从 firebase 存储下载和实例化 3d 模型到统一

c++ - 如何在 Visual Studio 2017 中启动 HLSL 调试器?

ios - unity IOS firebase 处理前台推送通知

c++ - 二维 GLSL 渲染

c++ - 在 DirectX 中将 uint 打包和解包到 float4