如何在three.js中实现ShaderToy着色器?

Mic*_*c C 12 three.js

寻找有关如何在threejs内重新创建ShaderToy参数iGlobalTime,iChannel等的信息.我知道iGlobalTime是自Shader开始以来经过的时间,我认为iChannel的东西是用于从纹理中拉出rgb,但是会欣赏有关如何设置这些内容的信息.

编辑:已经浏览了所有带有three.js示例的着色器,并认为答案都在某处 - 只需找到等效于例如iChannel1 =纹理输入等.

INF*_*NF1 30

我不确定你是否回答了你的问题,但是对于其他人来说,知道对于THREEJS的整合步骤可能会有好处.

首先,您需要知道shadecorys是片段着色器.话虽这么说,你必须设置一个"通用"顶点着色器,它应该适用于所有的shadeaeys(片段着色器).

步骤1 创建"通用"顶点着色器

varying vec2 vUv; 
void main()
{
    vUv = uv;

    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
}
Run Code Online (Sandbox Code Playgroud)

这个顶点着色器非常基本.请注意,我们定义了一个变量变量vUv来告诉片段着色器纹理映射在哪里.这很重要,因为我们不会将屏幕分辨率(iResolution)用于基本渲染.我们将使用纹理坐标.我们已经这样做了,以便在同一个THREEJS场景中的不同对象上集成多个阴影.

步骤2 选择我们想要的阴影并创建片段着色器.(我选择了一个表现良好的简单玩具:niklashuss的简单隧道2D).

以下是此玩具的给定代码:

void main(void)
{
    vec2 p = gl_FragCoord.xy / iResolution.xy;
    vec2 q = p - vec2(0.5, 0.5);

    q.x += sin(iGlobalTime* 0.6) * 0.2;
    q.y += cos(iGlobalTime* 0.4) * 0.3;

    float len = length(q);

    float a = atan(q.y, q.x) + iGlobalTime * 0.3;
    float b = atan(q.y, q.x) + iGlobalTime * 0.3;
    float r1 = 0.3 / len + iGlobalTime * 0.5;
    float r2 = 0.2 / len + iGlobalTime * 0.5;

    float m = (1.0 + sin(iGlobalTime * 0.5)) / 2.0;
    vec4 tex1 = texture2D(iChannel0, vec2(a + 0.1 / len, r1 ));
    vec4 tex2 = texture2D(iChannel1, vec2(b + 0.1 / len, r2 ));
    vec3 col = vec3(mix(tex1, tex2, m));
    gl_FragColor = vec4(col * len * 1.5, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

步骤3 自定义shadertoy原始代码以获得完整的GLSL片段着色器.错过代码的第一件事是制服和变化声明.将它们添加到frag shader文件的顶部(只需复制并粘贴以下内容):

uniform float iGlobalTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;

varying vec2 vUv;
Run Code Online (Sandbox Code Playgroud)

注意,只声明用于该样本的shadeaeys变量,以及先前在我们的顶点着色器中声明的变化的vUv.

我们必须要做的最后一件事是正确的UV映射,现在我们决定不使用屏幕分辨率.为此,只需替换使用IResolution制服的线,即:

vec2 p = gl_FragCoord.xy / iResolution.xy;
Run Code Online (Sandbox Code Playgroud)

有:

vec2 p = -1.0 + 2.0 *vUv;
Run Code Online (Sandbox Code Playgroud)

就是这样,你的着色器现在可以在你的THREEJS场景中使用了.

第4步 你的THREEJS代码:

设置制服:

var tuniform = {
        iGlobalTime:    { type: 'f', value: 0.1 },
        iChannel0:  { type: 't', value: THREE.ImageUtils.loadTexture( 'textures/tex07.jpg') },
        iChannel1:  { type: 't', value: THREE.ImageUtils.loadTexture( 'textures/infi.jpg' ) },
    };
Run Code Online (Sandbox Code Playgroud)

确保纹理包裹:

tuniform.iChannel0.value.wrapS = tuniform.iChannel0.value.wrapT = THREE.RepeatWrapping;
tuniform.iChannel1.value.wrapS = tuniform.iChannel1.value.wrapT = THREE.RepeatWrapping;
Run Code Online (Sandbox Code Playgroud)

使用着色器创建材质并将其添加到planegeometry中.planegeometry()将模拟阴影700x394的屏幕分辨率,换句话说,它将最好地转移艺术家想要分享的作品.

var mat = new THREE.ShaderMaterial( {
            uniforms: tuniform,
            vertexShader: vshader,
            fragmentShader: fshader,            
            side:THREE.DoubleSide
        } );

var tobject = new THREE.Mesh( new THREE.PlaneGeometry(700, 394,1,1), mat);
Run Code Online (Sandbox Code Playgroud)

最后,添加THREE.Clock()到iGlobalTime值的增量而不是更新功能中的总时间.

tuniform.iGlobalTime.value += clock.getDelta();
Run Code Online (Sandbox Code Playgroud)

就是这样,你现在可以使用这个设置运行大部分的遮阳板......

  • 它允许您将UV坐标转换为XY绝对坐标.这是使它工作的技巧/黑客...... (3认同)

And*_*Ray 9

这是一个旧线程,但现在有一种自动化的方法.只需访问http://shaderfrog.com/app/editor/new,然后点击右上角的"导入> ShaderToy"并粘贴到URL中.如果它不公开,您可以粘贴原始源代码.然后您可以保存着色器(需要注册,没有电子邮件确认),然后单击"导出> Three.js".

您可能需要在导入后稍微调整参数,但我希望随着时间的推移对其进行改进.例如,ShaderFrog尚不支持音频输入或视频输入,但您可以使用图像预览它们.

概念证明:

ShaderToy https://www.shadertoy.com/view/MslGWN

ShaderFrog http://shaderfrog.com/app/view/247

完全披露:我是上周发布的这个工具的作者.我认为这是一个有用的功能.