Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
t0, t1, t2 можно считать на CPU раз за кадр для каждого щита в скрипте. Тем самым можно убрать 3 saturate и кучу вычислений.
Shader "CS/Shield"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Tint ("Tint color", Color) = (1,1,1,1)
_Width ("Width", Range(0.0, 1.0)) = 0.7
_HdrPower ("HDR Power", Float) = 5.0
_DoubleSided ("Double Sided", Float) = 0.0
}
SubShader
{
Tags
{
"RenderType"="Transparent"
"Queue"="Transparent+100"
}
LOD 100
Blend One One
Cull [_DoubleSided]
ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
fixed4 rim : TEXCOORD1;
};
sampler2D _MainTex;
fixed4 _MainTex_ST;
fixed4 _Tint;
fixed _Width;
fixed _HdrPower;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// rim
fixed3 viewDir =
normalize(ObjSpaceViewDir(v.vertex));
fixed dotRes =
1.0 - abs(dot(viewDir, v.normal));
o.rim = _Tint * _HdrPower *
smoothstep(1.0 - _Width, 1.0, dotRes);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col * i.rim;
}
ENDCG
}
}
}

Здесь v2f — возвращаемое значение вершинных шейдеров интерполированное для данного пикселя на экране
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
uv — текстурная координата пикселя
vertext — координата пикселя в экранных координатах
Названо не у меня, а у Unity, переименовывать я не стал.
uv это координаты текселя
Для данного пикселя/фрагмента, вычисляемая из uv-координат присвоенных вершинам, по которым может взяться, а может и не взяться, семпл из текстуры.
Уж, простите, но различие между фрагментом и пикселем я в этом контексте считаю буквоедством.
I — направление на камеру в мировых координатах — можно посчитать, как разницу мировых координат камеры и мировых координат вершины.Такая формулировка противоречит формуле, ведь I это вектор от камеры к вершине.
float3 I = normalize(worldVertex - _WorldSpaceCameraPos.xyz);
float4 a;
float3 b;
float3 c = normalize(a - b);Вы молодец, но сам спецэффект выглядит не очень. Возможно в другом масштабе хорошо смотрится. Игроки нынче избалованны эффектами в ааа играх 8)
float hitIntensity = (1 - t0) * ((1 / (d0)) - 1) +
(1 - t1) * ((1 / (d1)) - 1) +
(1 - t2) * ((1 / (d2)) - 1);
Анимированный эффект щита космического корабля в Unity3D