将ShaderToy转换为片段着色器

时间:2016-07-06 04:21:32

标签: android iphone opengl-es fragment-shader

我在ShaderToy上遇到了几个着色器,我没有成功将它们转换为可在移动设备上使用的格式,例如android.widget.radiobutton

我有this Shader,我希望能够在移动设备上使用它。

我知道我需要修改iXXXX变量并将mainImage更改为main()。

有谁知道我怎么做到这一点?我无法找到有关如何执行此操作的任何资源,也从未遇到过。

.fsh

2 个答案:

答案 0 :(得分:4)

我写了main()并在答案的底部包含了ShaderToys变量的Sprite等效变量。

<强>设置

要将着色器应用于节点,您需要告诉SpriteKit将着色器附加到.fsh文件中的SKSpriteNode。

  1. 为着色器代码创建以.fsh结尾的空文本文件。
  2. 混合

    <强> shader1.fsh

    void main() {
    
    vec4 val = texture2D(_texture, v_tex_coord);
    vec4 grad = texture2D(u_gradient, v_tex_coord);
    
    if (val.a < 0.1 && grad.r < 1.0 && grad.a > 0.8) {
    vec2 uv = gl_FragCoord.xy / u_sprite_size.xy;
    uv = screenDistort(uv);
    vec3 video = getVideo(uv);
    float vigAmt = 3.+.3*sin(u_time + 5.*cos(u_time*5.));
    float vignette = (1.-vigAmt*(uv.y-5)*(uv.y-5.))*(1.-vigAmt*(uv.x-.5)*(uv.x-.5));
    
    video += stripes(uv);
    video += noise(uv*2.)/2.;
    video *= vignette;
    video *= (12.+mod(uv.y*30.+u_time,1.))/13.;
    
    gl_FragColor = vec4(video,1.0);
    
    } else {
     gl_FragColor = val;
    }
    
    } // end of main()
    
    1. 接下来,在SpriteKit中附加着色器。
    2. <强> shader1.swift

      let sprite = self.childNodeWithName("targetSprite") as! SKSpriteNode
      let shader = SKShader(fileNamed: "shader1.fsh")
      sprite.shader = shader
      

      说明

      • 着色器将每个像素变为效果的颜色(screenDistort(uv))。
      • main()是切入点。
      • gl_FragColor是回归。
      • 对于图像的每个像素,执行此代码。
      • 当代码执行时,它告诉每个像素颜色应该是效果的颜色。 vec4()调用有一个r,g,b,一个值。

      ShaderToys变量名称 - &gt; SpriteKit变量名称

      iGlobalTime - &gt; u_time

      iResolution - &gt; u_sprite_size

      fragCoord.xy - &gt; gl_FragCoord.xy

      iChannelX - &gt; SKUniform with name of “iChannelX” containing SKTexture

      fragColor - &gt; gl_FragColor

      由于您拥有Sprite等效变量,现在可以轻松转换高于main()的其余方法。

      float noise {}

      float onOff {}

      float ramp {}

      float stripes {}

      vec3 getVideo {}

      vec2 screenDistort {}

      理论

      Q值。为什么main()包含texture2Du_gradient, v_tex_coord

      一个。 SpriteKit使用纹理和紫外线坐标。

      UV映射

      UV贴图是将2D图像投影到3D模型表面进行纹理贴图的3D建模过程。

      紫外线坐标

      在对网格进行纹理处理时,您需要一种方法告诉OpenGL图像的哪个部分必须用于每个三角形。这是通过UV坐标完成的。每个顶点在其位置顶部可以有一对浮点数U和V.这些坐标用于访问和扭曲纹理。

      SKShader Class Reference

      OpenGL ES for iOS

      Best Practices for Shaders

      WWDC Session 606 - What's New in SpriteKit - Shaders, Lighters, Shadows

答案 1 :(得分:0)

这在unity3D引擎中适用于我。

child: new AnimatedBuilder(
  animation: _controller,
  child: new Image.network(widget.url),
  builder: (BuildContext context, Widget child) {
    return new Transform.rotate(
      angle: _controller.value * 2.0 * math.PI,
      child: child,
    );
  },
),