Glsl 与直线的距离——Shadertoy

Glsl 与直线的距离——Shadertoy,glsl,shader,Glsl,Shader,我是shadertoy的新手,我一直在玩一些东西,但有一件事我搞不懂,那就是如何计算点到直线的距离。我可以很容易地用铅笔和纸自己做,但不知何故,当我试图把它应用到shadertoy上时,我总是把事情搞砸。以下是我所拥有的: void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord/iResolution.xy; uv.x -= 0.5; //Puts the origin at t

我是shadertoy的新手,我一直在玩一些东西,但有一件事我搞不懂,那就是如何计算点到直线的距离。我可以很容易地用铅笔和纸自己做,但不知何故,当我试图把它应用到shadertoy上时,我总是把事情搞砸。以下是我所拥有的:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    uv.x -= 0.5; //Puts the origin at the center of the screen

    float r; //Red value
    float g; //Green value
    float b; //Blue value

    float lm = 1.1; //slope
    float lb = 0.5; //intercept

    //Slope/intercept declarations manipulate line
    //second line
    float lmp = 0.0-(1.0/lm); //calculates the slope of the perpendicular line
    float lbp = lb + uv.y + lmp*(uv.x); //and the intercept

    //Intersection
    float ix = (lbp-lb)/(lm-lmp); //Intersection Y
    float iy = lm*(ix)+lb; //Intersection X based off of the first equation
    //distance
    float dist = sqrt(pow((uv.x - ix),2.0)+pow((uv.y - iy),2.0));

    if (dist < 0.05){

        r = 1.0;
        g = 1.0;
        b = 1.0;
    }

    fragColor = vec4(r,g,b,1.0); //supposed to draw a line
}

如果你有一条线,由一个点(
O
)和一个方向(
D
)给出,那么线上距离点p最近的点可以计算如下

X=O+D*dot(P-O,D);

两个矢量的点积等于两个矢量之间的夹角的余弦乘以两个矢量的大小(长度)

dot(A,B)==|A |*| B |*cos(alpha)
V
D
的点积等于直线(
O
D
)和向量
V=p-O
)之间的夹角的余弦乘以
V
的量(长度),因为
D
是a(
D
的长度是1.0)

在您的情况下,行由a给出,形式如下:

f(x)=lb+lmp*x;
直线上的点为(0.0,
lb
),方向为(1.0,
lmp

将此应用于代码会产生以下片段着色器:

浮动数据线(vec2o,vec2dir,vec2p) { vec2d=标准化(dir); vec2x=O+D*dot(P-O,D); 返回距离(P,X); } 无效主图像(输出vec4 fragColor,输入vec2 fragCoord) { vec2 uv=fragCoord/iResolution.xy; uv.x-=0.5;//将原点置于屏幕中心 float lm=1.1;//斜率 浮点lb=0.5;//截距 浮动距离=dfLine(vec2(0.0磅),vec2(1.0磅),紫外线); 在线浮动=步长(dist,0.05);//如果在线则为1.0,否则为0.0 vec3颜色=在线*vec3(1.0); fragColor=vec4(颜色,1.0); }
如果你有一条线,由一个点(
O
)和一个方向(
D
)给出,那么线上距离点p最近的点可以计算如下

X=O+D*dot(P-O,D);

两个矢量的点积等于两个矢量之间的夹角的余弦乘以两个矢量的大小(长度)

dot(A,B)==|A |*| B |*cos(alpha)
V
D
的点积等于直线(
O
D
)和向量
V=p-O
)之间的夹角的余弦乘以
V
的量(长度),因为
D
是a(
D
的长度是1.0)

在您的情况下,行由a给出,形式如下:

f(x)=lb+lmp*x;
直线上的点为(0.0,
lb
),方向为(1.0,
lmp

将此应用于代码会产生以下片段着色器:

浮动数据线(vec2o,vec2dir,vec2p) { vec2d=标准化(dir); vec2x=O+D*dot(P-O,D); 返回距离(P,X); } 无效主图像(输出vec4 fragColor,输入vec2 fragCoord) { vec2 uv=fragCoord/iResolution.xy; uv.x-=0.5;//将原点置于屏幕中心 float lm=1.1;//斜率 浮点lb=0.5;//截距 浮动距离=dfLine(vec2(0.0磅),vec2(1.0磅),紫外线); 在线浮动=步长(dist,0.05);//如果在线则为1.0,否则为0.0 vec3颜色=在线*vec3(1.0); fragColor=vec4(颜色,1.0); } @Rabbid

谢谢,但是代码在对dfLine()的调用中缺少p,因此可能是:

或者类似于简单的动画和平滑的线条:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
 vec2 uv = fragCoord/iResolution.xy;
 uv.x -= 0.5; //Puts the origin at the center of the screen

 float lm = sin(iTime); // animated slope, 1.1
 float lb = mix(0.5, 1.0, sin(iTime)); //0.5; //intercept   0.5-1.0 to keep it in the view port 
 vec2 P = vec2(uv.x, uv.y);
 //float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  vec2(uv.x,uv.y));

 float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  P);
 float onLine = 1.0 - smoothstep(0.0, 0.02, dist);

 vec3  color  = onLine * vec3(1.0);
 fragColor = vec4(color, 1.0);   
}
@犹太教

谢谢,但是代码在对dfLine()的调用中缺少p,因此可能是:

或者类似于简单的动画和平滑的线条:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
 vec2 uv = fragCoord/iResolution.xy;
 uv.x -= 0.5; //Puts the origin at the center of the screen

 float lm = sin(iTime); // animated slope, 1.1
 float lb = mix(0.5, 1.0, sin(iTime)); //0.5; //intercept   0.5-1.0 to keep it in the view port 
 vec2 P = vec2(uv.x, uv.y);
 //float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  vec2(uv.x,uv.y));

 float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  P);
 float onLine = 1.0 - smoothstep(0.0, 0.02, dist);

 vec3  color  = onLine * vec3(1.0);
 fragColor = vec4(color, 1.0);   
}

