WebGL/GLSL - ShaderToy如何工作?

Cha*_*lie 51 javascript shader glsl webgl pixel-shader

我一直在敲Shadertoy - https://www.shadertoy.com/ - 最近,为了更多地了解OpenGL和GLSL.

据我所知,到目前为止,OpenGL用户首先必须准备要使用的所有几何体并配置OpenGL服务器(允许的光源数量,纹理存储等).一旦完成,用户就必须在OpenGL程序编译之前提供至少一个顶点着色器程序和一个片段着色器程序.

但是,当我查看Shadertoy上的代码示例时,我只看到一个着色器程序,并且大多数使用的几何图形似乎直接写入GLSL代码.

这是如何运作的?

我猜测顶点着色器已经预先准备好了,可编辑/样本着色器只是一个片段着色器.但是,这并没有解释一些更复杂的例子中的几何...

谁能解释Shadertoy是如何工作的?

Abs*_*thm 64

ShaderToy是一个用于编写像素着色器的工具.

什么是像素着色器?

如果渲染全屏四边形,意味着四个点中的每一个都放置在视口的四个角之一中,则该四边形的片段着色器称为像素着色器,因为您可以说现在每个片段对应于一个屏幕的像素.因此,像素着色器是全屏四边形的片段着色器.

因此属性总是相同的,顶点着色器也是如此:

positions = [ [-1,1], [1,1], [-1,-1], [1,-1] ]
uv = [ [0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0] ]
Run Code Online (Sandbox Code Playgroud)

并且该四边形呈现为TRIANGLE_STRIP.此外,UVs有些人更喜欢使用片段着色器的内置变量,而不是明确地设置,gl_FragCoord然后将其与例如a分开uniform vec2 uScreenResolution.

顶点着色器:

attribute vec2 aPos;
attribute vec2 aUV;
varying vec2 vUV;

void main() {
    gl_Position = vec4(aPos, 0.0, 1.0);
    vUV = aUV;
}
Run Code Online (Sandbox Code Playgroud)

然后片段着色器看起来像这样:

uniform vec2 uScreenResolution;
varying vec2 vUV;

void main() {
    // vUV is equal to gl_FragCoord/uScreenResolution
    // do some pixel shader related work
    gl_FragColor = vec3(someColor);
}
Run Code Online (Sandbox Code Playgroud)

ShaderToy可以在默认的几个制服,为您提供iResolution(又名uScreenResolution)iGlobalTime,iMouse......你可以在你的像素着色器使用.

为了将几何直接编码到片段着色器(也称为像素着色器)中,开发人员使用称为光线跟踪的东西.这是非常复杂的编程领域,但简而言之:您通过一些数学公式呈现几何体,稍后在像素着色器中,当您希望检查某些像素是否是几何体的一部分时,您可以使用该公式来检索该信息.谷歌有点应该给你足够的资源来阅读精确构建射线追踪器的内容和方式,这可能会有所帮助: 如何在现代OpenGL中进行射线追踪?

希望这可以帮助.

  • 通常,光线跟踪在CPU上完成,并且对于图像中的每个像素,通过像素跟踪光线.由于像素着色器是为光栅化基元中的每个像素运行的程序,因此使用片段着色器进行光线跟踪比使用顶点着色器更自然和直观.这是合乎逻辑的事,对吧?但是,有像http://www.vertexshaderart.com/这样的东西.当你考虑某个着色器阶段的实际输出时,可以选择VS/FS在gpu上进行光线跟踪. (3认同)

gma*_*man 12

Shadertoy 被称为“TOY”是有原因的。这基本上是一个谜题。仅给定一个函数作为输入,告知当前像素位置,编写一个生成图像的函数。

该网站设置 WebGL 来绘制单个四边形(矩形),然后让您提供一个函数,将当前像素渲染为fragCoord. 然后你用它来计算一些颜色。

例如,如果你这样做了

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec4 red = vec4(1, 0, 0, 1);
    vec4 green = vec4(0, 1, 0, 1);
    fragColor = mix(red, green, sin(fragCoord.x / 10.0) * 0.5 + 0.5);
}
Run Code Online (Sandbox Code Playgroud)

你会得到像这样的红色和绿色条纹

