Opengl es 使用片段着色器在特定位置绘制完美的水平线

Opengl es 使用片段着色器在特定位置绘制完美的水平线,opengl-es,glsl,webgl,shader,Opengl Es,Glsl,Webgl,Shader,使用应用于屏幕对齐四边形的片段着色器,是否可以在垂直轴上的任何选定位置绘制单像素高度的完美水平线 我已经找到了许多使用smoothstep或更复杂函数的解决方案,但我正在寻找一种优雅而快速的方法 我提出的一个解决方案是使用指数函数并使其更陡峭,但它有许多我不想看到的缺点(由于指数函数,线条不是真正的一个像素高度,要获得正确的高度非常困难),以下是GLSL代码: void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 u

使用应用于屏幕对齐四边形的片段着色器,是否可以在垂直轴上的任何选定位置绘制单像素高度的完美水平线

我已经找到了许多使用smoothstep或更复杂函数的解决方案,但我正在寻找一种优雅而快速的方法

我提出的一个解决方案是使用指数函数并使其更陡峭,但它有许多我不想看到的缺点(由于指数函数,线条不是真正的一个像素高度,要获得正确的高度非常困难),以下是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代码:

我想要的是:

  • 以像素单位或标准化为单位绘制到特定Y位置的完美水平线
  • 其强度限制在[0,1]范围内,无需夹紧
  • 一种快速的方法
如果您只想:

在所选的任意位置绘制一条单像素高度的完美水平线 将碎片着色器应用于垂直轴上的位置 屏幕对齐四边形

,那么也许:

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
}
void主图像(输出vec4 fragColor,输入vec2 fragCoord)
{
int iPosition=250;//以像素为单位的y坐标
inti厚度=10;//以像素为单位的厚度
vec2 uv=fragCoord.xy/iResolution.xy;
浮点数v=浮点数(iPosition)/iResolution.y;
float vHalfHeight=(float(i间隙)/(i解决方案y))/2。;
如果(uv.y>v-vHalfHeight&&uv.y
如果您只想:

在所选的任意位置绘制一条单像素高度的完美水平线 将碎片着色器应用于垂直轴上的位置 屏幕对齐四边形

,那么也许:

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
}
void主图像(输出vec4 fragColor,输入vec2 fragCoord)
{
int iPosition=250;//以像素为单位的y坐标
inti厚度=10;//以像素为单位的厚度
vec2 uv=fragCoord.xy/iResolution.xy;
浮点数v=浮点数(iPosition)/iResolution.y;
float vHalfHeight=(float(i间隙)/(i解决方案y))/2。;
如果(uv.y>v-vHalfHeight&&uv.y
是一种没有分支的简洁解决方案。我不知道它是否真的比分支更快

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);
}
是一个没有分支的整洁解决方案。我不知道它是否真的比分支更快

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);
}

我知道这个问题在我之前已经得到了正确的回答,但如果有人正在寻找一种以像素完美的方式渲染纹理线的方法,我用一些例子写了一篇文章


一般来说,这是一个像素级的UI,但将其用于线条只是一个夹持/重复纹理采样的问题。我也在使用Unity,但没有理由只使用Unity。

我知道这个问题在我之前已经得到了正确的回答,但如果有人想用像素完美的方式渲染纹理线,我就用一些例子写了一篇文章


一般来说,这是一个像素级的UI,但将其用于线条只是一个夹持/重复纹理采样的问题。我也使用Unity,但没有理由该方法是唯一的。

谢谢,这个解决方案是完美的,除了性能,我知道这个解决方案,但分支是一种不可行的方法,我想有一种方法可以通过删除条件来优化它。所以,我不知道
step
函数的计算成本,但我通过执行
v=step(uv.y,v+vHalfHeight)-step(uv.y,v-vHalfHeight)删除了分支干得好!你知道有什么简单的工具可以用来测量着色器的执行时间吗?可能会在高分辨率时钟信号之间循环数千次!:)不,但我也很想知道它是如何实现的:)ShaderToy上的iq和abje发布了一个非常优雅的解决方案(带有分支)
fragColor=vec4(fragCoord.y+0.5==iPosition)
我想知道这是不是最快的?谢谢你,这个解决方案除了性能之外非常完美,我知道这个解决方案,但分支是一种不可行的方法,我想有一种方法可以通过删除条件来优化它。因此,我不知道
step
函数的计算成本,但我通过执行
v=step(uv.y,v+vHalfHeight)-step(uv.y,v-vHalfHeight)来删除分支干得好!你知道有什么简单的工具可以用来测量着色器的执行时间吗?可能会在高分辨率时钟信号之间循环数千次!:)不,但我想知道这是怎么可能的:)ShaderToy上的iq和abje发布了一个非常优雅的解决方案(带有分支)
fragColor=vec4(fragCoord.y+0.5==iPosition)
我想知道这是不是最快的?ShaderToy上的Zabidon发布了一个看起来更好的解决方案,带有
v=step(abs(fragCoord.y-py),1.)v=step(abs(fragCoord.y-py),1.)