寻找有关如何在threejs内重新创建ShaderToy参数iGlobalTime,iChannel等的信息。我知道iGlobalTime是自着色器开始以来经过的时间,我认为iChannel的东西是用于从纹理中拉出rgb,但是会很感激如何设置它们。
编辑:已经浏览了所有带有three.js示例的着色器,并且认为答案都在某处 - 只需要找到等效的例子。 iChannel1 =纹理输入等。
答案 0 :(得分:29)
我不确定你是否已经回答了你的问题,但是对于其他人来说,了解一下对于THREEJS的整合步骤可能会有好处。
首先,您需要知道shadecorys是片段着色器。话虽这么说,你必须设置一个“通用”顶点着色器,它应该适用于所有的shadeaeys(片段着色器)。
第1步 创建“通用”顶点着色器
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
这个顶点着色器非常基本。请注意,我们定义了一个变量变量vUv来告诉片段着色器纹理映射在哪里。这很重要,因为我们不会将屏幕分辨率(iResolution
)用于基本渲染。我们将使用纹理坐标。我们已经这样做了,以便在同一个THREEJS场景中的不同对象上集成多个阴影。
第2步 选择我们想要的阴影并创建片段着色器。 (我选择了一个表现良好的简单玩具:Simple tunnel 2D by niklashuss)。
以下是此玩具的给定代码:
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);
}
第3步 自定义shadertoy原始代码以获得完整的GLSL片段着色器。 错过代码的第一件事是制服和变化声明。将它们添加到frag shader文件的顶部(只需复制并粘贴以下内容):
uniform float iGlobalTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
varying vec2 vUv;
注意,只声明用于该样本的shadeaeys变量,以及先前在我们的顶点着色器中声明的变化的vUv。
我们必须解决的最后一件事是正确的UV映射,现在我们决定不使用屏幕分辨率。为此,只需更换使用IResolution制服的线,即:
vec2 p = gl_FragCoord.xy / iResolution.xy;
使用:
vec2 p = -1.0 + 2.0 *vUv;
就是这样,你的着色器现在可以在你的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' ) },
};
确保纹理包裹:
tuniform.iChannel0.value.wrapS = tuniform.iChannel0.value.wrapT = THREE.RepeatWrapping;
tuniform.iChannel1.value.wrapS = tuniform.iChannel1.value.wrapT = THREE.RepeatWrapping;
使用着色器创建材质并将其添加到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);
最后,将THREE.Clock()
的增量添加到iGlobalTime值,而不是更新功能中的总时间。
tuniform.iGlobalTime.value += clock.getDelta();
就是这样,你现在可以使用这个设置运行大部分阴影......
答案 1 :(得分:9)
这是一个旧线程,但现在有一种自动化的方法。只需转到http://shaderfrog.com/app/editor/new,然后点击右上角的“导入> ShaderToy”并粘贴到网址中。如果它不公开,您可以粘贴原始源代码。然后您可以保存着色器(需要注册,无需确认电子邮件),然后单击“导出> Three.js”。
您可能需要在导入后略微调整参数,但我希望随着时间的推移对其进行改进。例如,ShaderFrog尚不支持音频输入或视频输入,但您可以使用图像预览它们。
概念证明:
ShaderToy https://www.shadertoy.com/view/MslGWN
ShaderFrog http://shaderfrog.com/app/view/247
完全披露:我是上周发布的这个工具的作者。我认为这是一个有用的功能。
答案 2 :(得分:2)
这是基于各种来源,包括@ INF1的答案。
基本上,您将Shadertoy中缺少的统一变量(iGlobalTime等,请参阅此列表:https://www.shadertoy.com/howto)插入片段着色器,将main()
重命名为z
,然后更改{源代码中的{1}}为“gl_FragColor
”。在大多数Shadertoys'z
'中都是'fragColor
'。
我为这个家伙的两个很酷的着色器(https://www.shadertoy.com/user/guil)做了这个,但不幸的是我没有得到大理石的例子(https://www.shadertoy.com/view/MtX3Ws)。
工作的jsFiddle在这里:https://jsfiddle.net/dirkk0/zt9dhvqx/ 在第56行中将着色器从frag1更改为frag2以查看两个示例。
并且不要在jsFiddle中“整洁” - 它打破了着色器。
编辑: https://medium.com/@dirkk/converting-shaders-from-shadertoy-to-threejs-fe17480ed5c6