2015-10-20 2 views
2

Я пытаюсь посмотреть, как выглядят шейдеры в интерфейсе Builder с использованием набора спрайтов, и хотел бы использовать некоторые из шейдеров в ShaderToy. Чтобы сделать это, я создал файл «shader.fsh», файл сцены и добавил цвет спрайта на сцену, предоставив ему собственный шейдер (shader.fsh)Использование шейдеров Shadertoy в построителе интерфейса (Xcode)

В то время как работают очень простые шейдеры:

void main() { 
    gl_FragColor = vec4(0.0,1.0,0.0,1.0); 
} 

Любая попытка я сделать, чтобы преобразовать шейдеры из ShaderToy вызывают Xcode замерзать (спиннинг цвета шар), как только попытка сделать их.

Шейдер Я работаю с, например, является this one:

#define M_PI 3.1415926535897932384626433832795 

float rand(vec2 co) 
{ 
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 
} 

void mainImage(out vec4 fragColor, in vec2 fragCoord) 
{ 
    float size = 30.0; 
    float prob = 0.95; 

    vec2 pos = floor(1.0/size * fragCoord.xy); 

    float color = 0.0; 
    float starValue = rand(pos); 

    if (starValue > prob) 
    { 
     vec2 center = size * pos + vec2(size, size) * 0.5; 

     float t = 0.9 + 0.2 * sin(iGlobalTime + (starValue - prob)/(1.0 - prob) * 45.0); 

     color = 1.0 - distance(fragCoord.xy, center)/(0.5 * size); 
     color = color * t/(abs(fragCoord.y - center.y)) * t/(abs(fragCoord.x - center.x)); 
    } 
    else if (rand(fragCoord.xy/iResolution.xy) > 0.996) 
    { 
     float r = rand(fragCoord.xy); 
     color = r * (0.25 * sin(iGlobalTime * (r * 5.0) + 720.0 * r) + 0.75); 
    } 

    fragColor = vec4(vec3(color), 1.0); 
} 

Я пробовал:

  • Замена mainImage() с основной (пустоте) (так что она будет называться)
  • Замена переменных iXxxxx (iGlobalTime, iResolution) и переменных fragCoord со связанными с ними переменными (на основе предложений here)
  • Замена некоторых переменных (iGlobalTime) ...

При изменении mainImage в основной() и замена из переменных получил его на работу без ошибок в режиме реального времени TinyShading тестер приложение - результат всегда один и тот же в Xcode (вращающийся шар, замораживание). Любой совет здесь был бы полезен, поскольку на данный момент имеется довольно мало информации.

+0

Любые новости по этому вопросу? – salocinx

+0

@salocinx - Я бы отказался от этого. У вас такие же проблемы? – BadPirate

+1

Не совсем те же проблемы ... Я попытался скомпилировать этот файл: https://www.shadertoy.com/view/MtB3zW, как вы предложили, и я также прочитал связанные страницы. Я также заменил каждое неизвестное поле соответствующими аналогами, а также соответствующим образом изменил подпись основного. Но я получаю некоторые ошибки «не-const ссылки не могут связываться с векторным элементом». X-Code до сих пор не зависает с простыми шейдерами, но функции матрицы шейдеров, похоже, реализованы иначе, чем в шейдерном языке WebGL ... Apple сделала это иначе, чем остальная часть мира - еще раз ...; -) – salocinx

ответ

3

Мне удалось получить эту работу в SpriteKit, используя SKShader. Я смог отобразить каждый шейдер ShaderToy, который я пытался сделать до сих пор. Единственное исключение заключается в том, что вы должны удалить любой код с помощью iMouse, так как в iOS нет мыши. Я сделал следующее ...

1) Измените объявление функцию в ShaderToy для ...

void main(void) { 
    ... 
} 

функция ShaderToy имеет вход с именем fragCoord. В iOS это глобально доступно как gl_FragCoord, поэтому ваша функция main больше не нуждается в каких-либо входах.

