我不确定您是否回答了您的问题,但对其他人来说了解 Shaderoys 到 THREEJS 的集成步骤可能会有所帮助。
首先,你需要知道shaderoys是一个片段着色器。话虽这么说,您必须设置一个“通用”顶点着色器,该着色器应与所有着色器(片段着色器)一起使用。
Step 1创建“通用”顶点着色器
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
这个顶点着色器非常基本。请注意,我们定义了一个变化变量 vUv 来告诉片段着色器纹理映射在哪里。这很重要,因为我们不会使用屏幕分辨率(iResolution
)用于我们的基础渲染。我们将使用纹理坐标来代替。我们这样做是为了将多个着色器集成到同一个 THREEJS 场景中的不同对象上。
Step 2选择我们想要的着色器并创建片段着色器。 (我选择了一个简单但表现良好的玩具:简单的 2D 隧道,作者:niklashuss https://www.shadertoy.com/view/4sXSzs).
这是这个玩具的给定代码:
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);
}
Step 3自定义shadertoy原始代码以获得完整的GLSL片段着色器。
代码中首先遗漏的是制服和变量声明。将它们添加到碎片着色器文件的顶部(只需复制并粘贴以下内容):
uniform float iGlobalTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
varying vec2 vUv;
请注意,仅声明了用于该示例的 Shadertoys 变量,以及先前在顶点着色器中声明的变化的 vUv。
既然我们决定不使用屏幕分辨率,我们最后需要调整的是正确的 UV 映射。为此,只需替换使用 IResolution 制服的行,即:
vec2 p = gl_FragCoord.xy / iResolution.xy;
with:
vec2 p = -1.0 + 2.0 *vUv;
就是这样,您的着色器现在已准备好在 THREEJS 场景中使用。
Step 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() 将模拟 Shaderoys 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);
最后,添加 deltaTHREE.Clock()
iGlobalTime 值而不是更新函数中的总时间。
tuniform.iGlobalTime.value += clock.getDelta();
就是这样,您现在可以使用此设置运行大多数着色器......