ПрограммированиеСтатьиГрафика

Программирование шейдеров на HLSL. (7 стр)

Оптимизация кода.

1. Не изобретайте колесо! Используйте intrinsic функции. Например:

Неоптимизированный код:

float DOT3(float3 v1,float3 v2)
{
  return(v1.x * v2.x +v1.y * v2.y +v1.z * v2.z);
}
float v=DOT3(V,R);

на выходе:

mul r0.xy, v0, c0 
add r0.w, r0.y, r0.x
mad oPos, c0.z, v0.z, r0.w

Используя dot3 вместо DOT3, на выходе получите такое:

dp3 r0.w, v0, c1

2. Всячески избегайте привидения типов и пытайтесь всегда выбрать необходимый тип. Например:

Неоптимизированный код:

sampler smth;
float4 main(float2 coor: TEXCOORD2) : COLOR
{
   float3 col=tex2D(smth, coor);
   return float4(col,0);
}

на выходе:

ps_2_0
def c0, 0, 0, 0, 0
dcl t2.xy
dcl_2d s0
texld r0, t2, s0
mov r0.w, c0.x
mov oC0, r0

Оптимизированный код:

sampler smth;
float4 main(float2 coor: TEXCOORD2) : COLOR
{
   float4 col=tex2D(smth, coor);
   return col;
}

на выходе:

ps_2_0
dcl t2.xy
dcl_2d s0
texld r0, t2, s0
mov oC0, r0

3. Объединяйте скаляры в вектора. Таким образом, можно уменьшить число констант в вашем шейдере. Например:

Неоптимизированный код:

float x, y;
float4 main (float4 pos :POSITION) : POSITION
{
  return (pos * x+y);
}

на выходе:

vs_2_0
dcl_position v0
mul r0, v0, c0.x
add oPos, r0, c1.x

Оптимизированный код:

float2 vec;
float4 main (float4 pos :POSITION) : POSITION
{
  return (pos * vec.x + vec.y);
}

на выходе:

vs_2_0
dcl_position v0
mad oPos, v0, c0.x, c0.y

4. Для ветвлений используйте тип bool как static. Например:

Неоптимизированный код:

float4 a;
bool b = true;
float4 main(float4 x: TEXCOORD0, float4 y : TEXCOORD1) : COLOR
{
  if(b)
    return  x+a;
  else
   return  y+a;
}

на выходе:

ps_2_0
dcl t0
dcl t1
add r1, t0, c0
add r0, t1, c0
cmp r0, -c1.x, r0, r1
mov oC0, r0

Объявление переменной b как static намного оптимизирует выходной код:

ps_2_0
dcl t0
add r0, t0, c0
mov oC0, r0

5. Векторизируйте типы. Например:

Неоптимизированный код:

float4 main (float k: COLOR) : COLOR
{
  float a, b, c, d;
  a = k + 1;
  b = k + 2;
  c = k + 3;
  d = k + 4;
  return float4 (a, b, c, d);
}

на выходе:

ps 2_0
def c0, 1, 2, 3, 4
dcl v0.x
add r0.x, v0.x, c0.x
add r0.y, v0.x, c0.y
add r0.z, v0.x, c0.z
add r0.w, v0.x, c0.w
mov oC0, r0

Оптимизированный код:

float4 main(float k: COLOR) : COLOR
{
  float4 v;
  v = k + float4(1,2,3,4);
  return v;
}

на выходе:

ps_2_0
def c0, 1, 2, 3, 4
dcl v0.x
add r0, v0.x, c0
mov oC0, r0

Завершение.

Несколько советов:

Подсказка: В помощь программисту шейдеров.
Рекомендуется скачать Render Monkey™ с сайта ATi Technologies®.
Программу Shader Works от Mad Software.
Подобную программу от NVIDIA® — FXComposer™.
Посетить сайт ShaderX.

P.S. По поводу API, каждый должен понимать, что все подобные эффекты можно сделать и на OpenGL, применяя при этом или GL_VERTEX/FRAGMENT PROGRAM либо на новом высокоуровневом языке GLSL или Cg.

Особую благодарность авторы выражают IronPeter'у.

Страницы: 1 2 3 4 5 6 7

#3D, #Direct3D, #DirectX, #HLSL, #шейдеры

1 июня 2004 (Обновление: 19 июня 2024)

Комментарии [151]