Войти
ПрограммированиеФорумГрафика

Шейдер Unity показывающий радиус

#0
12:57, 25 апр. 2018

Пытаюсь освоить шедеры.
Решил попробовать сделать примерно такой шейдер показывающий радиус атаки.
Изображение

Вот что у меня получилось.
Изображение
Изображение
При разработки шейдера использовал Amplify Shader Editor для unity

Вот как выглядит список  нод.
Изображение

А теперь собственно сам вопрос.
1) Подскажите правильный ли я подход начал использовать при разработке шейдера? Если нет то подскажите более оптимальный способ  ?
2) Как изменять цвет черной области и добавить ей прозрачность?
3) Как добавить обводку черной области?
Спасибо.

Если кому нужен сам код.

Shader "New AmplifyShader"
{
  Properties
  {
    _Vector0("Vector 0", Vector) = (0,0,0,0)
    _TextureSample0("Texture Sample 0", 2D) = "white" {}
    _Color0("Color 0", Color) = (0.4068966,0,1,0)
    [HideInInspector] _texcoord( "", 2D ) = "white" {}
    [HideInInspector] __dirty( "", Int ) = 1
  }

  SubShader
  {
    Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" }
    Cull Back
    CGPROGRAM
    #pragma target 3.0
    #pragma surface surf Standard keepalpha addshadow fullforwardshadows 
    struct Input
    {
      float3 worldPos;
      float2 uv_texcoord;
    };

    uniform float3 _Vector0;
    uniform sampler2D _TextureSample0;
    uniform float4 _TextureSample0_ST;
    uniform float4 _Color0;

    void surf( Input i , inout SurfaceOutputStandard o )
    {
      float3 ase_worldPos = i.worldPos;
      float3 temp_output_5_0_g4 = ( ( ase_worldPos - ( _Vector0 - ase_worldPos ) ) / 10 );
      float dotResult8_g4 = dot( temp_output_5_0_g4 , temp_output_5_0_g4 );
      float clampResult10_g4 = clamp( dotResult8_g4 , 0 , 1 );
      float2 uv_TextureSample0 = i.uv_texcoord * _TextureSample0_ST.xy + _TextureSample0_ST.zw;
      o.Albedo = ( pow( clampResult10_g4 , 1000 ) * ( tex2D( _TextureSample0, uv_TextureSample0 ) * _Color0 ) ).rgb;
      o.Alpha = 1;
    }

    ENDCG
  }
  Fallback "Diffuse"
  CustomEditor "ASEMaterialInspector"
}


#1
14:34, 25 апр. 2018

Такой еффект обычно прожектором делают. Твой вариант - не оптимальный подход, большой филрейт, не оптимальный шейдер (dot, pow, ресампл uv на пиксельном)

#2
14:35, 25 апр. 2018

Если не хочешь прожекторы, а на всю сцену, то через post effect с использованием depth buffer

#3
19:07, 25 апр. 2018

Спасибо больше за помощь ))

#4
21:31, 25 апр. 2018

Столкнулся с такой вот проблемой. Для проектора тоже нужен шейдер.
Нашел в инете такой вот шейдер.
http://hyunkell.com/blog/rts-style-unit-selection-in-unity-5/

Shader "Projector/AdditiveTint" {
  Properties {
    _Color ("Tint Color", Color) = (1,1,1,1)
    _Attenuation ("Falloff", Range(0.0, 1.0)) = 1.0
    _ShadowTex ("Cookie", 2D) = "gray" {}
  }
  Subshader {
    Tags {"Queue"="Transparent"}
    Pass {
      ZWrite Off
      ColorMask RGB
      Blend SrcAlpha One // Additive blending
      Offset -1, -1

      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #include "UnityCG.cginc"
      
      struct v2f {
        float4 uvShadow : TEXCOORD0;
        float4 pos : SV_POSITION;
      };
      
      float4x4 unity_Projector;
      float4x4 unity_ProjectorClip;
      
      v2f vert (float4 vertex : POSITION)
      {
        v2f o;
        o.pos = UnityObjectToClipPos (vertex);
        o.uvShadow = mul (unity_Projector, vertex);
        return o;
      }
      
      sampler2D _ShadowTex;
      fixed4 _Color;
      float _Attenuation;
      
      fixed4 frag (v2f i) : SV_Target
      {
        // Apply tint & alpha mask
        fixed4 texCookie = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
        fixed4 outColor = _Color * texCookie.a;
        // Distance attenuation
        float depth = i.uvShadow.z; // [-1(near), 1(far)]
        return outColor * clamp(1.0 - abs(depth) + _Attenuation, 0.0, 1.0);
      }
      ENDCG
    }
  }
}

Проблема в том что он умножает свой цвет на цвет с которым он соприкасается. Не могу понять как от избавиться ((  Что бы везде цвет был одинаковый.

Изображение
#5
21:59, 25 апр. 2018

sg_afanasev
у тебя в последнем шейдере только 2 умножения на цвет. пошамань

#6
23:23, 25 апр. 2018

Эти два умножения как я понял отвечают за  цвет в инпекторе.

Изображение

А за смешивание цветов с поверхностью отвечает вот эта строчка
Blend SrcAlpha One
Попробовал различные параметры для нее цвет смешивается иначе но вот подходящего результата добиться не получается

#7
6:04, 26 апр. 2018
Изображение

Разобрался вроде бы смешивание больше не происходит.

Если кому не сложно посмотрите пожалуйста код шейдера может что подскажите по оптимизации.

Shader"Custom/DiffuseWithShadow"
{

  Properties {
    _Color ("Tint Color", Color) = (1,1,1,1)
    _Attenuation ("Falloff", Range(0.0, 1.0)) = 1.0
    _ShadowTex ("Cookie", 2D) = "gray" {}
  }
  Subshader {
    Tags {"Queue"="Transparent"}
    Pass {
      ZWrite Off
      ColorMask RGB
      Blend  One OneMinusSrcAlpha // Additive blending
      Offset -1, -1

      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #include "UnityCG.cginc"
      
      struct v2f {
        float4 uvShadow : TEXCOORD0;
        float4 pos : SV_POSITION;
      };
      
      float4x4 unity_Projector;
      float4x4 unity_ProjectorClip;
      
      v2f vert (float4 vertex : POSITION)
      {
        v2f o;
        o.pos = UnityObjectToClipPos (vertex);
        o.uvShadow = mul (unity_Projector, vertex);
        return o;
      }
      
      sampler2D _ShadowTex;
      fixed4 _Color;
      float _Attenuation;
      
      fixed4 frag (v2f i) : SV_Target
      {
        // Apply tint & alpha mask
        fixed4 texCookie = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
        fixed4 outColor = _Color * texCookie.a;
        // Distance attenuation
        float depth = i.uvShadow.z; // [-1(near), 1(far)]
        return outColor * clamp(1.0 - abs(depth) + _Attenuation, 0.0, 1.0);
      }
      ENDCG
    }
  }

}

ПрограммированиеФорумГрафика

Тема в архиве.