2014-07-18 2 views
9

ищет информацию о том, как воссоздать параметры ShaderToy iGlobalTime, iChannel и т. Д. В пределах трех js. Я знаю, что iGlobalTime - это время, прошедшее с момента запуска Shader, и я думаю, что материал iChannel предназначен для вытягивания rgb из текстур, но он будет знать информацию о том, как их установить.Как реализовать шейдер ShaderToy в three.js?

Редактировать: прошли все шейдеры, которые поставляются с примерами three.js и считают, что ответы все там где-то - просто нужно найти эквивалент, например. iChannel1 = вход текстуры и т. д.

ответ

26

Я не уверен, что вы ответили на свой вопрос, но для других может быть полезно узнать шаги интеграции для 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 с этой установкой ...

+0

Спасибо за ваш ответ. но откуда это взялось? 'vec2 p = -1.0 + 2.0 * vUv;' – socrateisabot

+3

Позволяет конвертировать ваши координаты UV в абсолютные координаты XY. Это трюк/взлом, который заставляет его работать ... – INF1

+0

отличная информация! Вот пример, который вы описываете. Глядя на https://www.shadertoy.com/view/XsBXWt# Я застрял на входе channel0, который является аудио-файлом. Должен ли я пройти настройку для веб-аудиофайлов HTML5 для этого? –

7

Это старая нить, но теперь автоматизированный способ сделать это. Просто перейдите к http://shaderfrog.com/app/editor/new и в правом верхнем правом углу нажмите «Импорт> ShaderToy» и вставьте URL-адрес. Если он не является общедоступным, вы можете вставить исходный код. Затем вы можете сохранить шейдер (требуется регистрация, нет подтверждения по электронной почте) и нажмите «Экспорт> Три.js».

Возможно, вам придется немного изменить параметры после импорта, но я надеюсь, что со временем это улучшится. Например, ShaderFrog пока не поддерживает аудио и видеовходы, но вы можете их предварительно просмотреть с изображениями.

Доказательство концепции:

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

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

Полное раскрытие: Я являюсь автором этого инструмента который я начал на прошлой неделе. Я думаю, что это полезная функция.

+0

спасибо, глядя на это сейчас. –

+0

Я пробовал это, и он всегда возвращает ошибку, и шейдер не будет компилироваться. Я пытаюсь импортировать этот шейдер: https://www.shadertoy.com/view/4sSGDc – Ajq

+0

Есть еще некоторые крайние случаи синтаксиса, которые приводят к сбою импортера. Я добавлю это в список ошибок. –

1

Это основано на различных источниках, включая ответ @ INF1.

В основном вы вставляете отсутствуют унифицированные переменные из Shadertoy (iGlobalTime и т.д., см этот список: https://www.shadertoy.com/howto) в пиксельный шейдер, то переименовать mainImage(out vec4 z, in vec2 w) в main(), а затем изменить z в исходном коде «gl_FragColor». В большинстве Shadertoys 'z' есть 'fragColor'.

Я сделал это для двух крутых шейдеров этого парня (https://www.shadertoy.com/user/guil), но, к сожалению, я не получил мраморный пример для работы (https://www.shadertoy.com/view/MtX3Ws).

Рабочий jsFiddle находится здесь: https://jsfiddle.net/dirkk0/zt9dhvqx/ Измените шейдер от frag1 до frag2 в строке 56, чтобы увидеть оба примера.

И не «Tidy» в jsFiddle - он разбивает шейдеры.

EDIT: https://medium.com/@dirkk/converting-shaders-from-shadertoy-to-threejs-fe17480ed5c6

Смежные вопросы