如何对纹理执行 HSL 变换?
如果我有一个 OpenGL 纹理,并且我需要在渲染纹理之前对其执行 HSL 修改,据我所知我需要一个着色器。问题是,我对着色器一无所知。有谁知道我需要去哪里看?
我想编写一个函数,在其中可以传入纹理和三个值、色调偏移度数以及 0 到 2 之间的饱和度和亮度乘数,然后让它调用一个着色器,将这些变换应用到之前的纹理呈现。界面看起来像这样:
procedure HSLTransform(texture: GLuint; hShift: integer; sMult, lMult: GLfloat);
不过,我不知道例程中应该包含什么内容。我了解 HSL/RGB 转换中涉及的基本数学,但我不知道如何编写着色器或如何应用它。有人能指出我正确的方向吗?首选 Delphi 示例,但如果需要的话我也可以阅读 C。
If I have an OpenGL texture, and I need to perform HSL modifications on it before rendering the texture, from what I've heard I need a shader. Problem is, I know nothing about shaders. Does anyone know where I would need to look?
I want to write a function where I can pass in a texture and three values, a hue shift in degrees, and saturation and lightness multipliers between 0 and 2, and then have it call a shader that will apply these transformations to the texture before it renders. The interface would look something like this:
procedure HSLTransform(texture: GLuint; hShift: integer; sMult, lMult: GLfloat);
I have no idea what's supposed to go inside the routine, though. I understand the basic math involved in HSL/RGB conversions, but I don't know how to write a shader or how to apply it. Can someone point me in the right direction? Delphi examples preferred, but I can also read C if I have to.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这非常复杂,如果您不熟悉着色器和 FBO,则需要一些时间来理解它。所以这里有一些最小的、未经测试的OpenGL代码,它实现了丹维尔的回答。错误检查已被省略;它本身就够复杂的了。如果多次调用此函数,则应保留此代码中创建的任何或所有对象。
如果您不关心速度,VilleK 的答案 在 CPU 上运行要容易得多...
希望有帮助。对于 2.0 之前的 OpenGL,您需要首先加载适当的扩展,然后在各处添加一些
EXT
和/或ARB
。如果您愿意走这条路,但没有成功,请随时发表评论来描述您遇到的问题。我很乐意提供帮助!
This is quite involved, and if you're new to shaders and FBO's it will take some time to understand it. So here is some minimal, untested OpenGL code that implements Danvil's answer. Error checking has been left out; it's complicated enough as it is. If you call this function many times, you should hold on to any or all of the objects created in this code.
If you don't care about speed, VilleK's answer that runs on the CPU is a lot easier...
Hope that helps. For pre-2.0 OpenGL, you need to load the proper extensions first, and slap on some
EXT
s and/orARB
s here and there.If you're willing to go down this road, and it doesn't work out, don't hesitate to post a comment describing the problems you encounter. I'll be happy to help!
编写着色器并不像听起来那么难。您应该研究诸如 Cg 或 HLSL 之类的东西...基本上,您最终将编写一个接受像素并对其进行转换的函数。
CG 教程
编写着色器后,您将加载并将其与 OpenGL 扩展函数绑定。当您将几何图形推入管道时,它将由光栅化器应用。这是一个简单的教程,展示了如何编写和使用非常基本的着色器:
教程 - OpenGL 中的 Cg 像素着色器< /a>
Writing a shader is not as hard as it sounds. You should look into something like Cg, or HLSL... Basically, you're going to end up writing a single function that takes a pixel and transforms it.
The CG Tutorial
Once you're shader is written, you'll load and bind it with OpenGL extension functions. It will then be applied by the rasterizer when you push geometry into the pipeline. Here is a simple tutorial that shows how to write and use a very basic shader:
Tutorial - Cg Pixel Shaders in OpenGL
如果您不想使用着色器(即不需要实时),您可以获取纹理的像素并使用 Delphi 代码对其进行修改。像这样的事情:
如果你想使用字节而不是浮点数,你可以使用 GL_UNSIGNED_BYTE。
它的性能比着色器慢,但您可能会在更少的时间内完成工作,因为着色器编写起来很棘手,特别是如果您以前从未编写过着色器。它们还需要在 NVIDIA 和 ATI 硬件上进行测试,以确保它们正常工作。
If you don't want to use shaders (i.e. real time is not needed) you can get the pixels of the texture and modify it using Delphi code. Something like this:
You can use GL_UNSIGNED_BYTE if you want to work with bytes instead of floats.
It will be slower performance than shaders but you will probably get the work done in less times because shaders are tricky to write, especially if you've never written one before. They also need to be tested on both NVIDIA and ATI hardware to be sure they work properly.
使用渲染到纹理:
Use render to texture: