在GLSL中实现纹理圆角效果可以通过多种方法,这些方法各有其优缺点和适用场景。以下是几种常见的实现方法:
1. 使用距离函数
最常见的方法是计算像素到中心的距离,并使用该距离来决定像素是否显示。
#version 330 core in vec2 TexCoord; out vec4 FragColor; uniform sampler2D texture1; uniform vec2 resolution; uniform float radius; void main() { vec2 center = vec2(0.5, 0.5); // 中心位置 vec2 uv = TexCoord; // 当前纹理坐标 float dist = length(uv - center); // 计算距离 float alpha = smoothstep(radius, radius + 0.01, dist); // 创建圆角掩码 vec4 color = texture(texture1, TexCoord); FragColor = vec4(color.rgb, color.a * (1.0 - alpha)); // 应用掩码 }
2. 使用圆形遮罩纹理
你可以创建一个圆形遮罩纹理,用于在片段着色器中结合原始纹理。这个方法有时更灵活,尤其是在处理多个不同的形状时。
#version 330 core in vec2 TexCoord; out vec4 FragColor; uniform sampler2D texture1; uniform sampler2D maskTexture; // 圆形遮罩纹理 void main() { vec4 texColor = texture(texture1, TexCoord); float maskAlpha = texture(maskTexture, TexCoord).r; // 从遮罩纹理中取样 FragColor = vec4(texColor.rgb, texColor.a * maskAlpha); // 应用遮罩 }
3. 利用discard
语句
你可以在片段着色器中使用discard
语句来完全丢弃不在圆角区域内的像素。
#version 330 core in vec2 TexCoord; out vec4 FragColor; uniform sampler2D texture1; uniform float radius; void main() { vec2 center = vec2(0.5, 0.5); // 中心位置 vec2 uv = TexCoord; // 当前纹理坐标 float dist = length(uv - center); // 计算距离 if (dist > radius) { discard; // 丢弃超出圆角区域的像素 } vec4 color = texture(texture1, TexCoord); FragColor = color; // 输出纹理颜色 }
4. 利用Shader中的数学函数
在一些情况下,你可能需要创建更复杂的圆角效果,结合其他数学函数来实现。例如,可以结合高斯模糊函数或其他形状的遮罩来创建柔和的边缘效果。
#version 330 core in vec2 TexCoord; out vec4 FragColor; uniform sampler2D texture1; uniform vec2 resolution; uniform float radius; void main() { vec2 center = vec2(0.5, 0.5); // 中心位置 vec2 uv = TexCoord; // 当前纹理坐标 float dist = length(uv - center); // 计算距离 float alpha = 1.0 - smoothstep(radius - 0.01, radius, dist); // 更柔和的圆角 vec4 color = texture(texture1, TexCoord); FragColor = vec4(color.rgb, color.a * alpha); // 应用圆角 }
5. 使用Alpha测试
你可以先将纹理的透明度设置为圆形区域,然后在渲染管线的早期阶段进行Alpha测试来丢弃不需要的像素。
#version 330 core in vec2 TexCoord; out vec4 FragColor; uniform sampler2D texture1; uniform float radius; void main() { vec2 center = vec2(0.5, 0.5); // 中心位置 vec2 uv = TexCoord; // 当前纹理坐标 float dist = length(uv - center); // 计算距离 float alpha = smoothstep(radius, radius + 0.01, dist); // 圆角掩码 vec4 color = texture(texture1, TexCoord); if (color.a * (1.0 - alpha) < 0.1) { discard; // 根据透明度决定是否丢弃 } FragColor = color; // 输出纹理颜色 }
总结
这些方法各有其特点和应用场景。选择合适的方法取决于具体的需求和性能考虑。例如,使用discard
语句可能对性能有影响,但非常直观;而使用遮罩纹理或距离函数则可能更灵活,适用于不同的场景.
标签:glsl,圆角,Opengl,float,TexCoord,纹理,vec4,vec2,uniform From: https://www.cnblogs.com/lianshanIn17/p/18351116