【问题标题】:Fluctuate float value in an Unity shaderUnity着色器中的浮动浮点值
【发布时间】:2017-03-10 14:14:12
【问题描述】:

我试图在着色器内的两个值之间波动以实现发光效果。 我需要它在着色器本身内部完成,而不是通过 C# 脚本。 我尝试使用 Unity 为着色器动画提供的 _Time 值,但它不起作用:

Shader "Test shader" {
Properties {
    _ColorTint ("Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB)", 2D) = "white" {}
    _GlowColor("Glow Color", Color) = (1,0,0,1)
    _GlowPower("Glow Power", Float) = 3.0
    _UpDown("Shine Emitter Don't Change", Float) = 0
}
SubShader {
    Tags { 
        "RenderType"="Opaque" 
    }

    CGPROGRAM
    #pragma surface surf Lambert

    struct Input {
            float4 color : Color;
            float2 uv_MainTex;
            float3 viewDir;
            float4 _Time;
    };

    float4 _ColorTint;
    sampler2D _MainTex;
    float4 _GlowColor;
    float _GlowPower;
    float _UpDown;

    void surf(Input IN, inout SurfaceOutput o) {
        if (_UpDown == 0) {
            _GlowPower += _Time.y;
        }
        if (_UpDown == 1) {
            _GlowPower -= _Time.y;
        }
        if (_GlowPower <= 1) {
            _UpDown = 0;
        }
        if (_GlowPower >= 3) {
            _UpDown = 1;
        }

        IN.color = _ColorTint;
        o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * IN.color;
        half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
        o.Emission = _GlowColor.rgb * pow(rim, _GlowPower);
    }
    ENDCG
}
FallBack "Diffuse"
}

这使得光芒无限增长。

我做错了什么?

【问题讨论】:

  • 我可能错了,但_Time.y不就是游戏开始后经过的时间吗?如果是这样,那么您将为 _Glowpower 添加/减去不断增长的值。例如,总和 1-2+3-4+5-6+7 等等,这是走向无穷大
  • 您是否尝试过使用 _SinTime 而不是 _Time?也许像_GlowPower=3*_SinTime.y。我从未使用过它,但从名字上我希望它会返回类似 sin(time) 的东西,它在 -1 和 1 之间振荡
  • 统一值不能这样工作。您不能在着色器中更改 _UpDown 并期望它为下一次着色器执行保留该值。听起来您应该将此代码移动到脚本中,并且只将最终的 _GlowPower 提供给着色器。
  • @xyLe_ 非常感谢,这有帮助:)

标签: unity3d shader cg


【解决方案1】:

稍微扩展我的评论:

在这种情况下你不能使用_Time.y,因为它是游戏开始后经过的时间,因此它会随着时间的推移而增加。

您可以改用_SinTime.y,它代表sin(_Time.y)。这意味着它在值 -1 和 1 之间波动。您可以使用它并将(可能是 _SinTime 的缩放版本)分配给您的变量:_GlowPower = C * _SinTime.y

更多关于内置着色器变量:http://docs.unity3d.com/Manual/SL-UnityShaderVariables.html

【讨论】:

    【解决方案2】:

    为了做一个脉冲发光...我会在着色器“外部”有一个脚本,并在 c# 脚本中发送一个参数 (_GlowPower) 计算,如下所示...。

    glowPow = Mathf.Sin(time);
    

    那么你只需要计算一次。如果你把它放在顶点着色器中……它每个顶点执行一次,如果它在表面着色器中……那么每个像素一次 = 性能浪费。

    您可以像这样将变量发送到您的着色器...(非常方便)

    material.SetFloat(propertyName, valueToSend);
    

    所以你可以发送,时间,力量,发光或任何你想要的。

    如果你真的需要对每个顶点或每个像素进行辉光计算,那么使用

    _glowPow = sin(_time);
    

    在着色器内部。

    【讨论】:

      猜你喜欢
      • 2012-02-21
      • 2013-02-22
      • 2012-07-15
      • 2013-08-01
      • 2021-03-31
      • 1970-01-01
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多