2) сделать замену все, чтобы изменить следующие из их названия ShaderToy их имена IOS ...

  • fragCoord становится gl_FragCoord
  • fragColor становится gl_FragColor
  • iGlobalTime становится u_time

Примечание: Есть еще что я еще не встречал.Я буду обновлять, как я

3) Предоставление iResolution немного сложнее ...

iResolution является размер видового экрана (в пикселях), что в переводе на размер спрайтов в SpriteKit. Это было доступно как u_sprite_size в iOS, но было удалено. К счастью, Apple представляет собой хороший пример того, как вводить его в ваш шейдер, используя uniforms в своем SKShader documentation.

Однако, как указано в разделе Shader Inputs ShaderToy, тип iResolution является vec3 (х, у, г), в отличие от u_sprite_size, который vec2 (х и у). Мне еще предстоит увидеть один ShaderToy, который использует значение ziResolution. Таким образом, мы можем просто использовать значение z, равное нулю. Я изменил пример в документации Apple, чтобы обеспечить мой шейдер iResolution типа vec3 как так ...

let uniformBasedShader = SKShader(fileNamed: "YourShader.fsh") 

let sprite = SKSpriteNode() 
sprite.shader = uniformBasedShader  

let spriteSize = vector_float3(
    Float(sprite.frame.size.width), // x     
    Float(sprite.frame.size.height), // y 
    Float(0.0)      // z - never used 
) 

uniformBasedShader.uniforms = [  
    SKUniform(name: "iResolution", vectorFloat3: spriteSize) 
] 

Вот это :)

0

Вот изменения в шейдер, который работает при загрузке в качестве шейдер с быстрым:

#define M_PI 3.1415926535897932384626433832795 

float rand(vec2 co); 

float rand(vec2 co) 
{ 
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 
} 

void main() 
{ 
    float size = 50.0; //Item 1: 
    float prob = 0.95; //Item 2: 

    vec2 pos = floor(1.0/size * gl_FragCoord.xy); 

    float color = 0.0; 
    float starValue = rand(pos); 

    if (starValue > prob) 
    { 
     vec2 center = size * pos + vec2(size, size) * 0.5; 

     float t = 0.9 + 0.2 * sin(u_time + (starValue - prob)/(1.0 - prob) * 45.0); //Item 3: 

     color = 1.0 - distance(gl_FragCoord.xy, center)/(0.9 * size); 
     color = color * t/(abs(gl_FragCoord.y - center.y)) * t/(abs(gl_FragCoord.x - center.x)); 
    } 
    else if (rand(v_tex_coord) > 0.996) 
    { 
     float r = rand(gl_FragCoord.xy); 
     color = r * (0.25 * sin(u_time * (r * 5.0) + 720.0 * r) + 0.75); 
    } 

    gl_FragColor = vec4(vec3(color), 1.0); 
} 

Play с пунктом 1: увеличить количество звезд на небе меньше число, тем больше звезд мне нравится номер, чтобы быть около 50 не слишком густая Пункт 2: изменяет хаотичность или как близко друг к другу звезды появятся 1 = нет, 0,1 = бок о бок около 0,75 дает приятное ощущение.

Пункт 3, где большая часть магии случается, это размер и пульс звезд.

float t = 0.9 

Изменение 0,9, увеличатся начальная звезда подписать вверх или вниз хорошее значение 1.4 не слишком большой, не слишком мало.

float t = 0.9 + 0.2 

Изменение второго значения в этом уравнении 0.2, будет увеличивать ширину импульса эффекта звезд пропорционально к исходному размеру мне нравится с 1.4 значением 1.2.

Чтобы добавить затенение к вашему быстрому проекта добавить спрайт на сцену размер экрана затем добавьте затенение, как это:

let backgroundImage = SKSpriteNode() 
backgroundImage.texture = textureAtlas.textureNamed("any) 
    backgroundImage.size = screenSize 


     let shader = SKShader(fileNamed: "nightSky.fsh") 
     backgroundImage.shader = shader