Я не уверен, что вы ответили на свой вопрос, но для других может быть полезно узнать шаги интеграции для shadertoys в THREEJS.
Во-первых, вам нужно знать, что shadertoys - это фрагмент-шейдеры. При этом вам нужно установить шейдер вершинного типа, который должен работать со всеми shadertoys (шейдерами фрагментов).
Шаг 1 Создание "общего назначения" вершинный шейдер
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
}
Эта вершинного шейдера довольно простой. Обратите внимание, что мы определили переменную переменную vUv, чтобы сообщить шейдеру фрагмента, где находится отображение текстур. Это важно, потому что мы не будем использовать разрешение экрана (iResolution
) для нашего базового рендеринга. Вместо этого мы будем использовать координаты текстуры. Мы сделали это, чтобы интегрировать несколько shadertoys на разные объекты в одной и той же ситуации 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 шейдер. Первое, что не хватает в коде, - это форма и декларация об изменении. Добавьте их в верхней части файла осколочной шейдеры (просто скопируйте и вставьте следующий):
uniform float iGlobalTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
varying vec2 vUv;
Note, только shadertoys переменного, используемая для этой выборки объявляется, а также изменяющееся ВУФ-ранее объявленный в нашем вершинном шейдере.
Последнее, что нам нужно сделать, это правильное отображение 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;
Создать материал с вашими шейдеры и добавить это к плоскогеометрии. Плоскогеометрия() будет имитировать разрешение экрана shadertoys 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();
То есть это, теперь вы можете запускать большинство shadertoys с этой установкой ...
Спасибо за ваш ответ. но откуда это взялось? 'vec2 p = -1.0 + 2.0 * vUv;' – socrateisabot
Позволяет конвертировать ваши координаты UV в абсолютные координаты XY. Это трюк/взлом, который заставляет его работать ... – INF1
отличная информация! Вот пример, который вы описываете. Глядя на https://www.shadertoy.com/view/XsBXWt# Я застрял на входе channel0, который является аудио-файлом. Должен ли я пройти настройку для веб-аудиофайлов HTML5 для этого? –