使用片段着色器在特定位置绘制完美的水平线
Drawing a perfect horizontal line at a specific position with a fragment shader
是否可以通过将片段着色器应用于屏幕对齐的四边形,在垂直轴上的任何选定位置绘制单个像素高度的完美水平线?
我发现了许多具有平滑步骤或更复杂功能的解决方案,但我正在寻找一种优雅而快速的方法来实现这一点。
我所做的一个解决方案是使用指数函数并使其更陡峭,但它有许多我不想要的缺点(由于指数函数,该线实际上不是一个像素高度,而且它相当棘手得到一个正确的),这里是 GLSL 代码:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
// a centered horizontal line
float v = pow(uv.y - 0.5, 2.);
// make it steeper
v *= 100000.;
// make it white on a black background
v = clamp(1. - v, 0., 1.);
fragColor = vec4(v);
}
这是执行此代码的 shadertoy 代码:https://www.shadertoy.com/view/Ms2cWh
我想要什么:
- 以像素为单位或归一化绘制到特定 Y 位置的完美水平线
- 其强度限制在 [0, 1] 范围内而没有钳位
- 一种快速的方法
如果您只想:
draw a perfect horizontal line of a single pixel height at any chosen
position on the vertical axis with a fragment shader applied to a
screen aligned quad
,那么也许:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
int iPosition = 250; // the y coord in pixels
int iThickness = 10; // the thickness in pixels
vec2 uv = fragCoord.xy / iResolution.xy;
float v = float( iPosition ) / iResolution.y;
float vHalfHeight = ( float( iThickness ) / ( iResolution.y ) ) / 2.;
if ( uv.y > v - vHalfHeight && uv.y < v + vHalfHeight )
fragColor = vec4(1.,1.,1.,1.); // or whatever color
}
Here 是一个没有分支的简洁解决方案。我不知道它是否真的比分支更快。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
float py = iMouse.y/iResolution.y;
float hh = 1./iResolution.y;
// can also be replace with step(0., hh-abs(uv.y-py))
float v = sign(hh-abs(uv.y-py));
fragColor = vec4(v);
}
我知道这个问题在我面前得到了正确的回答,但如果有人正在寻找一种方法来以像素完美的方式渲染纹理线,我写了一个 article 和一些例子。
一般来说,它是关于像素完美 UI 的,但是将它用于线条只是 clamping/repeating 纹理采样的问题。我也在使用 Unity,但没有理由认为该方法是它独有的。
是否可以通过将片段着色器应用于屏幕对齐的四边形,在垂直轴上的任何选定位置绘制单个像素高度的完美水平线?
我发现了许多具有平滑步骤或更复杂功能的解决方案,但我正在寻找一种优雅而快速的方法来实现这一点。
我所做的一个解决方案是使用指数函数并使其更陡峭,但它有许多我不想要的缺点(由于指数函数,该线实际上不是一个像素高度,而且它相当棘手得到一个正确的),这里是 GLSL 代码:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
// a centered horizontal line
float v = pow(uv.y - 0.5, 2.);
// make it steeper
v *= 100000.;
// make it white on a black background
v = clamp(1. - v, 0., 1.);
fragColor = vec4(v);
}
这是执行此代码的 shadertoy 代码:https://www.shadertoy.com/view/Ms2cWh
我想要什么:
- 以像素为单位或归一化绘制到特定 Y 位置的完美水平线
- 其强度限制在 [0, 1] 范围内而没有钳位
- 一种快速的方法
如果您只想:
draw a perfect horizontal line of a single pixel height at any chosen position on the vertical axis with a fragment shader applied to a screen aligned quad
,那么也许:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
int iPosition = 250; // the y coord in pixels
int iThickness = 10; // the thickness in pixels
vec2 uv = fragCoord.xy / iResolution.xy;
float v = float( iPosition ) / iResolution.y;
float vHalfHeight = ( float( iThickness ) / ( iResolution.y ) ) / 2.;
if ( uv.y > v - vHalfHeight && uv.y < v + vHalfHeight )
fragColor = vec4(1.,1.,1.,1.); // or whatever color
}
Here 是一个没有分支的简洁解决方案。我不知道它是否真的比分支更快。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
float py = iMouse.y/iResolution.y;
float hh = 1./iResolution.y;
// can also be replace with step(0., hh-abs(uv.y-py))
float v = sign(hh-abs(uv.y-py));
fragColor = vec4(v);
}
我知道这个问题在我面前得到了正确的回答,但如果有人正在寻找一种方法来以像素完美的方式渲染纹理线,我写了一个 article 和一些例子。
一般来说,它是关于像素完美 UI 的,但是将它用于线条只是 clamping/repeating 纹理采样的问题。我也在使用 Unity,但没有理由认为该方法是它独有的。