Вот сам шейдер с моими многозначущими комментариями, возможно я ошибся в понимании какой-то строки.
Синтаксис:
Используется glsl
Shader "Custom/3_Specular" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_SpecColor ("Specular color", Color)=(1,1,1,1)
_Shininess ("Shininess", Float)=10
}
SubShader {
Pass{
Tags {"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 _Color;
float4 _SpecColor;
float _Shininess;
uniform float4 _LightColor0;
struct vertexInput{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct vertexOutput{
float4 pos : SV_POSITION;
float4 col : COLOR;
float3 viewDir : COLOR1;
float3 normal : COLOR2;
};
vertexOutput vert(vertexInput v)
{
vertexOutput o;
o.normal = v.normal; // просто напросто нормалька
o.viewDir = normalize(_WorldSpaceCameraPos.xyz-v.vertex); // направление, в котором смотрит камера
//(по идее v.vertex нужно было бы перевести в мировые координаты при помощи mul(v.vertex, _Object2World), но работает и так)
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
float4 frag(vertexOutput o) : COLOR
{
float3 lightDirection=normalize(_WorldSpaceLightPos0.xyz); // нормализируем направление нашего Directional Light'a, можно и без нормализации, тоже робит
float3 diffuseReflection = _LightColor0.xyz * max(0.0, dot(o.normal, lightDirection)); // 1. получаем векторное произведение между вектором лучей света и нормалью. 2. Отсекаем значение меньше нуля. 3. Умножаем полученный вектор на цвет источника света
// diffuseReflection - это обычное освещение, без бликов
float3 specLight = max(0.0, dot(reflect(-lightDirection, o.normal), o.viewDir)); // 1. отражаем свет по нормальке (не совсем понятно, что там происходит, но общий смысл понятен). 2. Получаем векторное произведение между вектором взгляда и полученным вектором. То есть 1 будет тогда, когда мы смотрем прямо на отраженный вектор. 3. Отсекаем значение меньше нуля
// specLight - это уже чисто сам блик, и его месторасположение зависит от взора камеры и направления света
float3 specularReflection = diffuseReflection * pow(specLight,_Shininess); // 1. Возносим полученный блик в степень, шоб сильнее жарило. 2. Умножаем обычное освещение на полученный суперблик. Хз, зачем это.
float3 lightFinal = diffuseReflection + specularReflection*_SpecColor + UNITY_LIGHTMODEL_AMBIENT; // ну а тут мы тупо добавляем всё освещение
float4 color = float4(lightFinal * _Color,1.0); // и придаем ему еще нужный цвет
return color;
}
ENDCG
}
}
FallBack "Diffuse"
}
Properties {
_Color ("Color", Color) = (1,1,1,1)
_SpecColor ("Specular color", Color)=(1,1,1,1)
_Shininess ("Shininess", Float)=10
}
SubShader {
Pass{
Tags {"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 _Color;
float4 _SpecColor;
float _Shininess;
uniform float4 _LightColor0;
struct vertexInput{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct vertexOutput{
float4 pos : SV_POSITION;
float4 col : COLOR;
float3 viewDir : COLOR1;
float3 normal : COLOR2;
};
vertexOutput vert(vertexInput v)
{
vertexOutput o;
o.normal = v.normal; // просто напросто нормалька
o.viewDir = normalize(_WorldSpaceCameraPos.xyz-v.vertex); // направление, в котором смотрит камера
//(по идее v.vertex нужно было бы перевести в мировые координаты при помощи mul(v.vertex, _Object2World), но работает и так)
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
float4 frag(vertexOutput o) : COLOR
{
float3 lightDirection=normalize(_WorldSpaceLightPos0.xyz); // нормализируем направление нашего Directional Light'a, можно и без нормализации, тоже робит
float3 diffuseReflection = _LightColor0.xyz * max(0.0, dot(o.normal, lightDirection)); // 1. получаем векторное произведение между вектором лучей света и нормалью. 2. Отсекаем значение меньше нуля. 3. Умножаем полученный вектор на цвет источника света
// diffuseReflection - это обычное освещение, без бликов
float3 specLight = max(0.0, dot(reflect(-lightDirection, o.normal), o.viewDir)); // 1. отражаем свет по нормальке (не совсем понятно, что там происходит, но общий смысл понятен). 2. Получаем векторное произведение между вектором взгляда и полученным вектором. То есть 1 будет тогда, когда мы смотрем прямо на отраженный вектор. 3. Отсекаем значение меньше нуля
// specLight - это уже чисто сам блик, и его месторасположение зависит от взора камеры и направления света
float3 specularReflection = diffuseReflection * pow(specLight,_Shininess); // 1. Возносим полученный блик в степень, шоб сильнее жарило. 2. Умножаем обычное освещение на полученный суперблик. Хз, зачем это.
float3 lightFinal = diffuseReflection + specularReflection*_SpecColor + UNITY_LIGHTMODEL_AMBIENT; // ну а тут мы тупо добавляем всё освещение
float4 color = float4(lightFinal * _Color,1.0); // и придаем ему еще нужный цвет
return color;
}
ENDCG
}
}
FallBack "Diffuse"
}
Так вот я подумал - как бы мне сделать блик не таким разбавленным
А таким, чтобы прям был насыщенный красный цвет. Грубо говоря (1,0,0,1), но с fade out'ом. Ну, думаю, вот есть же строчка
Синтаксис:
Используется glsl
float3 specularReflection = diffuseReflection * pow(specLight,_Shininess);
По идее pow(specLight,_Shininess) - это и есть мой суперкрасный цвет, но только еще умноженный на себя какое-то количество раз, и вот мы его берем и умножаем на обычный diffuse, таким образом смешивая цвета, правда?
Ну я и убрал это умножение и получил
Синтаксис:
Используется glsl
float3 specularReflection =pow(specLight,_Shininess);
И да, вроде блик стал немного больше, но не полностью красным. А еще на задней стороне модельки появился артефактище.
Так почему же так?