Программирование шейдеров на 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'у.
#3D, #Direct3D, #DirectX, #HLSL, #шейдеры
1 июня 2004 (Обновление: 19 июня 2024)