2016-06-15 3 views
1

Я пытаюсь колебаться между двумя значениями внутри шейдера, чтобы достичь сияющего эффекта. Мне нужно, чтобы это было сделано внутри самого шейдера, а не с помощью сценариев на C#. Я попытался использовать значение _Time, что Unity дает нам шейдерной анимации, но он не работает:Колебание флюктуации в шейдере Unity

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" 
} 

Это делает свечение расти в бесконечность.

Что я делаю неправильно?

+0

Возможно, я ошибаюсь, но не _Time.y только прошедшее время с начала игры? если это так, то вы добавите/вычитаете растущие значения в _Glowpower. Подумайте, например, о сумме 1-2 + 3-4 + 5-6 + 7 и т. Д., Это идет к бесконечности. – TheDjentleman

+1

Вы пытались использовать _SinTime вместо _Time? Может быть, как '_GlowPower = 3 * _SinTime.y'. Я никогда не использовал его, но от имени я бы ожидал, что он вернет нечто вроде греха (время), которое колеблется между -1 и 1 – TheDjentleman

+0

Равномерные значения не работают. Вы не можете изменить '_UpDown' внутри вашего шейдера и ожидать, что он сохранит это значение для следующего исполнения шейдера. Похоже, что вы должны перенести этот код на сценарий и предоставить финальный '_GlowPower' в шейдер. – Quinchilion

ответ

1

немного Продление мой комментарий:

Вы не можете использовать _Time.y в этом случае, так как это время, прошедшее с момента начала игры, таким образом, она будет увеличиваться с течением времени.

Вместо этого вы можете использовать _SinTime.y, что представляет собой sin(_Time.y). Это означает, что колеблется между значениями -1 и 1. Вы можете использовать это и назначить (может быть уменьшенная версия _SinTime) к переменной: _GlowPower = C * _SinTime.y

Подробнее о Строить в шейдерных переменных: http://docs.unity3d.com/Manual/SL-UnityShaderVariables.html

0

Для ведения пульсирующее свечение ... Я бы сценарий «вне» шейдер и отправить в в параметре (_GlowPower) вычислить в C# сценарий, как это ....

glowPow = Mathf.Sin(time); 

Тогда вам нужно только вычислить его один раз , ЕСЛИ вы поместите его в шейдер VErtex ... он делает это один раз на вершину, и если его в поверхностном шейдере ... затем один раз на пиксель = производительность.

вы можете отправить переменные в свой шейдер, как это ... (очень удобно)

material.SetFloat(propertyName, valueToSend); 

Таким образом, вы можете отправить, время, силы, свечение или whatverer вы хотите.

Если вам действительно нужно сделать расчет тлеющий на вершине или на пиксель, а затем использовать

_glowPow = sin(_time); 

в затенении.

Смежные вопросы