533955f1

Код вершинного шейдера обводки силуэта



17.5.4. Код вершинного шейдера обводки силуэта

Настала пора представить код вершинного шейдера для визуализации силуэта. Основная задача шейдера заключается в определении того, является ли переданная вершина частью силуэта. Если да, то вершинный шейдер осуществляет сдвиг вершины на заданный скаляр в направлении вектора нормали вершины.

// Файл: outline.txt // Описание: Вершинный шейдер, отображающий силуэт

// // Глобальные переменные //

extern matrix WorldViewMatrix; extern matrix ProjMatrix;

static vector Black = {0.0f, 0.0f, 0.0f, 0.0f};

// // Структуры //

struct VS_INPUT { vector position : POSITION; vector normal : NORMAL0; vector faceNormal1 : NORMAL1; vector faceNormal2 : NORMAL2; };

struct VS_OUTPUT { vector position : POSITION; vector diffuse : COLOR; };

// // Точка входа //

VS_OUTPUT Main(VS_INPUT input) { // Обнуляем члены выходной структуры VS_OUTPUT output = (VS_OUTPUT)0;

// Преобразуем местоположение в пространство вида input.position = mul(input.position, WorldViewMatrix);

// Вычисляем вектор направления взгляда на вершину. // Вспомните, что в пространстве вида зритель находится // в начале координат (зритель это то же самое, что и камера). vector eyeToVertex = input.position;

// Преобразуем нормали в пространство вида. Компоненте w // присваиваем нуль, поскольку преобразуем векторы. // Предполагается, что в мировой матрице нет масштабирования input.normal.w = 0.0f; input.faceNormal1.w = 0.0f; input.faceNormal2.w = 0.0f;

input.normal = mul(input.normal, WorldViewMatrix); input.faceNormal1 = mul(input.faceNormal1, WorldViewMatrix); input.faceNormal2 = mul(input.faceNormal2, WorldViewMatrix);

// Вычисляем косинус угла между вектором eyeToVertex // и нормалями граней float dot0 = dot(eyeToVertex, input.faceNormal1); float dot1 = dot(eyeToVertex, input.faceNormal2);

// Если у косинусов разные знаки (один положительный, // а другой отрицательный) значит край является частью // силуэта if((dot0 * dot1) < 0.0f) { // Знаки разные, значит вершина является частью // края силуэта, смещаем позиции вершин на заданный // скаляр в направлении нормали вершины input.position += 0.1f * input.normal; }

// Преобразование в однородное пространство отсечения output.position = mul(input.position, ProjMatrix);

// Устанавливаем цвет силуэта output.diffuse = Black;

return output; }



Содержание раздела