Визуальные эффекты на GPU Стандартные модели освещения...

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