netlib.narod.ru< Назад | Оглавление | Далее >

Добавляем тротуар

Теперь, когда у вас есть базовая сцена с объектом и фоном, пришло время реализовать простейший вариант марева. Основываясь на рассмотренном ранее варианте с маревом над нагретым тротуаром, вы можете использовать подход, аналогичный тому, который применялся для эффекта глубины резкости в главе 6. Если предположить, что эффект марева проявляется только на определенном расстоянии от камеры, можно использовать технику имитатора глубины для создания простого, но убедительного эффекта марева.

Для нового шейдера мы используем базовый шейдер, разработанный в предыдущем разделе, и скопируем в него проход имитатора глубины из шейдера, созданного в главе 6. Поскольку используется имитатор глубины, вам необходимо добавить к рабочему пространству соответствующую переменную Far_Dist, которая в данном случае будет называться Heat_Dist.

Для прохода визуализации имитатора глубины вам надо изменить вершинный и пиксельный шейдеры, основываясь на информации, изложенной в предыдущих абзацах. С учетом изменений шейдера для использования переменной Heat_Dist, вы должны получить следующий код:

float Heat_Dist;
float fInverseViewportWidth;
float fInverseViewportHeight;
float4x4 matViewProjection;
struct VS_OUTPUT
{
    float4 Pos: POSITION;
    float2 texCoord: TEXCOORD0;
};

VS_OUTPUT vs_main(float4 Pos: POSITION)
{
    VS_OUTPUT Out;

    // Просто выводим местоположение без преобразования
    // Координата Z содержит глубину, на которой располагается
    // имитатор марева
    Out.Pos = float4(Pos.xy, Heat_Dist, 1);

    // Устанавливаем координаты текстуры таким образом, чтобы
    // вся текстура полностью отображалась на экран
    Out.texCoord.x = 0.5 * (1 + Pos.x + fInverseViewportWidth);
    Out.texCoord.y = 0.5 * (1 - Pos.y + fInverseViewportHeight);

    return Out;
}

Для пиксельного шейдера вместо простой выборки размытой цели визуализации, необходимо выполнить применение проиллюстрированного ранее кода размытия к вашей исходной цели визуализации. С учетом этих модификаций вы должны получить следующий код пиксельного шейдера:

float OffsetScale;
sampler Texture0;
sampler Texture1;

float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR
{
    // Читаем и масштабируем смещение искажения
    float2 offset = tex3D(Texture1, float3(8*texCoord.x,8*texCoord.y,0)).xy;
    offset = ((offset*2.0)-1.0)*OffsetScale;

    // Выборка из цели визуализации с учетом полученного смещения
    return tex2D(Texture0,texCoord+offset);
}

В предложенном коде пиксельного шейдера координаты текстуры для карты искажений умножаются на 8. Это позволяет повысить зашумленность текстуры, повторяя карту искажений несколько раз по всему экрану. В данном шейдере используется текстура noisevolume.dds, которая находится на CD-ROM. Кроме того, чтобы разрешить неоднократное повторение карты искажений на экране, вам необходимо гарантировать, что режимам объекта текстуры ADDRESSU и ADDRESSV будет присвоено значение D3DTADDRESS_WRAP. Рис. 7.6 показывает результат визуализации для данного шейдера. Код шейдера находится на CD-ROM в файле shader_3.rfx.


Рис. 7.6. Итоговое рабочее пространство и результат визуализации для простого шейдера, реализующего эффект марева с использованием имитатора глубины

Рис. 7.6. Итоговое рабочее пространство и результат визуализации для простого шейдера, реализующего эффект марева с использованием имитатора глубины


 

ПРИМЕЧАНИЕ
В примере с нагретым тротуаром вы можете заметить, что эффект марева возникает в нескольких метрах над землей. В предложенной реализации эффект распространяется на весь экран. Если вы хотите имитировать естественное поведение, то должны маскировать часть имитатора, в зависимости от ее высоты над землей, или воспользоваться преимуществами техники, рассматриваемой в следующем разделе.

В предыдущем шейдере кое-что упущено; марево статично и не перемещается по экрану. В примере с нагретым тротуаром горячий воздух поднимается над поверхностью, вызывая перемещение возникающих искажений. Воспользовавшись встроенной переменной fTime0_1, которая с течением времени изменяет свое значение в диапазоне от 0 до 1, вы можете изменить пиксельный шейдер для анимации карты искажений. Поскольку карта искажений является объемной текстурой, в которой каждый слой текстуры представляет собой отдельный кадр ее анимации, вы также можете применять анимацию с синхронизацией по времени для компонента Z текстуры, чтобы еще больше улучшить анимацию. Применив эти изменения, вы получите следующий код пиксельного шейдера:

float OffsetScale;
float fTime0_1;
sampler Texture0;
sampler Texture1;

float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR
{
    // Читаем и масштабируем смещение искажений
    float2 offset = tex3D(Texture1, float3(8 * texCoord.x,
                    8 * texCoord.y + 2 * fTime0_1, fTime0_1)).xy;
    offset = ((offset * 2.0) - 1.0) * OffsetScale;

    return tex2D(Texture0, texCoord+offset);
}

 

ПРИМЕЧАНИЕ
Объемные текстуры (volume textures) позволяют вам хранить пиксели в трехмерном массиве вместо двухмерного, и адресоваться к текселям, используя не только координаты X и Y, но также и Z. Проще всего представить объемную текстуру в виде набора обычных текстур, сложенных в стопку одна над другой. Поскольку объемные текстуры являются специализированным, зависящим от оборудования форматом, храниться они могут только в файлах .DDS.

Благодаря анимации искажения выглядят более реалистично и естественно. Во втором упражнении к этой главе я предложу вам исследовать другой подход к анимации карты искажений, выглядящий еще более естественным. Код шейдера я поместил на CD-ROM в файл shader_4.rfx.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz