OpenGL:如何渲染完美的矩形渐变?

OpenGL: How to render perfect rectangular gradient?(OpenGL:如何渲染完美的矩形渐变?)
本文介绍了OpenGL:如何渲染完美的矩形渐变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我可以只用一个三角形并为每个角使用 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 transforming objects with multiple rotations of Different axis(OpenGL 变换不同轴多次旋转的对象)
GLFW first responder error(GLFW 第一响应者错误)
SOIL not linking correctly(SOIL 连接不正确)
Core profile vs version string? Only getting GLSL 1.3/OGL 3.0 in mesa 10.0.1(核心配置文件与版本字符串?在 mesa 10.0.1 中只获得 GLSL 1.3/OGL 3.0)
What is the range of OpenGL texture ID?(OpenGL 纹理 ID 的范围是多少?)
How taxing are OpenGL glDrawElements() calls compared to basic logic code?(与基本逻辑代码相比,OpenGL glDrawElements() 调用的繁重程度如何?)