OpenGL: How to render perfect rectangular gradient?(OpenGL:如何渲染完美的矩形渐变?)
问题描述
我可以只用一个三角形并为每个角使用 glColor 来渲染三角形渐变.
I can render triangular gradient with simply just one triangle and using glColor for each corner.
但是如何渲染完美的矩形渐变?我试过一个四边形,但中间会出现难看的接缝.我也尝试过 2x2 大小的纹理,好像应该这样做:从每个角落适当混合,但是当拉伸太多时纹理采样精度变得不精确(我开始看到大于 1x1 大小的像素).
But how to render perfect rectangular gradient? I tried with one quad, but the middle will get ugly seam. I also tried with texture of 2x2 size, it was like it should be done: proper blending from each corner, but the texture sampling precision becomes unprecise when stretched too much (i started to see pixels bigger than 1x1 size).
是否有某种方法可以在着色器中计算此值?
Is there some way of calculating this in a shader perhaps?
--
图像链接已损坏(已删除).
Link to images were broken(removed).
推荐答案
确实,您想要的渐变类型依赖于每个像素的 4 种颜色,而 OpenGL 通常只在三角形上插入输入(因此是 3 个输入).仅使用标准插值法无法获得完美的梯度.
Indeed, the kind of gradient you want relies on 4 colors at each pixel, where OpenGL typically only interpolates input over triangles (so 3 inputs). Getting the perfect gradient is not possible just with the standard interpolants.
现在,正如您提到的,2x2 纹理可以做到.如果您确实看到精度问题,我建议将纹理的格式切换为通常需要更高精度的格式(例如浮动纹理).
Now, as you mentioned, a 2x2 texture can do it. If you did see precision issues, I suggest switching the format of the texture to something that typically requires more precision (like a float texture).
最后,正如您在问题中也提到的,您可以使用着色器解决此问题.假设您将对应于 (u,v) = (0,0) (0,1) (1,0) (1,0) 的额外属性 per-vertex 一直传递到像素着色器(使用顶点着色器只是做一个传递).
Last, and as you mentioned also in your question, you can solve this with a shader. Say you pass an extra attribute per-vertex that corresponds to (u,v) = (0,0) (0,1) (1,0) (1,0) all the way to the pixel shader (with the vertex shader just doing a pass-through).
您可以在像素着色器中执行以下操作(注意,这里的想法是合理的,但我没有测试代码):
You can do the following in the pixel shader (note, the idea here is sound, but I did not test the code):
顶点着色器片段:
varying vec2 uv;
attribute vec2 uvIn;
uv = uvIn;
片段着色器:
uniform vec3 color0;
uniform vec3 color1;
varying vec2 uv;
// from wikipedia on bilinear interpolation on unit square:
// f(x,y) = f(0,0)(1-x)(1-y) + f(1,0)x(1-y) + f(0,1)(1-x)y + f(1,1) xy.
// applied here:
// gl_FragColor = color0 * ((1-x)*(1-y) + x*y) + color1*(x*(1-y) + (1-x)*y)
// gl_FragColor = color0 * (1 - x - y + 2 * x * y) + color1 * (x + y - 2 * x * y)
// after simplification:
// float temp = (x + y - 2 * x * y);
// gl_FragColor = color0 * (1-temp) + color1 * temp;
gl_FragColor = mix(color0, color1, uv.u + uv.v - 2 * uv.u * uv.v);
这篇关于OpenGL:如何渲染完美的矩形渐变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:OpenGL:如何渲染完美的矩形渐变?
基础教程推荐
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01