View
60
Download
0
Category
Preview:
DESCRIPTION
Визуальные эффекты на GPU Стандартные модели освещения - Гуро. 1. Падающий равномерно рассеивается по всем направлением верхней полусферы 2. Энергия, уходящая в заданном направлении пропорциональна только плотности световой энергии, падающей в данную точку. - PowerPoint PPT Presentation
Citation preview
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели освещения - ГуроСтандартные модели освещения - Гуро
l
P
1. Падающий равномерно рассеивается по всем направлением верхней полусферы
2. Энергия, уходящая в заданном направлении пропорциональна только плотности световой энергии, падающей в данную точку
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели освещения - диффузнаяСтандартные модели освещения - диффузная
v
n
P
l
n - вектор нормали в точке Рv - вектор на наблюдателяl - вектор на источник света
lnIkkCC lightdasurfres ,,0max
Уравнение освещенности:
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели - освещение по БлиннуСтандартные модели - освещение по Блинну
v
n
P
l
h
Уравнение освещенности:
plightslightdasurfres hnIklnIkkCC ,,0max,,0max
vl
vlh
h - бисектор векторов l и v
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели - освещение по БлиннуСтандартные модели - освещение по Блинну
surfC
ak
sk
lightI
dk
p
- цвет поверхности
- цвет источника света
- вклад фонового освещения
- вклад диффузной освещенности
- вклад бликовой освещенности
- гладкость поверхности
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели - освещение по БлиннуСтандартные модели - освещение по Блинну
struct VertexData{ float4 pos : POSITION; float2 texCoord : TEXCOORD0; float3 n : NORMAL; };
struct FragmentData{ float4 pos : POSITION; float2 texCoord : TEXCOORD0; float3 n; float3 l; float3 h; float3 v;};
Вход вершинной программы
Вход фрагментной программы
Визуальные эффекты на Визуальные эффекты на GPUGPUОсвещение по Блинну. Вершинная программаОсвещение по Блинну. Вершинная программа
FragmentData main ( VertexData IN, uniform float4 lightPos, uniform float4 eyePos, uniform float4x4 mvp, uniform float4x4 mv, uniform float4x4 mvi ){ FragmentData OUT;
float3 p = mul ( mv, IN.pos ).xyz;
OUT.n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; OUT.l = normalize ( lightPos.xyz - p ); OUT.v = normalize ( eyePos.xyz - p ); OUT.h = normalize ( OUT.l + OUT.v ); OUT.pos = mul ( mvp, IN.pos ); OUT.texCoord = IN.texCoord;
return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUОсвещение по Блинну. Фрагментная программаОсвещение по Блинну. Фрагментная программа
float4 main ( FragmentData IN ) : COLOR{ const float4 diffColor = float4 ( 0.5, 0.0, 0.0, 1.0 ); const float4 specColor = float4 ( 0.7, 0.7, 0.0, 1.0 ); const float specPower = 30.0;
float3 n2 = normalize ( IN.n ); float3 l2 = normalize ( IN.l ); float3 h2 = normalize ( IN.h ); float4 diff = diffColor * max ( dot ( n2, l2 ), 0.0 ); float4 spec = specColor * pow ( max ( dot ( n2, h2 ), 0.0 ), specPower );
return diff + spec;}
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели - освещение по ФонгуСтандартные модели - освещение по Фонгу
vn
P
l
rr - отражение вектора v относительно нормали n
Уравнение освещенности:
plightslightdasurfres rlIklnIkkCC ,,0max,,0max
Визуальные эффекты на Визуальные эффекты на GPUGPUСтандартные модели - освещение по ФонгуСтандартные модели - освещение по Фонгу
Визуальные эффекты на Визуальные эффекты на GPUGPUОсвещение по Фонгу. Вершинная программаОсвещение по Фонгу. Вершинная программа
FragmentData main ( VertexData IN, uniform float4 lightPos, uniform float4 eyePos, uniform float4x4 mvp, uniform float4x4 mv, uniform float4x4 mvi ){ FragmentData OUT;
float3 p = mul ( mv, IN.pos ).xyz;
OUT.n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; OUT.l = normalize ( lightPos.xyz - p ); OUT.v = normalize ( eyePos.xyz - p ); OUT.pos = mul ( mvp, IN.pos ); OUT.texCoord = IN.texCoord;
return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUОсвещение по Фонгу. Фрагментная программаОсвещение по Фонгу. Фрагментная программа
float4 main ( FragmentData IN ) : COLOR{ const float4 diffColor = float4 ( 0.5, 0.0, 0.0, 1.0 ); const float4 specColor = float4 ( 0.7, 0.7, 0.0, 1.0 ); const float specPower = 30.0;
float3 n2 = normalize ( IN.n ); float3 l2 = normalize ( IN.l ); float3 v2 = normalize ( IN.v ); float3 r = reflect ( -v2, n2 ); float4 diff = diffColor * max ( dot ( n2, l2 ), 0.0 ); float4 spec = specColor * pow ( max ( dot ( l2, r ), 0.0 ), specPower );
return diff + spec;}
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
При использовании описанных моделей освещения поверхности получаются слишком гладкимиХочется добавить микрорельеф, не изменяя при этом саму геометрию объектов
Попробуем просто в каждой точке отклонять вектор нормали.Тогда изменится освещенность в точке и создастся иллюзия микрорельефа
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
n
n
nn 'n '
n '
n - истинный вектор нормали
n’ - искаженный вектор нормали
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
Результат искажения нормалей - при рендеринге обычного тора было произведено искажение векторов нормали
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
? - в каком пространстве задавать искажения вектора нормали n
! - будем задавать в искажения вектора (точнее, сам вектор нормали n) в пространстве “приклеенном” к выводимой грани
t
b
n
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
Для каждой грани определим следующие попарно ортогональных единичных вектора
t
b
n
t - касательный вектор к граниn - нормаль граниb - бинормаль (b = [n,t])
Эта тройка векторов образует ортонормированный базис в пространстве и, соответственно, систему координат, называемую касательной (tangent space)
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
Как кодировать искажения нормали - переведем единичный вектор нормали (в касательном пространстве) в цвет и поместим в текстуру
Неискаженная нормаль в касательном пространстве всегда равна n=(0,01)
)1(5.0
),1(5.0
),1(5.0
z
y
x
nb
ng
nr
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmappingBumpmapping
Вершинная программа:• вычислить вектора l, v, h (или r) • перевести их в касательное пространство• передать фрагментной программе вычисленные вектора и текстурные координаты
Фрагментная программа:• нормировать вектора l, v, h (или r)• взять из карты нормалей нормаль• перевести нормаль из RGB-представления• вычислить освещенность с использованием полученного вектора нормали и векторов l, v, h (или r)
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmapping - Bumpmapping - передаваемые данныепередаваемые данные
struct VertexData{ float4 pos : POSITION; float2 texCoord : TEXCOORD0; float3 n : NORMAL; float3 t : TEXCOORD1; float3 b : TEXCOORD2;};
struct FragmentData{ float4 pos : POSITION; float2 texCoord : TEXCOORD0; float3 lt; float3 ht;};
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmapping - вершинная программаBumpmapping - вершинная программа
FragmentData main ( VertexData IN, uniform float4 lightPos, uniform float4 eyePos, uniform float4x4 mvp, // modelview*projection
uniform float4x4 mv, // modelview uniform float4x4 mvi ) { FragmentData OUT; float3 p = mul ( mv, IN.pos ).xyz; float3 l = normalize ( lightPos.xyz - p ); float3 v = normalize ( eyePos.xyz - p ); float3 h = l + v; float3 n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; float3 t = mul ( mvi, float4 ( IN.t, 0 ) ).xyz; float3 b = mul ( mvi, float4 ( IN.b, 0 ) ).xyz;
OUT.pos = mul ( mvp, IN.pos ); OUT.texCoord = IN.texCoord; OUT.lt = float3 ( dot ( l, t ), dot ( l, b ), dot ( l, n ) ); OUT.ht = float3 ( dot ( h, t ), dot ( h, b ), dot ( h, n ) ); return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUBumpmapping - фрагментная программаBumpmapping - фрагментная программа
float4 main ( FragmentData IN, uniform sampler2D bumpMap, uniform sampler2D diffuseMap ) : COLOR{
const float4 specColor = float4 ( 1, 1, 1, 1 );
float3 n = tex2D ( bumpMap, IN.texCoord ).xyz;float3 nt = normalize ( 2.0*n - 1.0 );float3 l2 = normalize ( IN.lt );float3 h2 = normalize ( IN.ht );float diff = max ( dot ( nt, l2 ), 0.0 ) + 0.2;float spec = pow ( max ( dot ( nt, h2 ), 0.0 ), 30.0 );
return diff * tex2D ( diffuseMap, IN.texCoord ) + spec * specColor;
}
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
Поворот вокруг вектора нормали не изменяет векторов l и v, поэтому ранее рассмотренные модели освещения не зависят от подобных поворотов
Однако встречаются поверхности, для это свойство не выполняется (поверхность CD, полированный металл).Такие поверхности называются анизотропными
l
n
v
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
t
t
tn
nn
Проще всего моделировать такие поверхности, считая их состоящими из множества ориентированных бесконечно-тонких нитей.Тогда в каждой точке поверхности можно задать касательный t вектор к такой нити, т.е. на поверхности объекта возникает поле касательных векторов t (P)
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
t
n
l
nl
tl
? - как освещать подобную нить, ведь для нее неоднозначно определен вектор нормали n
! - рассмотрим диффузную и бликовую составляющие раздельно и для каждой из них выберем такой вектор n (ортогональный вектору t), максимизирующий соответствующую компоненту освещенности
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
Разложим вектор l на ортогональные части:
tnntl **,
Умножим скалярно на t и найдем параметры разложения
2**2*
*
,1,
,
,,
tlnnn
ttlln
tl
Легко убедиться, что максимум (l,n) достигается на следующем векторе:
2
*
*
*
,1 tl
n
n
n
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
Таким образом получаем следующее уравнение освещенности для анизотропной поверхности:
2
5.0
,1
,1p
lights
lightdasurfres
thIk
tlIkkCC
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
Передаваемые данныеПередаваемые данныеstruct VertexData{ float4 pos : POSITION; float2 texCoord : TEXCOORD0; float3 n : NORMAL; float3 t : TEXCOORD1; float3 b : TEXCOORD2;};
struct FragmentData{ float4 pos : POSITION; float2 texCoord : TEXCOORD0; float3 lt; float3 ht;};
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещения. Анизотропные модели освещения.
Вершинная программаВершинная программаFragmentData main ( VertexData IN, uniform float4 lightPos, uniform float4 eyePos,
uniform float4x4 mvp, uniform float4x4 mv, uniform float4x4 mvi )
{ FragmentData OUT; float3 p = mul ( mv, IN.pos ).xyz; float3 l = normalize ( lightPos.xyz - p ); float3 v = normalize ( eyePos.xyz - p ); float3 h = normalize ( l + v ); float3 n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; float3 t = mul ( mvi, float4 ( IN.t, 0 ) ).xzy; float3 b = mul ( mvi, float4 ( IN.b, 0 ) ).xyz;
OUT.lt = float3 ( dot ( l, t ), dot ( l, b ), dot ( l, n ) ); OUT.ht = float3 ( dot ( h, t ), dot ( h, b ), dot ( h, n ) ); OUT.pos = mul ( mvp, IN.pos ); OUT.texCoord = IN.texCoord; return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUАнизотропные модели освещенияАнизотропные модели освещения
Фрагментная программаФрагментная программаfloat4 main ( FragmentData IN, uniform sampler2D tangentMap, uniform sampler2D decalMap, uniform sampler2D anisoMap ) : COLOR{ const float3 specColor = float3 ( 0, 0, 1 );
float3 tang = normalize ( 2*tex2D( tangentMap, IN.texCoord ).xyz-1); float dot1 = dot ( normalize ( IN.lt ), tang ); float dot2 = dot ( normalize ( IN.ht ), tang ); float2 arg = float2 ( dot1, dot2 ); float2 ds = tex2D ( anisoMap, arg*arg ).xy; float3 color = tex2D ( decalMap, IN.texCoord ).xyz;
return float4 ( color * ds.x + specColor * ds.y, 1.0 );}
Визуальные эффекты на Визуальные эффекты на GPUGPUМодель Уорда (Ward)Модель Уорда (Ward)
Простейший вид модели освещения Уорда:
nh
thkIkkCC lightsasurfres ,
,exp
k - гладкость поверхности
t - касательный вектор
h - бисектор векторов l и v
Визуальные эффекты на Визуальные эффекты на GPUGPUМодель Уорда (Ward)Модель Уорда (Ward)
Фрагментная программаФрагментная программаfloat4 main ( FragmentData IN, uniform sampler2D tangentMap, uniform sampler2D decalMap ) : COLOR{ const float4 specColor = float4 ( 0, 0, 1, 0 ); const float3 n = float3 ( 0, 0, 1 ); const float roughness = 5.0;
float4 color = tex2D ( decalMap, IN.texCoord ); float3 tang = normalize ( 2*tex2D ( tangentMap, IN.texCoord ).xyz-1 ); float dot1 = dot ( IN.ht, tang ) * roughness; float dot2 = dot ( IN.ht, n ); float p = dot1 / dot2;
return float4 ( color.rgb + specColor.rgb * exp ( -p*p ), 1 );}
Визуальные эффекты на Визуальные эффекты на GPUGPUМоделирование преломленияМоделирование преломления
n
v
r
t
Визуальные эффекты на Визуальные эффекты на GPUGPUМоделирование преломленияМоделирование преломления
! - используем встроенную функцию refract для нахождения преломленного вектора и по этому вектору возьмем значение из кубической карты отражения.
const float eta = 0.9;// Find reflection/refraction vectors
float3 en = normalize ( IN.e ); float3 nn = normalize ( IN.n ); float3 r = reflect ( en, nn ); float3 t = refract ( en, nn, eta );
// Do a lookup into the environment map float3 envColor = texCUBE ( envMap, r ).xyz; float3 refractionColor = texCUBE ( envMap, t ).xyz;
Визуальные эффекты на Визуальные эффекты на GPUGPUМоделирование преломления - учет длины волныМоделирование преломления - учет длины волны
Визуальные эффекты на Визуальные эффекты на GPUGPUМоделирование преломления - учет длины волныМоделирование преломления - учет длины волны
! - функция refract зависит также и от коэффициента преломления eta. Данный коэффициент зависит от длины волны. Поэтому возьмем три коэффициента преломления (по одному для каждой цветовой компоненты), найдем преломленный вектор и соответствующий цвет.Из каждого из трех полученных цветов возьмем по одной цветовой компоненте (соответствующей длине волны) и построим из них новый цвет.
n
v
r
redt
bluetgreent
Визуальные эффекты на Визуальные эффекты на GPUGPUСвечение (glow)Свечение (glow)
Визуальные эффекты на Визуальные эффекты на GPUGPUСвечение (glow)Свечение (glow)
Нарисовать светящийся объект в текстуру
Применить «размытие» к этой текстуре
Нарисовать всю сцену
Наложить на изображение сцены размытую текстуру
Визуальные эффекты на Визуальные эффекты на GPUGPUДифракцияДифракция
Визуальные эффекты на Визуальные эффекты на GPUGPUДифракцияДифракция
d
v
vn n
l
l
A B
C
Разность фаз можно приближенно записать как du, где u= sin 1 - sin 2.Если эта разница кратна длине волны, то происходит усиление света, в противном случае - ослабевание.
Визуальные эффекты на Визуальные эффекты на GPUGPUДифракция. Вершинная программа.Дифракция. Вершинная программа.
FragmentData main ( VertexData IN, uniform float4 lightPos, uniform float4 eyePos, uniform float4x4 mvp, uniform float4x4 mv, uniform float4x4 mvi ){ FragmentData OUT; float3 p = mul ( mv, IN.pos ); float3 l = normalize ( lightPos.xyz - p ); float3 v = normalize ( eyePos.xyz - p ); float3 h = normalize ( l + v ); float3 n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; float3 t = mul ( mvi, float4 ( IN.t, 0 ) ).xzy; float3 b = mul ( mvi, float4 ( IN.b, 0 ) ).xyz;
OUT.lt = float3 ( dot ( l, t ), dot ( l, b ), dot ( l, n ) ); OUT.ht = float3 ( dot ( h, t ), dot ( h, b ), dot ( h, n ) ); OUT.vt = float3 ( dot ( v, t ), dot ( v, b ), dot ( v, n ) ); OUT.pos = mul ( mvp, IN.pos ); OUT.texCoord = IN.texCoord; return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUДифракция. Фрагментная программа.Дифракция. Фрагментная программа.
float4 main ( FragmentData IN, uniform sampler2D tangentMap, uniform sampler2D decalMap, uniform sampler1D rainbowMap ) : COLOR{ const float3 specColor = float3 ( 0, 0, 1 ); const float3 n = float3 ( 0, 0, 1 ); const float roughness = 30.0; const float d = 40.0; float3 tang = normalize ( 2*tex2D(tangentMap, IN.texCoord).xyz-1); float u = dot ( IN.ht, tang ); float w = dot ( IN.ht, n ); float e = roughness * u / w; float3 color = float3 ( 0, 0, 0 ); float u1 = d * abs ( u );
for ( int n = 1; n <= 8; n++ )color += tex1D ( rainbowMap, u1 / float ( n ) ).rgb;
return float4 ( specColor * exp ( -e*e ) + color * 0.25, alpha );}
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг мехаРендеринг меха
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг мехаРендеринг меха
Слои 1, 2, 3 и т.д.
Текстура
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг мехаРендеринг меха
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг мехаРендеринг меха
Модель освещения - анизотропная (для волосков)Вершинный шейдер - сдвинуть вершины для слоя и подготовить все величины для расчета освещенностиФрагментный шейдер - непосредственно расчет освещенности
n
po s
pos+n*d
pos+n*2*d
pos+n*3*d
Вершинная программа также обеспечивает перенос вершин для очередного слоя и анимацию меха путем изменения текстурных координат в зависимости от времени
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг меха. Вершинная программаРендеринг меха. Вершинная программа
FragmentData main ( VertexData IN, uniform float tl, uniform float time, uniform float4 lightPos, uniform float4 eyePos, uniform float4x4 mvp, uniform float4x4 mv, uniform float4x4 mvi ) { FragmentData OUT; float4 pp = IN.pos + tl * float4 ( IN.n, 0 ); float3 p = mul ( mv, pp ).xyz; float3 l = normalize ( lightPos.xyz - p ); float3 v = normalize ( eyePos.xyz - p ); float3 h = l + v; float3 n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; float3 t = mul ( mvi, float4 ( IN.t, 0 ) ).xyz; float3 b = mul ( mvi, float4 ( IN.b, 0 ) ).xyz; OUT.pos = mul ( mvp, pp ); OUT.texCoord = IN.texCoord + float2 ( 0, 0.02 * sin ( time ) * tl ); OUT.color = IN.color; OUT.lt = float3 ( dot ( l, t ), dot ( l, b ), dot ( l, n ) ); OUT.ht = float3 ( dot ( h, t ), dot ( h, b ), dot ( h, n ) ); return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг меха. Фрагментная программаРендеринг меха. Фрагментная программа
float4 main ( FragmentData IN, uniform sampler2D furMap, uniform sampler2D anisoMap ) : COLOR{ const float3 specColor = float3 ( 1, 1, 1 );
float3 tang = normalize ( IN.furDir ); float dot1 = dot ( normalize ( IN.lt ), tang ); float dot2 = dot ( normalize ( IN.ht ), tang ); float2 arg = float2 ( dot1, dot2 ); float2 ds = tex2D ( anisoMap, arg*arg ).xy; float4 color = tex2D ( furMap, IN.texCoord * float2 ( 6, 12 ) );
return IN.color * float4 ( color.xyz + specColor * ds.y*0.5, color.w*color.w );}
Визуальные эффекты на Визуальные эффекты на GPUGPUРендеринг меха. Главная программаРендеринг меха. Главная программа
// draw shells from innermost to outermostglEnable ( GL_BLEND );glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
// draw every layerfor ( int i = 0; i < numLayers; i++ ){
float t = (float) i / MAX_LAYERS;float shadow = 0.7*(shadowMin * (1 - t) + shadowMax * t);
glColor4f ( shadow, shadow, shadow, shadow );
vertexProgram.setParameter ( "tl", t * scale );
object -> render ();}
// restore stateglDisable ( GL_BLEND );
Визуальные эффекты на Визуальные эффекты на GPUGPUСгорание как в Сгорание как в DooM IIIDooM III
Визуальные эффекты на Визуальные эффекты на GPUGPUСгорание как в Сгорание как в DooM III. Вершинная программаDooM III. Вершинная программа
FragmentData main ( VertexData IN, uniform float4 lightPos, uniform float4 eyePos, uniform float4x4 mvp,
uniform float4x4 mv, uniform float4x4 mvi ){ FragmentData OUT;
OUT.p = mul ( mv, IN.pos ).xyz; OUT.n = mul ( mvi, float4 ( IN.n, 0 ) ).xyz; OUT.l = normalize ( lightPos.xyz - OUT.p ); OUT.v = normalize ( eyePos.xyz - OUT.p ); OUT.h = normalize ( OUT.l + OUT.v ); OUT.pos = mul ( mvp, IN.pos ); OUT.texCoord = IN.texCoord;
return OUT;}
Визуальные эффекты на Визуальные эффекты на GPUGPUСгорание как в Сгорание как в DooM III. Фрагментная программаDooM III. Фрагментная программа
float4 main ( FragmentData IN, uniform float time, uniform sampler3D noiseMap ) : COLOR{
float3 noise = turbulence ( noiseMap, 0.1 * IN.p );float t = -0.3 - noise.x + fmod ( time, 15 ) / 15;float3 n2 = normalize ( IN.n );float3 l2 = normalize ( IN.l );float3 h2 = normalize ( IN.h );float4 diff = diffColor * max ( dot ( n2, l2 ), 0.5 );float4 spec = specColor * pow ( max ( dot ( n2, h2 ), 0 ), 30 );float4 color = diff + spec;
if ( t > 0 )if ( t > 0.02 )
color = float4 ( 0, 0, 0, 0 );else
color = lerp ( darkRed, brightRed, t * 50 );return color;
}
Recommended