めくるめくシェーダーアートの世界/The World of Dazzling Shader Art

56ffef8ea4a48c8560b825f7f14ef4a9?s=47 ta_ka_tsu
September 06, 2019

めくるめくシェーダーアートの世界/The World of Dazzling Shader Art

iOSDC2019

56ffef8ea4a48c8560b825f7f14ef4a9?s=128

ta_ka_tsu

September 06, 2019
Tweet

Transcript

  1. 8.

    ࣗݾ঺հ࠷ۙϋϚ͍ͬͯΔ͜ͱ ݪཧɿ $ 0ˠ$0 'F0ʴ$0ˠ'F $0 ໦୸Λ೩΍ͯ͠ൃੜ͢ΔҰࢎԽ୸ૉ͕ ࠭మ ࢎԽమ Λؐݩ͢Δ͜ͱͰమʹͳΔɻ

    ຊདྷమͷ༥఺͸ˆ͕ͩɺ໦୸ʹ઀͠ ͍ͯΔˍෆ७෺ΛؚΉ͜ͱʹΑΓڽݻ఺ ߱Լ͕ى͜ΓɺΑΓ௿͍Թ౓Ͱ༹༥͠࿍ ͷఈͰమմͱͳΔɻ
  2. 11.

    ࣗݾ঺հ࠷ۙϋϚ͍ͬͯΔ͜ͱ ࢀߟจݙɿ ɾӬా࿨޺ɹ  ɹΠν͔Β࡞Δమ ೶ࢁړଜจԽڠձ ɾӬా࿨޺ɹ  ɹਓ͸ͲͷΑ͏ʹమΛ࡞͖͔ͬͯͨ ߨஊࣾ

    ɾڥɹஐ༸ɹϨϯΨࣜͨͨΒ੡మ࿍ʹΑΔమͮ͘Γ IUUQXXXUPSBZTGPSKQBDUJWJUZTDJFODF@FEVQEGI@QEG ɾᜊ౻౒ɾࡔຊູɾߴ௩ल࣏ɹ౛ঊ͕ܧঝ͢Δ఻౷ٕज़ͷࣗવՊ ֶతௐࠪ IUUQTXXXSFLJIBLVBDKQPVUMJOFQVCMJDBUJPOSPOCVOSPOCVOQEG QEG
  3. 12.
  4. 14.
  5. 43.
  6. 44.
  7. 45.
  8. 47.
  9. 48.

    #include <metal_stdlib> using namespace metal; fragment float4 Basic1(float4 pixPos [[position]])

    { return float4(1.0, 0.0, 0.0, 1.0); } ૊ΈࠐΈؔ਺ͷΠϯΫϧʔυ جຊฤ
  10. 49.

    #include <metal_stdlib> using namespace metal; fragment float4 Basic1(float4 pixPos [[position]])

    { return float4(1.0, 0.0, 0.0, 1.0); } ໊લۭؒNFUBMΛ࢖͏ͱ͍͏એݴ جຊฤ
  11. 50.

    #include <metal_stdlib> using namespace metal; fragment float4 Basic1(float4 pixPos [[position]])

    { return float4(1.0, 0.0, 0.0, 1.0); } ϑϥά ϝϯτγΣʔμ ʔ༻ͷؔ਺Ͱ͋Δͱ͍͏ؔ਺ଐੑ جຊฤ
  12. 51.

    #include <metal_stdlib> using namespace metal; fragment float4 Basic1(float4 pixPos [[position]])

    { return float4(1.0, 0.0, 0.0, 1.0); } ϥελϥΠβ͔Β౉͞ΕΔϐΫηϧ࠲ඪͰ͋Δ͜ͱΛࣔ͢ Ҿ਺ଐੑ جຊฤ
  13. 52.

    #include <metal_stdlib> using namespace metal; fragment float4 Basic1(float4 pixPos [[position]])

    { return float4(1.0, 0.0, 0.0, 1.0); } ೖྗͱͳΔϐΫηϧ࠲ඪΛ֨ೲ͢Δม਺ جຊฤ
  14. 53.

    #include <metal_stdlib> using namespace metal; fragment float4 Basic1(float4 pixPos [[position]])

    { return float4(1.0, 0.0, 0.0, 1.0); } ϑϥά ϝϯτγΣʔμ ʔͷؔ਺໊ جຊฤ
  15. 54.

    let library = device.makeDefaultLibrary() let fragmentFunction = library.makeFunction(name:”Basic1”) . .

    . let pipelineDescriptor = MTLRenderPipelineDescriptor() pipelineDescriptor.fragmentFunction = fragmentFunction . . . $16ଆͰؔ਺໊͔Β.5-'VODUJPOΛऔಘ͠ ύΠϓϥΠϯͷϑϥά ϝϯτγΣʔμ ʔͱͯ͠ઃఆ͓ͯ͘͠ جຊฤ
  16. 56.

    float bool int char short uchar uint ushort half size_t

    ptrdiff_t void ˞MPOHVOTJHOFEMPOH͸.FUBMҎ߱Ͱαϙʔτ ˞EPVCMFMPOHMPOHVOTJHOFEMPOHMPOHMPOHEPVCMF͸ະαϙʔτ جຊฤ .4-ͷεΧϥʔܕ
  17. 57.

    float2 float3 float4 bool2 bool3 bool4 int2 int3 int4 char2

    char3 char4 short2 short3 short4 uchar2 uchar3 uchar4 uint2 uint3 uint4 ushort2 ushort3 ushort4 half2 half3 half4 جຊฤ .4-ͷϕΫτϧܕ
  18. 58.

    .4-ͷϕΫτϧܕ֤ίϯϙʔωϯτ΁ͷΞΫηε float4 vec(1.0, 2.0, 3.0, 4.0); float a = vec.x;

    // 1.0 float b = vec.y; // 2.0 float c = vec.z; // 3.0 float d = vec.w; // 4.0 float e = vec.r; // 1.0 float f = vec.g; // 2.0 float g = vec.b; // 3.0 float h = vec.a; // 4.0 vec.x = 3.0; // (3.0, 2.0, 3.0, 4.0) float i = vec.r; // 3.0 جຊฤ
  19. 59.

    float4 vec1(4.0, 4.0, 4.0, 4.0); float4 vec2(1.0, 2.0, 4.0, 8.0);

    float4 v1 = vec1 + vec2; // (5.0, 6.0, 8.0, 12.0) float4 v2 = vec1 - vec2; // (3.0, 2.0, 0.0, -4.0) float4 v3 = vec1 * vec2; // (4.0, 8.0, 16.0, 32.0) float4 v4 = vec1 / vec2; // (4.0, 2.0, 1.0, 0.5) .4-ͷϕΫτϧܕՃݮ৐আ جຊฤ
  20. 60.

    float4 vec(1.0, 2.0, 3.0, 4.0); float4 v1 = vec +

    2.0; // (3.0, 4.0, 5.0, 6.0) float4 v2 = vec - 2.0; // (-1.0, 0.0, 1.0, 2.0) float4 v3 = vec * 2.0; // (2.0, 4.0, 6.0, 8.0) float4 v4 = vec / 2.0; // (0.5, 1.0, 1.5, 2.0) vec = 1.0; // (1.0, 1.0, 1.0, 1.0) .4-ͷϕΫτϧܕεΧϥʔܕͱͷՃݮ৐আ جຊฤ
  21. 61.

    half2x2 half2x3 half2x4 float2x2 float2x3 float2x4 half3x2 half3x3 half3x4 half4x2

    half4x3 half4x4 float3x2 float3x3 float3x4 float4x2 float4x3 float4x4 .4-ͷߦྻܕ ໊લۭؒNFUBM಺ جຊฤ
  22. 64.
  23. 66.

    .4-ͷϕΫτϧܕ4XJ[[MJOH float4 vec(1.0, 2.0, 3.0, 4.0); vec.xy; // (1.0, 2.0)

    vec.zwx; // (3.0, 4.0, 1.0) vec.xxxy; // (1.0, 1.0, 1.0, 2.0) vec.ra; // (1.0, 4.0) vec.rgb; // (1.0, 2.0, 3.0) vec.xyb; // compile error! vec.xy = float2(0.0, 1.0); // (0.0, 1.0, 3.0, 4.0) vec.xxy = float3(5.0, 4.0, 3.0); // compile error! جຊฤ
  24. 68.

    MFOHUIؔ਺ ϕΫτϧYͷ௕͞Λฦ͢ float2 vec2d(3.0, 4.0); length(vec2d); // 5.0 float3 vec3d(1.0,

    1.0, 1.0); length(vec3d); // 1.732… P W MFOHUI W ؔ࿈ɿEJTUBODFؔ਺EJTUBODF Q Q MFOHUI QQ Ts length(T x) جຊฤ
  25. 70.

    DMBNQؔ਺ YΛNJO7ʙNBY7ͷൣғʹΫϥϯϓ͢Δ NJO7ʽNBY7 clamp(0.6, 0.0, 1.0); // 0.6 clamp(-0.3, 0.0,

    1.0); // 0.0 clamp(1.2, 0.0, 1.0); // 1.0 DMBNQ Y NJO7 NBY7 NJO NBY Y NJO7 NBY7 T clamp(T x, T minV, T maxV) جຊฤ
  26. 71.

    9 :   8JEUI   )FJHIU 8JEUI )FJHIU

    ϐΫηϧ࠲ඪܥ جຊฤ
  27. 74.
  28. 76.

    TUFQؔ਺ Y͕FEHFҎ্ͷ৔߹ʹΛ ͦΕҎ֎ͷ৔߹͸Λฦؔ͢਺ step(0.5, 1.0); // 1.0 step(0.5, 0.3); //

    0.0 step(0.5, 0.5); // 1.0 TUFQ  Y ͷάϥϑ T step(T edge, T x) جຊฤ
  29. 79.
  30. 81.

    TNPPUITUFQؔ਺ Y͕FҎԼͷ৔߹͸ FҎ্ͷ৔߹͸Λฦ͢ɻ ͦͷؒͷ৔߹͸Τϧϛʔτิؒ ˞ ͨ݁͠ՌΛฦ͢ɻ FʻF smoothstep(0.5, 1.0, 1.2);

    // 1.0 smoothstep(0.5, 1.0, 0.2); // 0.0 smoothstep(0.5, 1.0, 0.6); // 0.104 smoothstep(0.5, 1.0, 0.9); // 0.896 T smoothstep(T e1, T e2, T x) ˞۠ؒ [e1 , e2 ] 3( x − e1 e2 − e1 )2 − 2( x − e1 e2 − e1 )3 ͷ x ʹରͯ͠͸ Λฦ͢ جຊฤ
  31. 84.

    fragment float4 Basic5(float4 pixPos[[position]]) { float4 red(1.0, 0.0, 0.0, 1.0);

    float4 green(0.0, 1.0, 0.0, 1.0); float m1 = smoothstep(300.0, 400.0, length(pixPos.xy)); return mix(red, green, m1); } جຊฤ
  32. 85.
  33. 86.

    fragment float4 Basic5(float4 pixPos[[position]]) { float4 red(1.0, 0.0, 0.0, 1.0);

    float4 green(0.0, 1.0, 0.0, 1.0); float m1 = smoothstep(300.0, 400.0, length(pixPos.xy)); return mix(red, green, m1); } جຊฤ NJYؔ਺
  34. 87.

    NJYؔ਺ YͱZͷؒΛBͰઢܗิؒ ˞ ͢Δؔ਺ ʽBʽ  mix(10.0, 20.0, 0.5); //

    15.0 mix(100.0, 50.0, 0.2); // 90.0 mix(10, -10.0, 0.6); // -2.0 T mix(T x, T y, T a) NJY   Y ͷάϥϑ جຊฤ
  35. 88.

    fragment float4 Basic5(float4 pixPos[[position]]) { float4 red(1.0, 0.0, 0.0, 1.0);

    float4 green(0.0, 1.0, 0.0, 1.0); float m1 = smoothstep(300.0, 400.0, length(pixPos.xy)); return mix(red, green, m1); } جຊฤ
  36. 90.

    fragment float4 Basic5(float4 pixPos[[position]]) { float4 red(1.0, 0.0, 0.0, 1.0);

    float4 green(0.0, 1.0, 0.0, 1.0); float m1 = smoothstep(300.0, 400.0, length(pixPos.xy)); return mix(red, green, m1); } جຊฤ NJYؔ਺
  37. 91.
  38. 92.

    fragment float4 Basic6(float4 pixPos[[position]]) { float4 red(1.0, 0.0, 0.0, 1.0);

    float4 green(0.0, 1.0, 0.0, 1.0); float4 blue(0.0, 0.0, 1.0, 1.0); float m1 = smoothstep(300.0, 400.0, length(pixPos.xy)); float4 col = mix(red, green, m1); float m2 = step(500.0, length(pixPos.xy)); col = mix(col, blue, m2); return col; } جຊฤ
  39. 100.

    // όοϑΝͷ࡞੒ resolutionBuffer = device.makeBuffer(length: 2 *ɹMemoryLayout<Float>.size, options: []) .

    . . // όοϑΝ΁ղ૾౓Λॻ͖ࠐΈ memcpy(resolutionBuffer.contents(), [width, height], 2 * MemoryLayout<Float>.size) . . . // ϑϥάϝϯτγΣʔμʔͷόοϑΝͱͯ͠ઃఆ renderEncoder.setFragmentBuffer(resolutionBuffer, offset: 0, index: 0) ࠲ඪม׵ͱਖ਼نԽ
  40. 101.

    // όοϑΝͷ࡞੒ resolutionBuffer = device.makeBuffer(length: 2 *ɹMemoryLayout<Float>.size, options: []) .

    . . // όοϑΝ΁ղ૾౓Λॻ͖ࠐΈ memcpy(resolutionBuffer.contents(), [width, height], 2 * MemoryLayout<Float>.size) . . . // ϑϥάϝϯτγΣʔμʔͷόοϑΝͱͯ͠ઃఆ renderEncoder.setFragmentBuffer(resolutionBuffer, offset: 0, index: 0) ࠲ඪม׵ͱਖ਼نԽ
  41. 102.

    fragment float4 Hogehoge(float4 pixPos [[position]], constant float2& res [[buffer(0)]]) {

    . . . } όοϑΝ͔Β౉͞ΕΔ஋Ͱ͋Δ͜ͱΛࣔ͢ Ҿ਺ଐੑ ࠲ඪม׵ͱਖ਼نԽ
  42. 103.

    fragment float4 Hogehoge(float4 pixPos [[position]], constant float2& res [[buffer(0)]]) {

    . . . } όοϑΝ͔Β౉͞ΕΔ஋͸ ࢀরܕ͔ϙΠϯλܕͰड͚औΒͳ͚Ε͹ͳΒͳ͍ ࠲ඪม׵ͱਖ਼نԽ
  43. 104.

    fragment float4 Hogehoge(float4 pixPos [[position]], constant float2& res [[buffer(0)]]) {

    . . . } .4-Ͱ͸ࢀরܕ΍ϙΠϯλܕʹ͸ ΞυϨεۭؒम০ࢠ͕ඞཁ ࠲ඪม׵ͱਖ਼نԽ
  44. 105.

    fragment float4 CodSys1(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; return step(length(uv), 1.0); } ࠲ඪม׵ͱਖ਼نԽ
  45. 107.

    fragment float4 CodSys1(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; return step(length(uv), 1.0); } ࠲ඪม׵ͱਖ਼نԽ
  46. 108.

    9   8JEUI   )FJHIU 8JEUI )FJHIU ϐΫηϧ࠲ඪܥ

    pixPos.xy : ࠲ඪม׵ͱਖ਼نԽ
  47. 109.

      8JEUI   )FJHIU 8JEUI )FJHIU ࠲ඪ஋Λഒ͢Δ 2.0

    * pixPos.xy ࠲ඪม׵ͱਖ਼نԽ  8JEUI  )FJHIU
  48. 110.

      8JEUI   )FJHIU 8JEUI )FJHIU 2.0 *

    pixPos.xy - res ղ૾౓ΛҾ͘ 8JEUI )FJHIU ࠲ඪม׵ͱਖ਼نԽ
  49. 111.

            (2.0 *

    pixPos.xy - res)/min(res.x, res.y) ղ૾౓ͷখ͍͞ํͰׂΔ   ࠲ඪม׵ͱਖ਼نԽ
  50. 112.

            float2 uv

    = (2.0 * pixPos.xy - res)/min(res.x, res.y) uv.y *= -1.0 :࠲ඪΛ൓సͤ͞Δ           ࠲ඪม׵ͱਖ਼نԽ
  51. 113.

             

            ࠲ඪม׵ͱਖ਼نԽ
  52. 123.

    fragment float4 Polar1(float4 pixPos [[position]], constant float2 &res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; float theta = atan2(uv.y, uv.x); float threshold = 0.5*sin(5 * theta) + 0.5; return step(length(uv), threshold); } ۃ࠲ඪͷར༻
  53. 125.

    θ ภ֯ͷ஋ʹΑ͖͍ͬͯ͠஋Λม͍͑ͯΔ float theta = atan2(uv.y, uv.x); float threshold =

    0.5*sin(5 * theta) + 0.5; return step(length(uv), threshold); ۃ࠲ඪͷར༻
  54. 126.

    θ ͖͍͠஋ͷม͑ํͰ৭ʑͳܗʹ float theta = atan2(uv.y, uv.x); float threshold =

    0.2*sin(5 * theta) + 0.8; return step(length(uv), threshold); ۃ࠲ඪͷར༻
  55. 127.

    θ ͖͍͠஋ͷม͑ํͰ৭ʑͳܗʹ float theta = atan2(uv.y, uv.x); float threshold =

    0.1*step(sin(20 * theta), 0.0) + 0.9; return step(length(uv), threshold); ۃ࠲ඪͷར༻
  56. 130.

    fragment float4 Animation1(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; float theta = atan2(uv.y, uv.x) - time; float threshold = 0.2*sin(5 * theta) + 0.8; return step(length(uv), threshold); } Ξχϝʔγϣϯ
  57. 131.

    fragment float4 Animation1(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; float theta = atan2(uv.y, uv.x) - time; float threshold = 0.2*sin(5 * theta) + 0.8; return step(length(uv), threshold); } Ξχϝʔγϣϯ
  58. 133.

    float theta = atan2(uv.y, uv.x); float amp = 0.2 *

    sin(time); float threshold = amp*sin(5 * theta) + 0.8; return step(length(uv), threshold); Ξχϝʔγϣϯ
  59. 136.
  60. 137.

    fragment float4 Replication1(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2.0; uv = fract(uv) * 2.0 - 1.0; float theta = atan2(uv.y, uv.x) - time; float threshold = 0.2*sin(5 * theta) + 0.8; return step(length(uv), threshold); } ෳ੡
  61. 138.
  62. 139.
  63. 143.
  64. 146.

    GSBDU         

    GSBDU      ෳ੡
  65. 147.

    ෳ੡ fragment float4 Replication1(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant

    float& time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 5.0; uv = fract(uv) * 2.0 - 1.0; float theta = atan2(uv.y, uv.x) - time; float threshold = 0.2*sin(5 * theta) + 0.8; return step(length(uv), threshold); }
  66. 148.
  67. 150.

    fragment float4 Id1(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2.0; uv = fract(uv) * 2.0 - 1.0; return step(length(uv), 1.0); } ෳ੡ͷࣝผ
  68. 152.

    fragment float4 Id2(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2.0; float2 id = floor(uv); uv = fract(uv) * 2.0 - 1.0; float threshold = exp(-length(id)); return step(length(uv), threshold); } ෳ੡ͷࣝผ
  69. 154.

    fragment float4 Id2(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2.0; float2 id = floor(uv); uv = fract(uv) * 2.0 - 1.0; float threshold = exp(-length(id)); return step(length(uv), threshold); } ෳ੡ͷࣝผ
  70. 157.

    floor(2.0 * uv)       

                                                             ෳ੡ͷࣝผ
  71. 158.

    ෳ੡ͷࣝผ fragment float4 Id2(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) {

    float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2.0; float2 id = floor(uv); uv = fract(uv) * 2.0 - 1.0; float threshold = exp(-length(id)); return step(length(uv), threshold); }
  72. 167.

    float N11(float v) { return fract(sin(v)*43758.5453123); } fragment float4 Noise1(float4

    pixPos [[position]], constant float2& res[[buffer(0)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; return N11(uv.x); } ٙࣅཚ਺
  73. 169.

    float N21(float2 p) { return N11(dot(p, float2(12.9898, 78.233))); } fragment

    float4 Noise2(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; return N21(uv); } ٙࣅཚ਺ ˞EPU W W ɿϕΫτϧͷ಺ੵΛऔΔؔ਺
  74. 171.

    fragment float4 Noise3(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; uv *= 4.0; float2 id = floor(uv); return N21(id); } ٙࣅཚ਺
  75. 173.

    fragment float4 Noise4(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; uv *= 4.0; float2 id = floor(uv); uv = fract(uv)*2.0 - 1.0; float r = N21(id); return step(length(uv), r); } ٙࣅཚ਺
  76. 176.

  77. 177.

    fragment float4 Color1(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; float2 id = floor(4*uv); float r = N21(id); float g = N21(id + float2(123.34, 32.34)); float b = N21(id + float2(23.0, 342.0)); return float4(r, g, b, 1.0); } ৭
  78. 178.

  79. 180.

    float3 hsv2rgb(float h, float s, float v) { float3 a

    = fract(h + float3(0.0, 2.0, 1.0)/3.0)*6.0-3.0; a = clamp(abs(a) - 1.0, 0.0, 1.0) - 1.0; a = a*s + 1.0; return a*v; } ৭ ৭૬ ࠼౓ ໌౓ )47৭ۭؒΛ࢖͏ ˞I T W͸શͯʙͷ஋
  80. 181.

    fragment float4 Color2(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; float2 id = floor(4*uv); float h = N21(id); float3 rgb = hsv2rgb(h, 1.0, 1.0); return float4(rgb, 1.0); } ৭
  81. 182.

  82. 183.

    fragment float4 Color3(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; float2 id = floor(4*uv); float h = N21(id); float3 rgb = hsv2rgb(h, 0.7, 1.0); return float4(rgb, 1.0); } ৭
  83. 184.

  84. 185.

    fragment float4 Color4(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv *= -1.0; float2 id = floor(4*uv); float h = N21(id); float3 rgb = hsv2rgb(fract(h + 0.2*time), 0.7, 1.0); return float4(rgb, 1.0); } ৭
  85. 186.

  86. 187.

  87. 189.

    float grid(float2 p) { float g = 0.0; p =

    fract(p); g = max(g, step(0.98, p.x)); g = max(g, step(0.98, p.y)); return g; } fragment float4 Distorted1(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2; float4 red(1.0, 0.0, 0.0, 1.0); return red * grid(uv); } ۭؒΛ࿪ΊΔ
  88. 191.

    fragment float4 Distorted2(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2; uv.x += sin(uv.y); float4 red(1.0, 0.0, 0.0, 1.0); return red * grid(uv); } ۭؒΛ࿪ΊΔ
  89. 193.

    fragment float4 Distorted3(float4 pixPos [[position]], constant float2& res[[buffer(0)]]) { float2

    uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2; uv.x += sin(uv.y); uv.y += sin(uv.x); float4 red(1.0, 0.0, 0.0, 1.0); return red * grid(uv); } ۭؒΛ࿪ΊΔ
  90. 195.

    fragment float4 Distorted4(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2; uv.x += 0.5 * sin(uv.y + time) + 0.5; uv.y += 0.5 * sin(uv.x + time) + 0.5; float4 red(1.0, 0.0, 0.0, 1.0); return red * grid(uv); } ۭؒΛ࿪ΊΔ
  91. 197.

    fragment float4 Distorted5(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2; uv *= 1.0 + (0.1 * sin(time) + 0.1) * length(uv); float4 red(1.0, 0.0, 0.0, 1.0); return red * grid(uv); } ۭؒΛ࿪ΊΔ
  92. 199.

    fragment float4 Distorted6(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]]) { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; uv *= 2; uv.x += 0.5 * sin(uv.y + time) + 0.5; uv.y += 0.5 * sin(uv.x + time) + 0.5; uv = fract(uv); uv -= 0.5; float theta = atan2(uv.y, uv.x); float threshold = 0.25*sin(5*theta)+0.25; return step(length(uv), threshold); } ۭؒΛ࿪ΊΔ
  93. 201.
  94. 203.

    // όοϑΝͷ࡞੒ imageTexture = try! textureLoader.newTexture(name: “icon", scaleFactor: 1.0, bundle:

    nil, options: [.SRGB: false]) . . . // ϑϥάϝϯτγΣʔμʔͷόοϑΝͱͯ͠ઃఆ renderEncoder.setFragmentTexture(imageTexture, index: 0) ςΫενϟ
  95. 204.

    // όοϑΝͷ࡞੒ imageTexture = try! textureLoader.newTexture(name: “icon", scaleFactor: 1.0, bundle:

    nil, options: [.SRGB: false]) . . . // ϑϥάϝϯτγΣʔμʔͷόοϑΝͱͯ͠ઃఆ renderEncoder.setFragmentTexture(imageTexture, index: 0) ςΫενϟ
  96. 206.

    fragment float4 Texture1(float4 pixPos [[position]], constant float2& res[[buffer(0)]], texture2d<float> tex[[texture(0)]])

    { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); uv.y *= -1.0; constexpr sampler s(address::clamp_to_edge, filter::linear); return image.sample(s, uv); } ςΫενϟ
  97. 207.
  98. 209.
  99. 210.

    fragment float4 Texture2(float4 pixPos [[position]], constant float2& res[[buffer(0)]], texture2d<float> tex[[texture(0)]])

    { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); // uv.y *= -1.0; constexpr sampler s(address::clamp_to_edge, filter::linear); return image.sample(s, uv); } ςΫενϟ
  100. 211.
  101. 212.

    fragment float4 Texture2(float4 pixPos [[position]], constant float2& res[[buffer(0)]], texture2d<float> tex[[texture(0)]])

    { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); // uv.y *= -1.0; constexpr sampler s(address::clamp_to_edge, filter::linear); return image.sample(s, uv); } ςΫενϟ
  102. 213.
  103. 214.

    fragment float4 Texture3(float4 pixPos [[position]], constant float2& res[[buffer(0)]], texture2d<float> tex[[texture(0)]])

    { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); constexpr sampler s(address::repeat, filter::linear); return image.sample(s, uv); } ςΫενϟ
  104. 215.
  105. 217.

    fragment float4 Texture4(float4 pixPos [[position]], constant float2& res[[buffer(0)]], texture2d<float> tex[[texture(0)]])

    { float2 uv = (2.0 * pixPos.xy - res)/min(res.x, res.y); constexpr sampler s(address::repeat, filter::linear); float idY = floor(uv.y * 40); float d = N11(idY); float offset = 0.1 * step(0.8, d); uv.x += offset; return image.sample(s, uv); } ςΫενϟ
  106. 218.
  107. 221.

    ௖఺ॲཧ ϥελϥΠζ ϑϥάϝϯτॲཧ ೖྗɿ௖఺ྻ ग़ྗɿը૾ όοϑΝ ը໘ղ૾౓ όοϑΝ ܦա࣌ؒ ςΫενϟ

    όοϑΝ Ճ଎౓ όοϑΝ ϚΠΫԻྔ ςΫενϟ Χϝϥը૾ όοϑΝ ࠷ޙʹ৮ͬͨ఺ ΠϯλϥΫγϣϯ
  108. 222.

    fragment float4 Sample(float4 pixPos [[position]], constant float2& res[[buffer(0)]], constant float&

    time[[buffer(1)]], constant float& volume[[buffer(2)]], constant float& accel[[buffer(3)]], constant float2& touch[[buffer(4)]], texture2d<float> tex[[texture(0)]], texture2d<float> cam[[texture(1)]]) { . . . } ΠϯλϥΫγϣϯ
  109. 223.