DirectX9 中的简单 HLSL 发光/模糊效果
几天来我一直在努力寻找任何资源来帮助我使用高级着色器语言和 DirectX 9 托管库编写简单的发光/模糊着色器。
我需要做的就是将一组 CustomVertex.TransformedColored
顶点绘制为简单的线条,然后通过 HLSL 效果进行模糊/发光。
我已经在互联网上搜索了大约三天,得到了一些结果,但我只是找不到真正好的教程或示例。我对 HLSL 有基本的了解,但还不足以弄清楚如何编写这个着色器(我也阅读了 3 本 DirectX 书籍中的 HLSL 章节)。
这是一些(删节的)代码:
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 的特定部分寻求帮助,考虑到我必须发布的问题数量和代码量,我实际上只是在寻找一些帮助资源!
I have been struggling for days to find any resources to help me write a simple glow/blur shader using High Level Shader Language and DirectX 9 Managed Libraries.
All I need to do is have an array of CustomVertex.TransformedColored
vertices drawn as simple lines and then blurred/glowed by the HLSL effect.
I have searched the internet for about three days now with some results, but I just cannot find a really good tutorial or example. I have a basic understanding of HLSL but I do not understand it enough to figure out how to write this shader (I have read the HLSL chapter in 3 DirectX books as well).
Here is some (abridged) code:
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();
I guess I'm not so much looking for help on a specific part of HLSL, given the number of questions and amount of code I would have to post I'm really just looking for some help finding resources!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在您的代码中看到的直接问题是您将着色器应用于线条本身。像素着色器实际上并不是这样工作的。您无法与被着色的像素周围的任何像素进行交互。您得到的只是正在输出的一个像素的寄存器(位置、颜色、纹理坐标等)和采样器(纹理)。
要解决此问题,执行模糊效果(例如辉光或光晕)的基本过程是将要模糊的场景绘制到渲染目标。然后将该渲染目标用作使用模糊着色器绘制的全屏四边形上的纹理。一个简单的模糊着色器从该纹理中获取多个样本 - 每个样本都有一个稍微偏移的纹理坐标。结果是纹理的模糊图像。
通常,您会重复此过程(现在将全屏四边形上的渲染目标渲染到另一个渲染目标),水平进行一次模糊,垂直进行一次模糊,以使用最少数量的样本获得最大的模糊效果。
我建议查看 XNA Bloom 示例。那里有关于该过程的更广泛的文档。虽然 API 是 XNA,而不是 DirectX,但它们非常相似,并且都使用 HLSL。
The immediate problem I see with your code is that you're applying a shader to the lines themselves. Pixel shaders don't really work that way. You can't interact with any of the pixels around the pixel being shaded. All you get is registers (position, colour, texture coordinate, etc) and samplers (textures) for that one pixel that is being output.
To work around this, the basic process of doing a blur effect (such as for glow or bloom) is to draw the scene you want to blur to a render target. Then use that render target as a texture on a full-screen quad that you draw with a blur shader. A simple blur shader takes takes multiple samples from that texture - each with a slightly offset texture coordinate. The result is a blurred image of the texture.
Usually you repeat this process (now rendering the render-target-on-a-full-screen-quad to another render target), doing one blur horizontally and one vertically, to get the most blurring with the fewest number of samples.
I recommend looking at the XNA Bloom Sample. There is more extensive documentation on the process in there. While the API is XNA, not DirectX, they are fairly similar and they both use HLSL.