如何在GLSL中实现均匀的四角渐变效果?
问题分析与解决
先明确你的目标效果:实现四顶点的平滑双线性渐变,四个顶点颜色分别为左上蓝色(blue)、右上青蓝色(azure)、左下绿色(green)、右下角为青蓝与绿色的混合色(cyan)。
你的代码核心问题出在helpfunc的混合逻辑上:
- 第二个
mix的两个参数均为azure[x],导致右侧区域无论Y轴如何变化,颜色都固定为azure,完全忽略了右下角的混合需求 - 整体混合顺序与参数逻辑错误,没有正确实现双线性插值的渐变规则
修正后的代码
#version 450 layout(binding=0) uniform UniformBufferObject { mat4 model; mat4 view; mat4 proj; } ubo; layout(location=0) in vec2 inPosition; layout(location=1) in vec3 inColor; layout(location=2) in vec2 inUV; layout(location=0) out vec3 fragColor; vec3 azure = vec3(0.0, 0.5, 0.5); vec3 blue = vec3(0.0, 0.0, 1.0); vec3 green = vec3(0.0, 1.0, 0.0); vec3 cyan = vec3(0.0, 1.0, 1.0); // 右下角目标颜色 float translate(float i) { return i + 0.5; } float helpfunc(int x) { // 双线性插值:先算上下边的X方向渐变,再算Y方向混合 float top_gradient = mix(blue[x], azure[x], translate(inPosition.x)); float bottom_gradient = mix(green[x], cyan[x], translate(inPosition.x)); return mix(top_gradient, bottom_gradient, translate(inPosition.y)); } void main() { gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); fragColor = vec3(helpfunc(0), helpfunc(1), helpfunc(2)); }
关键修正说明
- 补充右下角颜色:目标图右下角是green与azure的混合色,明确定义为
cyan,填补了之前缺失的顶点颜色逻辑 - 修正双线性插值逻辑:
- 先计算顶部边(Y轴上端)从blue到azure的X方向渐变
- 再计算底部边(Y轴下端)从green到cyan的X方向渐变
- 最后在Y轴方向混合上下边的渐变结果,得到当前像素的最终颜色
- 规范变量定义:将
vec3 azure = { ... }改为GLSL标准的vec3 azure = vec3(...)写法,避免潜在语法兼容问题
如果不想单独定义右下角的cyan,也可以用嵌套mix直接推导该颜色:
float helpfunc(int x) { return mix( mix(blue[x], azure[x], translate(inPosition.x)), mix(green[x], mix(azure[x], green[x], 0.5)[x], translate(inPosition.x)), translate(inPosition.y) ); }
调整后即可得到与目标图一致的渐变效果,不会再出现颜色偏向右下顶点的问题。
内容的提问来源于stack exchange,提问作者Garden_eel
相关产品推荐
相关产品推荐

