Текстура, позволяющая расчитать преломление луча света при столкновении с поверхностью, например водой. Название происходит от математического обозначения производной du/dv, т.к. DuDv карта является "производной" от карты нормалей. Из карты нормалей DuDv карту можно создать при помощи плагина к Photoshop или же используя программу TGAtoDUDV от ATI.
DuDv карта
Пример простейшего шейдера, использующего DuDv карту для расчета преломлений:
Итак, имеем:
- DuDv карту
- Текстуру, в которую были отрисованы объекты, находящиеся за преломляющей поверхностью (*)<vertex>
varying vec2 v_TexCoords; // ** Текстурные координаты для выборки из DuDv карты
varying vec4 v_ViewCoord; // ** Для выборки из текстуры (*)void main(void)
{
gl_Position = ftransform();
v_TexCoords = gl_MultiTexCoord0.xy;
v_ViewCoord = gl_ModelViewProjectionMatrix * gl_Vertex;
}
<fragment>
uniform sampler2D u_DuDvMap; // ** DuDv карта :)
uniform sampler2D u_DiffuseMap; // ** Текстура (*)
varying vec2 v_TexCoords;
varying vec4 v_ViewCoord;
constfloat k_Distortion = 0.0001; // ** Степень искаженияconstfloat k_Refraction = 0.035; // ** Степень преломленияvoid main()
{
// ** Для получения искажений, делается первичная выборка из DuDv карты, результат домножается на// ** коэф. искажений, после чего делается вторичная выборка и результат домножается на коэф преломления// ** Если искажения не нужны, достаточно сделать всего одну выборку и результат использовать для смещения текс. координат
vec4 distortion = texture2D( u_DuDvMap, v_TexCoords ) * k_Distortion;
vec4 dudvOffset = texture2D( u_DuDvMap, v_TexCoords + distortion.xy ) * k_Refraction;
vec4 projCoord = v_ViewCoord / v_ViewCoord.q;
projCoord += dudvOffset; // ** Искажаем
projCoord = clamp(( projCoord + 1.0) * 0.5, 0.0001, 0.9999);
gl_FragColor = mix( texture2D( u_DiffuseMap, projCoord.xy ), vec4(0.25, 0.5, 0.8, 1.0), 0.5);
}
Результат работы шейдра:
Как видно из примера, DuDv карта просто хранит смещения текстурных координат.