Простой эффект свечения / размытия HLSL в DirectX9 - PullRequest
2 голосов
/ 22 ноября 2010

В течение нескольких дней я пытался найти какие-либо ресурсы, которые помогли бы мне написать простой шейдер свечения / размытия с использованием языка высокоуровневых шейдеров и управляемых библиотек DirectX 9.

Все, что мне нужно сделать, это иметь массив CustomVertex.TransformedColored вершин, нарисованных в виде простых линий, а затем размытых / светящихся с помощью эффекта HLSL.

Я искал в Интернете около трех дней с некоторыми результатами, но я просто не могу найти действительно хороший учебник или пример. У меня есть базовое понимание HLSL, но я не понимаю его настолько, чтобы понять, как написать этот шейдер (я также прочитал главу HLSL в 3 книгах по DirectX).

Вот некоторый (сокращенный) код:

CustomVertex.TransformedColored[] glowVertices = new CustomVertex.TransformedColored[4];
glowVertices[0] = new CustomVertex.TransformedColored(random.Next(this.render.Width), random.Next(this.render.Height), 1, 1, Color.Cyan.ToArgb());
glowVertices[1] = new CustomVertex.TransformedColored(random.Next(this.render.Width), random.Next(this.render.Height), 1, 1, Color.Blue.ToArgb());
glowVertices[2] = new CustomVertex.TransformedColored(random.Next(this.render.Width), random.Next(this.render.Height), 1, 1, Color.Cyan.ToArgb());
glowVertices[3] = new CustomVertex.TransformedColored(random.Next(this.render.Width), random.Next(this.render.Height), 1, 1, Color.Blue.ToArgb());

this.device.BeginScene();
int passes = this.glowEffect.Begin(0);
for (int i = 0; i < passes; i++)
 {
     this.glowEffect.BeginPass(i);
     this.device.DrawUserPrimitives(PrimitiveType.LineStrip, glowVertices.Length - 1, glowVertices);
     this.glowEffect.EndPass();
 }
 this.glowEffect.End();
 this.device.EndScene();

Полагаю, я не очень ищу помощи по конкретной части HLSL, учитывая количество вопросов и объем кода, который мне нужно было бы опубликовать. Я просто ищу помощь в поиске ресурсов!

1 Ответ

6 голосов
/ 23 ноября 2010

Непосредственная проблема, которую я вижу с вашим кодом, заключается в том, что вы применяете шейдер к самим строкам.Пиксельные шейдеры действительно не работают таким образом.Вы не можете взаимодействовать ни с одним из пикселей вокруг затененного пикселя.Все, что вы получаете, это регистры (положение, цвет, координаты текстуры и т. Д.) И сэмплеры (текстуры) для этого одного пикселя, который выводится.

Чтобы обойти это, основной процесс создания эффекта размытия (такой какчто касается свечения или цветения) - это нарисовать сцену, которую вы хотите размыть, к цели рендеринга.Затем используйте эту цель рендеринга в качестве текстуры в полноэкранном квадрате, который вы рисуете с помощью шейдера размытия.Простой шейдер размытия берет несколько образцов из этой текстуры - каждый со слегка смещенной координатой текстуры.В результате получается размытое изображение текстуры.

Обычно вы повторяете этот процесс (теперь визуализируете target-on-a-a-full-screen-quad в другую цель визуализации), делая одно размытие по горизонтали и одновертикально, чтобы получить максимально размытое изображение с наименьшим количеством образцов.

Я рекомендую взглянуть на образец XNA Bloom .Там есть более обширная документация по этому процессу.Хотя API - это XNA, а не DirectX, они довольно похожи и оба используют HLSL.

...