WebGL / GLSL - ShaderToy如何工作? [英] WebGL/GLSL - How does a ShaderToy work?

查看:315
本文介绍了WebGL / GLSL - ShaderToy如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在敲Shadertoy - https://www.shadertoy.com/ - 最近,努力学习更多关于OpenGL和GLSL的信息。

I've been knocking around Shadertoy - https://www.shadertoy.com/ - recently, in an effort to learn more about OpenGL and GLSL in particular.

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

From what I understand so far, the OpenGL user first has to prepare all the geometry to be used and configure the OpenGL server (number of lights allowed, texture storage, etc). Once that's done, the user then has to provide at least one vertex shader program, and one fragment shader program before an OpenGL program compiles.

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

However, when I look at the code samples on Shadertoy, I only ever see one shader program, and most of the geometry used appears to be written directly into the GLSL code.

这是如何工作的?

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

My guess is that a vertex shader is already prepared upfront, and that the editable/sample shader is only a fragment shader. But then that doesn't explain the geometry in some of the more complex examples...

有人可以解释Shadertoy是如何工作的吗?

Can anyone explain how Shadertoy works?

推荐答案

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

ShaderToy is a tool for writing pixel shaders.

什么是像素着色器?

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

If you render a full screen quad, meaning that each of four points is placed in one of the four corners of the viewport, then the fragment shader for that quad is called pixel shader, because you could say that now each fragment corresponds to exactly one pixel of the screen. So a pixel shader is a fragment shader for a fullscreen quad.

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

So attributes are always the same and so is a vertex shader:

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] ]

该四边形呈现为 TRIANGLE_STRIP
此外,有些人更喜欢使用片段着色器的内置变量 gl_FragCoord ,而不是设置 UVs ,然后将其除以,例如,制服vec2 uScreenResolution

And that quad is rendered as TRIANGLE_STRIP. Also, instead of setting UVs explicitly, some prefer to use fragment shader's built-in variable gl_FragCoord, which is then divided with, for example, 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;
}

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

And fragment shader would then look something like this:

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

ShaderToy可以为您提供一些默认的制服, iResolution (又名 uScreenResolution ), iGlobalTime iMouse ,...您可以在像素着色器中使用它。

ShaderToy can supply you with a few uniforms on default, iResolution (aka uScreenResolution), iGlobalTime, iMouse,... which you can use in your pixel shader.

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

For coding geometry directly into the fragment shader (aka pixel shader), developer use something called ray-tracing. That is quite complex area of programming but in short: You present your geometry through some mathematical formulas, and later in pixel shader, when you wish to check if some pixel is a part of your geometry you use that formula to retrieve that information. Google-ing a bit should give you plenty of resources to read from what and how ray tracers are built exactly, and this might help: How to do ray tracing in modern OpenGL?

希望这会有所帮助。

这篇关于WebGL / GLSL - ShaderToy如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