在此输入图像描述

https://www.shadertoy.com/view/3l2cRz

Shadertoy 提供了一些其他输入。最常见的是渲染为 as 的分辨率iResolution。如果除以,fragCoord那么iResolution您将得到画布上从 0 到 1 以及向下从 0 到 1 的值,这样您就可以轻松地使函数分辨率独立。

这样做我们可以在中心画一个椭圆,如下所示

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    // uv goes from 0 to 1 across and up the canvas
    vec2 uv = fragCoord / iResolution.xy;
    
    vec4 red = vec4(1, 0, 0, 1);
    vec4 green = vec4(0, 1, 0, 1);

    float distanceFromCenter = distance(uv, vec2(0.5));
    fragColor = mix(red, green, step(0.25, distanceFromCenter));
}
Run Code Online (Sandbox Code Playgroud)

产生

在此输入图像描述

第二个最常见的输入是以iTime秒为单位,您可以随着时间的推移在函数中使用动画参数。

因此,考虑到这些输入,如果您应用足够的数学,您可以制作令人难以置信的图像,例如这个 Shadertoy 着色器生成此图像

令人惊奇的是,有人在仅给出上述输入的情况下就计算出生成该图像所需的数学。

许多最令人惊叹的 Shadertoy 着色器都使用一种称为光线行进的技术和一些称为“有符号距离场”的数学,您可以在此处阅读

但是,我认为重要的是要指出,虽然有很多很酷的东西可以从 Shadertoy 着色器中学习,但其中许多仅适用于“如何仅使用一个函数(其输入是像素位置并且其输出是单色”。他们没有回答“我应该如何为高性能应用程序编写着色器”。

与上面的海豚和这个快艇游戏相比

在此输入图像描述

https://www.youtube.com/watch?v=7v9gZK9HqqI

在我的 NVidia GeForce GT 750 上全屏显示时,海豚 Shadertoy 着色器的运行速度约为每秒 2 帧,而快艇游戏的运行速度为 60 fps。游戏运行速度快的原因是它使用了更传统的技术来绘制带有投影三角形的形状。即使是 NVidia 1060 GTX 全屏时也只能以每秒 10 帧左右的速度运行海豚着色器。


com*_*ble 7

ShaderToy显示简单的GLSL,它被编程为处理所有光照,几何等,它不是顶点几何,它是大部分光线投射,3D东西,或者你可以做2D着色器等.

任何颜色和空间数学都可以用GLSL语言编程.高级算法的组合使等值面,形状,然后将纹理投影到等值面上,并进行光线投射,从观察者发送虚线到距离,拦截任何方式,有许多3D的光线投射技术.

访问www.iquilezles.org,了解在shadertoy/glsl图形中使用的不同工具


小智 6

它基本上是将GLSL像素着色器源代码直接推送到显卡上.真正的魔力发生在人们用来创造惊人效果的难以置信的聪明算法中,如光线行进,光线投射,光线追踪.最好看看其他一些现场GLSL沙箱,例如:http://glsl.heroku.com/http://webglplayground.net/.它基本上创建了一个窗口,通常是两个代表屏幕的三角形,然后着色器就像光线跟踪器一样在每个像素上工作.
我一直在看这些,人们使用的算法是令人兴奋的,你需要一些严肃的数学印章,并查找"演示编码"源代码,以便能够围绕它们.许多关于着色器的玩具,只是打击你的心灵!总而言之,您只需要学习GLSL着色器编码和算法.不容易解决.


mle*_*age 5

传统上,在计算机图形学中,几何体是使用顶点创建的,并使用某种形式的材质(例如带有照明的纹理)进行渲染。在 GLSL 中,顶点着色器处理顶点,片段(像素)着色器处理材质。

但这并不是定义形状的唯一方法。正如可以按程序定义纹理(而不是查找其纹理元素)一样,也可以按程序定义形状(而不是查找其几何形状)。

因此,与光线追踪类似,这些片段着色器能够创建形状,而无需由顶点定义其几何形状。

还有更多定义形状的方法。例如体积数据(体素)、曲面曲线等。计算机图形文本应该涵盖其中的一些内容。


归档时间:

查看次数:

21265 次

最近记录:

9 年,5 月 前