如果Neontoy代码有效,那么你的问题是什么?如果Neontoy代码有效,那么你的问题是什么?你可以通过
uv
。这只是我答错了。我已经修好了。谢谢,我知道是打字错误。当然P=uv或直接uv,但“P”与解释中的字母匹配。解释中的字母是
dfLine
的参数。你需要一行额外的代码。为什么'vec2p=vec2(uv.x,uv.y);'而不是
vec2p=uv
vec2p=uv.xy?因为它第一次出现在我的脑海中,就像Python元组:)并且出于说明的目的,它还允许对它快速应用更改,并让“玩家”看到它是如何进行的:修改,如sin(uv.x)等。修改是我使用您的代码的目的之一,而不是解决问题,也许还有其他人继续这出戏——就像在沙德托经常发生的那样。简而言之,对dfLine的调用也是如此:为什么vec2(0.0,lb)、vec2(1.0,lm)、lb和lm从不单独使用。如果这是一个目标,那么对dfLine的调用也可以是内联的。您只需传递
uv
。这只是我答错了。我已经修好了。谢谢,我知道是打字错误。当然P=uv或直接uv,但“P”与解释中的字母匹配。解释中的字母是
dfLine
的参数。你需要一行额外的代码。为什么'vec2p=vec2(uv.x,uv.y);'而不是
vec2p=uv
vec2p=uv.xy?因为它第一次出现在我的脑海中,就像Python元组:)并且出于说明的目的,它还允许对它快速应用更改,并让“玩家”看到它是如何进行的:修改,如sin(uv.x)等。修改是我使用您的代码的目的之一,而不是解决问题,也许还有其他人继续这出戏——就像在沙德托经常发生的那样。简而言之,对dfLine的调用也是如此:为什么vec2(0.0,lb)、vec2(1.0,lm)、lb和lm从不单独使用。如果这是一个目标,那么对dfLine的调用也可以内联。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
 vec2 uv = fragCoord/iResolution.xy;
 uv.x -= 0.5; //Puts the origin at the center of the screen

 float lm = sin(iTime); // animated slope, 1.1
 float lb = mix(0.5, 1.0, sin(iTime)); //0.5; //intercept   0.5-1.0 to keep it in the view port 
 vec2 P = vec2(uv.x, uv.y);
 //float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  vec2(uv.x,uv.y));

 float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  P);
 float onLine = 1.0 - smoothstep(0.0, 0.02, dist);

 vec3  color  = onLine * vec3(1.0);
 fragColor = vec4(color, 1.0);   
}