Slide 1

Slide 1 text

ProcessingϢʔβʔͷͨΊͷ γΣʔμʔΞʔτೖ໳ "UTVTIJ"TBLVSBBBEFCEFC !1$%5PLZP ࢿྉ63-IUUQTHJUIVCDPNBBEFCEFC1$%@5PLZP@@8PSLTIPQ

Slide 2

Slide 2 text

ࣗݾ঺հ • Atsushi Asakura / aadebdeb • ΫϦΤΠςΟϒίʔμʔ / ϓϩάϥϚʔ • 3D CGɺγϛϡϨʔγϣϯɺδΣωϥςΟϒΞʔτʹಛʹڵຯ͕͋Δ • Twitter • https://twitter.com/aa_debdeb • OpenProcessing • https://www.openprocessing.org/user/51764/ • NEORT • https://neort.io/itjyV7OFFeaAOMQKr6tkglED8TE3

Slide 3

Slide 3 text

಺༰ • 1. جૅ • γΣʔμʔͱ͸ʁ γΣʔμʔΞʔτͱ͸ʁ • γΣʔμʔݴޠ GLSL • ࡞ྫ (جૅฤ) • 2. ϥϯμϜ • Ұ༷ཚ਺ɺϒϩοΫϊΠζɺόϦϡʔϊΠζɺfbm • ࡞ྫ (ϥϯμϜฤ) • 3. ਤܗ • ූ߸෇͖ڑ཭ؔ਺ͱ͸ʁ • جૅతͳਤܗ (ԁ, ࢛֯ܗ) • Ҡಈɾճసɾεέʔϧ, ϒʔϦΞϯԋࢉ • ࡞ྫ (ਤܗฤ) • 4. 3D • ϨΠϚʔνϯά

Slide 4

Slide 4 text

໨ඪ ͳͷͰɺؾܰʹ࣭໰͍ͯͩ͘͠͞ʂʂ γΣʔμʔΞʔτΛࣗ෼Ͱௐ΂ͳ͕Β ੍࡞Ͱ͖ΔΑ͏ʹͳΔ

Slide 5

Slide 5 text

1. جૅ

Slide 6

Slide 6 text

γΣʔμʔͱ͸ GPUͰ࣮ߦ͞ΕΔϓϩάϥϜ ௖఺ܭࢉ΍ӄӨ(ϥΠςΟϯά)ܭࢉʹར༻͞ΕΔ ௖఺ γΣʔμʔ ϑϥάϝϯτ γΣʔμʔ ΦϒδΣΫτͷҠಈ, ճస, εέʔϧ Χϝϥ… ඳը݁Ռ ϐΫηϧͷ৭(ӄӨ)Λܭࢉ ϝογϡΛߏ੒͢Δ ϙϦΰϯͷදࣔҐஔΛܭࢉ ϝογϡ ϐΫηϧ৘ใ (Ґஔ, ๏ઢ…) ΦϒδΣΫτͷ৭, ςΫενϟ ϥΠτ… GPU 3DϨϯμϦϯάύΠϓϥΠϯ (Α͋͘ΔϦΞϧλΠϜ3D)

Slide 7

Slide 7 text

γΣʔμʔΞʔτͱ͸ ը໘Λ෴͏࢛֯ܗϝογϡʹϑϥάϝϯτγΣʔμʔ͚ͩͰֆΛඳ͘දݱ v.s. Processing / p5.js • ௕ॴ • ׈Β͔ͳදݱ΍ෳࡶͳදݱ͕ಘҙ • άϥσʔγϣϯ, 3D • ϦΞϧλΠϜʹಈ͘දݱ͕ಘҙ • ୹ॴ • ঢ়ଶΛ࣋ͯͳ͍ • e.g. Ґஔͱ଎౓Λ࣋ͬͨύʔςΟΫϧΈ͍ͨͳදݱ͸Ͱ͖ͳ͍ • زԿֶతͳਤܗදݱ͕ಘҙͰ͸ͳ͍ • ௚ײతͰ͸ͳ͍ Πϝʔδ (఺ઢ͸Χϝϥͷը֯)

Slide 8

Slide 8 text

ϓϥοτϑΥʔϜ / πʔϧ • GLSL Sandbox • ؾܰʹγΣʔμʔΛॻ͚ΔWebαʔϏε • http://glslsandbox.com/ • Shadertoy • γΣʔμʔք۾ͷ໠ऀ͕ू͏৔ॴ • https://www.shadertoy.com/ • NEORT • σδλϧΞʔτϓϥοτϑΥʔϜɺGLSL Sandboxޓ׵ • https://neort.io/ • glslfan • ίʔσΟϯάը໘ΛϦΞϧλΠϜڞ༗ɺGLSL Sandboxޓ׵ • https://glslfan.com/ • Visual Studio Code Shader Toy Extension • VS CodeͷShadertoy֦ுɺGLSL Sandboxܗࣜ΋αϙʔτ • https://marketplace.visualstudio.com/items?itemName=stevensona.shader-toy

Slide 9

Slide 9 text

GLSL (OpenGL Shading Language) • OpenGLͰ࢖ΘΕΔγΣʔμʔݴޠ • CݴޠΛϕʔεʹ͍ͯ͠Δ • ੍ޚߏจ • if, for… • ૊ΈࠐΈܕ • ੔਺: int • ුಈখ਺఺਺: float • ϕΫτϧ: vec2, vec3, vec4 • ߦྻ: mat2, mat3, mat4 • ςΫενϟ: sampler2D • … • ૊ΈࠐΈؔ਺ • sin, cos, min, max, step, smoothstep, mix …

Slide 10

Slide 10 text

GLSL Sandbox http://glslsandbox.com/ ʹΞΫηε

Slide 11

Slide 11 text

Hello, World! precision highp float; void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } ුಈখ਺఺਺ͷਫ਼౓ (ίϯύΠϧʹඞཁ) mainؔ਺ (ΤϯτϦϙΠϯτ) precision highp float; void main(void) { … } gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); ϐΫηϧͷ৭ red green blue alpha • ৭ͷൣғ͸ 0ʙ1 (Processingͱҧ͏!) • alpha(ಁ໌౓)͸ग़ྗʹӨڹ͠ͳ͍ • 1ΛೖΕ͓ͯ͘͜ͱ͕ଟ͍ ϑϥάϝϯτγΣʔμʔͰ΍Δ΂͖͜ͱ͸ gl_FragColorʹ৭(vec4)Λઃఆ͢Δ͜ͱ /src/ch1-basic/hello-world.glsl

Slide 12

Slide 12 text

ϕΫτϧ • ෳ਺ͷ஋Λ·ͱΊͨ΋ͷ • ProcessingͷPVector, p5.jsͷp5.Vectorʹ૬౰ • vec2 • 2࣍ݩ࠲ඪ (X, Y) • vec3 • 3࣍ݩ࠲ඪ (X, Y, Z) • ৭ (R, G, B) • vec4 • ಉ࣍࠲ඪ (γΣʔμʔΞʔτͷจ຺Ͱ͸͋·Γ࢖ΘΕͳ͍) • ৭ + ಁ໌౓ (R, G, B, A)

Slide 13

Slide 13 text

ϕΫτϧͷ࡞੒ɾ஋ͷऔಘ vec4(1.0, 2.0, 3.0, 4.0); vec4(vec2(1.0, 2.0), 3.0, 4.0); vec4(vec3(1.0, 2.0, 3.0), 4.0); vec4(vec2(1.0, 2.0), vec2(3.0, 4.0)); vec4(1.0, vec2(2.0, 3.0), 4.0); vec4(1.0, vec3(1.0, 2.0, 3.0)); vec4(vec4(1.0, 2.0, 3.0, 4.0)); vec4 v = vec4(1.0, 2.0, 3.0, 4.0); v.x; // = 1.0 v.y; // = 2.0 v.z; // = 3.0 v.w; // = 4.0 v.xy; // = vec2(1.0, 2.0) v.xx; // = vec2(1.0, 1.0) v.yx; // = vec2(2.0, 1.0) v.xz; // = vec2(1.0, 3.0) v.xyz; // = vec3(1.0, 2.0, 3.0) v.xyy; // = vec3(1.0, 2.0, 2.0) v.r; // 1.0 v.g; // 2.0 v.b; // 3.0 v.a; // 4.0 v.rgb; // vec3(1.0, 2.0, 3.0) ϕΫτϧͷ࡞੒ vec2, vec3Ͱ΋ಉ༷ SwizzleԋࢉࢠʹΑΔ஋ͷऔಘ ͢΂ͯͷ૊Έ߹ΘͤͰͳ͍ vec2, vec3Ͱ΋ಉ༷ /src/ch1-basic/vector.glsl

Slide 14

Slide 14 text

ϕΫτϧͷԋࢉ vec4 v = vec4(1.0, 2.0, 3.0, 4.0) v + 1.0; // = vec4(2.0, 3.0, 4.0, 5.0) v - 1.0; // = vec4(0.0, 1.0, 2.0, 3.0) v * 2.0; // = vec4(2.0, 4.0, 6.0, 8.0) v / 2.0; // = vec4(0.5, 1.0, 1.5, 2.0) 1.0 + v; // = vec4(2.0, 3.0, 4.0, 5.0) 1.0 - v; // = vec4(0.0, -1.0, -2.0, -3.0) 2.0 * v; // = vec4(2.0, 4.0, 6.0, 8.0) 2.0 / v; // = vec4(2.0, 1.0, 0.666..., 0.5) vec4 v1 = vec4(1.0, 2.0, 3.0, 4.0); vec4 v2 = vec4(5.0, 6.0, 7.0, 8.0); v1 + v2; // = vec4(6.0, 8.0, 10.0, 12.0) v1 - v2; // = vec4(-4.0, -4.0, -4.0, -4.0) v1 * v2; // = vec4(5.0, 12.0, 21.0, 32.0) v1 / v2; // = vec4(0.2, 0.333..., 0.429..., 0.5) //ҟͳΔେ͖͞ͷϕΫτϧಉ࢜Ͱ͸ԋࢉͰ͖ͳ͍ vec2(1.0, 2.0) + vec3(1.0, 2.0, 3.0); // ͜Ε͸ΤϥʔʹͳΔ εΧϥʔͱͷԋࢉ vec2, vec3Ͱ΋ಉ༷ ϕΫτϧಉ࢜ͷԋࢉ vec2, vec3Ͱ΋ಉ༷ /src/ch1-basic/vector.glsl

Slide 15

Slide 15 text

ϐΫηϧҐஔͷར༻ precision highp float; uniform vec2 resolution; void main(void) { vec2 pos = gl_FragCoord.xy / resolution; gl_FragColor = vec4(pos, 0.0, 1.0); } uniform vec2 resolution; ը໘ͷେ͖͞ vec2 pos = gl_FragCoord.xy / resolution; ݱࡏͷϐΫηϧҐஔ resolution͕vec2(400, 300)ͷͱ͖ gl_FragCoord.xy͸… (0, 0) (400, 300) (200, 150) /src/ch1-basic/frag-coord.glsl

Slide 16

Slide 16 text

p5.jsͰಉ͡ॲཧΛ࣮૷͢Δͱ… let img; let resolution; function setup() { createCanvas(640, 480); img = createImage(width, height); resolution = createVector(width, height); } function draw() { img.loadPixels(); for (let w = 0; w < width; w++) { for (let h = 0; h < height; h++) { const coord = createVector(w, h); const c = getPixel(coord, resolution); img.set(w, h, c); } } img.updatePixels(); image(img, 0, 0); } function getPixel(coord, resolution) { return color( 255 * coord.x / resolution.x, 255 * coord.y / resolution.y, 0.0 ); } /src/ch1-basic/p5-coord.js γΣʔμʔΞʔτͰ͸ ͜ͷ෦෼͚ͩΛॻ͍͍ͯΔ γΣʔμʔͰ͸2ॏϧʔϓ෦෼͕ GPUͰฒྻʹॲཧ͞ΕΔͷͰૣ͍

Slide 17

Slide 17 text

࠲ඪͷݪ఺ X Y (0, 0) GLSL Processing / p5.js ࠨԼ͕ݪ఺ ࠨ্͕ݪ఺ X Y (0, 0) ࠲ඪͷݪ఺͕ҧ͏ͷͰ஫ҙʂ

Slide 18

Slide 18 text

࣌ؒͷར༻ precision highp float; uniform vec2 resolution; uniform float time; void main(void) { vec2 pos = gl_FragCoord.xy / resolution; gl_FragColor = vec4(pos, sin(time) * 0.5 + 0.5, 1.0); } ࣌ؒ ɾɾɾ uniform float time; ܦաඵ਺ /src/ch1-basic/time.glsl

Slide 19

Slide 19 text

Ϛ΢εҐஔͷར༻ precision highp float; uniform vec2 mouse; void main(void) { gl_FragColor = vec4(mouse, 0.0, 1.0); } uniform vec2 mouse; Ϛ΢εͷҐஔ (0ʙ1) ࢖͍Ͳ͜Ζ • ΠϯλϥΫγϣϯ • ύϥϝʔλௐ੔ /src/ch1-basic/mouse.glsl

Slide 20

Slide 20 text

σόοά • ίϯύΠϧΤϥʔͷݟํ • ։ൃऀπʔϧͷίϯιʔϧͰ֬ೝ • Chromeͷ৔߹ • ϝχϡʔ / ͦͷଞͷπʔϧ / σϕϩούʔ πʔϧ / Console λϒ • σόοάํ๏ • σόοΨʔ΍஋ΛจࣈྻͰදࣔ͢Δํ๏(printσόοά)͸ͳ͍ • gl_FragColor ʹௐ΂͍ͨ஋ΛೖΕͯ৭ͱͯ֬͠ೝ͢Δ e.g. ηϛίϩϯ͕ͳ͍৔߹…

Slide 21

Slide 21 text

஫ҙ఺ • ʮ໭ΔʯϘλϯΛԡ͞ͳ͍ • ԡ͢ͱॻ͖͔͚ͷίʔυ͕ফ͑Δ • ແݶϧʔϓΛ࡞Βͳ͍ • λϒ͕Ϋϥογϡͯ͠ॻ͖͔͚ͷίʔυ͕ফ͑ͨΓɺPC͕ෆ҆ఆʹͳΔ • ίʔσΟϯάதͷ్தঢ়ଶ͕ࣗಈίϯύΠϧ͞ΕͯҙਤͤͣແݶϧʔϓʹͳΔՄ ೳੑ͕͋Δ

Slide 22

Slide 22 text

GLSLͷϏϧτΠϯؔ਺ͱProcessing / p5.jsͷରԠؔ܎ (-4- 1SPDFTTJOHQKT ิ଍ TJO DPT TJO DPT QPX QPX FYQ FYQ MPH MPH TRSU TRSU BCT BCT qPPS qPPS NPE Š ༨ΓΛٻΊΔؔ਺ NJY MFSQ TUFQ Š ͜ͷޙʹղઆ TNPPUITUFQ Š ͜ͷޙʹղઆ MFOHUI NBH ϕΫτϧͷେ͖͞ Α͘࢖͏ؔ਺ͷΈΛൈਮ Ҿ਺ͷॱ൪΍ܕ͕ҟͳΔ͜ͱ͕͋ΔͷͰ஫ҙ

Slide 23

Slide 23 text

GLSLͷؔ਺ void main(void) { vec2 pos = gl_FragCoord.xy / resolution; gl_FragColor = vec4(sin(20.0 * pos) * 0.5 + 0.5, 0.0, 1.0); } void main(void) { vec2 pos = gl_FragCoord.xy / resolution; vec3 col = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), pos.x); gl_FragColor = vec4(col, 1.0); } GLSLͷ΄ͱΜͲͷؔ਺͸ϕΫτϧ΋Ҿ਺ʹड͚औΕΔ ϕΫτϧͷ֤ཁૉ͝ͱʹ஋͕ܭࢉ͞ΕΔ /src/ch1-basic/sin.glsl /src/ch1-basic/mix.glsl

Slide 24

Slide 24 text

step, smoothstep step(edge, x) x͕edgeະຬͷͱ͖0ɺͦΕҎ֎ͷͱ͖1Λฦ͢ smoothstep(edge0, edge1, x) x͕edge0ҎԼͷͱ͖0ɺedge1Ҏ্ͷͱ͖1ɺ ͦΕҎ֎ͷͱ͖0͔Β1ͷؒͷ׈Β͔ʹิؒͨ͠஋Λฦ͢ /src/ch1-basic/step.glsl /src/ch1-basic/smoothstep.glsl void main(void) { vec2 pos = gl_FragCoord.xy / resolution; vec3 col = vec3(step(0.5, pos.x)); gl_FragColor = vec4(col, 1.0); } precision highp float; uniform vec2 resolution; void main(void) { vec2 pos = gl_FragCoord.xy / resolution; vec3 col = vec3(smoothstep(0.25, 0.75, pos.x)); gl_FragColor = vec4(col, 1.0); }

Slide 25

Slide 25 text

࡞ྫ (جૅฤ) ࢢদ໛༷ (νΣοΧʔ) Ϧϯά /src/ch1-basic/checker/step-4.glsl /src/ch1-basic/ring/step-4.glsl

Slide 26

Slide 26 text

ࢢদ໛༷ 1. vec3 checker(vec2 pos, vec2 size) { return vec3(pos, 0.0); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); vec3 c = checker(pos, vec2(1.0)); gl_FragColor = vec4(c, 1.0); } resolution͕vec2(400, 300)ͷ৔߹.. (-1.33, -1) (1.33, 1) (0, 0) (1.33, -1) (-1.33, 1) ΞεϖΫτൺΛҡ࣋ͨ͠··ݪ఺Λத৺ʹͯ͠࠲ඪΛਖ਼نԽ /src/ch1-basic/checker/step-1.glsl

Slide 27

Slide 27 text

ࢢদ໛༷ 2. vec3 checker(vec2 pos, vec2 size) { vec2 m = mod(pos, 2.0 * size); return vec3(m, 0.0); } void main(void) { … vec3 c = checker(10.0 * pos, vec2(1.0)); … } (0, 0) (2.0 * size.x, 0) (size.x, size.y) (0, 2.0 * size.y) (2.0 * size.x, 2.0 * size.y) /src/ch1-basic/checker/step-2.glsl modͰ࠲ඪͷ܁Γฦ͠Λ࡞Δ

Slide 28

Slide 28 text

ࢢদ໛༷ 3. vec3 checker(vec2 pos, vec2 size) { vec2 m = mod(pos, 2.0 * size); vec2 s = step(size, m); return vec3(s, 0.0); } (0, 0) (1, 0) (0, 1) (1, 1) /src/ch1-basic/checker/step-3.glsl stepͰಉ֨͡ࢠͷϐΫηϧ͸ ಉ͡஋ʹͳΔΑ͏ʹ͢Δ

Slide 29

Slide 29 text

ࢢদ໛༷ — 4. ׬੒— vec3 checker(vec2 pos, vec2 size) { vec2 m = mod(pos, 2.0 * size); vec2 s = step(size, m); return s.x == s.y ? vec3(0.0) : vec3(1.0); } /src/ch1-basic/checker/step-4.glsl

Slide 30

Slide 30 text

Ϧϯά 1. vec3 ring(vec2 pos) { float l = length(pos); return vec3(l); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); vec3 col = ring(pos); gl_FragColor = vec4(col, 1.0); } (0, 0) => l = 0 (1.33, 1) => l = 1.66 (0.66, 0.5) => l = 0.83 resolution͕vec2(400, 300)ͷ৔߹.. /src/ch1-basic/checker/ring.glsl த৺͔Βͷڑ཭ΛٻΊΔ

Slide 31

Slide 31 text

Ϧϯά 2. vec3 ring(vec2 pos) { float l = length(20.0 * pos); float s = sin(l - time) * 0.5 + 0.5; return vec3(s); } /src/ch1-basic/checker/step-2.glsl ࡾ֯ؔ਺ͰपظύλʔϯΛ࡞Δ

Slide 32

Slide 32 text

Ϧϯά — 3. ৭ͷઢܗิؒ — vec3 c1 = vec3(0.5, 0.7, 1.0); vec3 c2 = vec3(0.1, 0.3, 0.8); vec3 ring(vec2 pos) { float l = length(20.0 * pos); float s = sin(l - time) * 0.5 + 0.5; return mix(c1, c2, s); } /src/ch1-basic/checker/step-3.glsl mixͰ2ͭͷ৭ͷ άϥσʔγϣϯΛ࡞Δ

Slide 33

Slide 33 text

Ϧϯά — 4. ׬੒ — vec3 c1 = vec3(0.5, 0.7, 1.0); vec3 c2 = vec3(0.1, 0.3, 0.8); vec3 ring(vec2 pos) { float l = length(20.0 * pos); float s = sin(l - time) * 0.5 + 0.5; return mix(c1, c2, smoothstep(0.8, 0.9, s)); } /src/ch1-basic/checker/step-4.glsl smoothstepͰΠΠײ͡ʹ͢Δ

Slide 34

Slide 34 text

2. ϥϯμϜ

Slide 35

Slide 35 text

ཚ਺ɾϊΠζ • Processing / p5.jsͰ͍͏ͱ͜Ζͷrandom, noise • GLSLʹ͸ཚ਺Λੜ੒͢Δ૊ΈࠐΈؔ਺͸ͳ͍ • ͳͷͰɺࣗ෼Ͱ࣮૷͢Δඞཁ͕͋Δ

Slide 36

Slide 36 text

Ұ༷ཚ਺ (ϗϫΠτϊΠζ) float random(float v) { return fract(sin(v * 12.9898) * 43758.5453); } float random(vec2 v) { return fract(sin(dot(v, vec2(12.9898, 78.233))) * 43758.5453); } /src/ch2-random/random-1d.glsl /src/ch2-random/random-2d.glsl /src/ch2-random/random-3d.glsl 1࣍ݩҾ਺ͷཚ਺ 2࣍ݩҾ਺ͷཚ਺

Slide 37

Slide 37 text

ϒϩοΫϊΠζ float blockNoise(vec2 v) { return random(floor(v)); } /src/ch2-random/block-noise-1d.glsl /src/ch2-random/block-noise-2d.glsl /src/ch2-random/block-noise-3d.glsl randomʹ౉͢Ҿ਺Λ ෳ਺ͷϐΫηϧͰಉ͡ʹ͢Δ͜ͱͰ ϒϩοΫΛ࡞Δ

Slide 38

Slide 38 text

όϦϡʔϊΠζ float valueNoise(vec2 v) { vec2 i = floor(v); vec2 f = smoothstep(0.0, 1.0, fract(v)); return mix( mix(random(i), random(i + vec2(1.0, 0.0)), f.x), mix(random(i + vec2(0.0, 1.0)), random(i + vec2(1.0, 1.0)), f.x), f.y ); } ϒϩοΫϊΠζΛิؒͯ͠׈Β͔ʹ͢Δ i i + (1, 0) i + (1, 1) i + (0, 1) f.x f.y v ࿈ଓ͕ͩϒϩοΫঢ়ͷߏ଄͕͏ͬ͢Βݟ͍͑ͯΔ… /src/ch2-random/value-noise-1d.glsl /src/ch2-random/value-noise-2d.glsl /src/ch2-random/value-noise-3d.glsl

Slide 39

Slide 39 text

fbm (Fractal Brown Motion) float fbm(vec2 v) { float n = 0.0; float a = 0.5; for (int i = 0; i < 5; i++) { n += a * valueNoise(v); v *= 2.0; a *= 0.5; } return n; } ෳ਺ͷϊΠζΛεέʔϧΛม͑ͳ͕ΒॏͶΔ ϒϩοΫײ͕ফ͑ͯࣗવͳϊΠζ͕ಘΒΕΔ /src/ch2-random/fbm-1d.glsl /src/ch2-random/fbm-2d.glsl /src/ch2-random/fbm-3d.glsl

Slide 40

Slide 40 text

ύʔϦϯϊΠζ float perlinNoise(vec2 v) { vec2 i = floor(v); vec2 f = fract(v); vec2 v00 = f; vec2 v10 = f - vec2(1.0, 0.0); vec2 v01 = f - vec2(0.0, 1.0); vec2 v11 = f - vec2(1.0, 1.0); vec2 i00 = i; vec2 i10 = i + vec2(1.0, 0.0); vec2 i01 = i + vec2(0.0, 1.0); vec2 i11 = i + vec2(1.0, 1.0); vec2 g00 = normalize(random2(i00) * 2.0 - 1.0); vec2 g10 = normalize(random2(i10) * 2.0 - 1.0); vec2 g01 = normalize(random2(i01) * 2.0 - 1.0); vec2 g11 = normalize(random2(i11) * 2.0 - 1.0); float d00 = dot(v00, g00); float d10 = dot(v10, g10); float d01 = dot(v01, g01); float d11 = dot(v11, g11); vec2 u = smoothstep(0.0, 1.0, f); return mix( mix(d00, d10, u.x), mix(d01, d11, u.x), u.y ); } ProcessingͷϊΠζ͸ύʔϦϯϊΠζ γΣʔμʔΞʔτͰ͸༨Γ࢖ΘΕͳ͍ (ܭࢉίετͷ໰୊??) /src/ch2-random/perlin-noise-2d.glsl /src/ch2-random/perlin-noise-3d.glsl

Slide 41

Slide 41 text

࡞ྫ (ϥϯμϜฤ) ΧϥʔϒϩοΫ RGBγϑτ /src/ch2-random/color-blocks/step-4.glsl /src/ch2-random/rgb-shift/step-3.glsl

Slide 42

Slide 42 text

ΧϥʔϒϩοΫ 1. float random(vec2 v) { return fract(sin(dot(v, vec2(12.9898, 78.233))) * 43758.5453); } vec3 colorBlocks(vec2 pos) { vec2 posIdx = floor(10.0 * pos); return vec3(random(posIdx)); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); vec3 col = colorBlocks(pos); gl_FragColor = vec4(col, 1.0); } /src/ch2-random/color-blocks/step-1.glsl ͜͜·Ͱ͸ϒϩοΫϊΠζͱಉ͡

Slide 43

Slide 43 text

ΧϥʔϒϩοΫ 2. vec3 random3(vec2 v) { return vec3(random(v), random(v + 10000.0), random(v + 20000.0)); } vec3 colorBlocks(vec2 pos) { vec2 posIdx = floor(10.0 * pos); return random3(posIdx); } RGBͷ֤ཁૉʹϥϯμϜͳ஋Λઃఆ /src/ch2-random/color-blocks/step-2.glsl

Slide 44

Slide 44 text

ΧϥʔϒϩοΫ 3. float random(vec3 v) { return fract(sin(dot(v, vec3(12.9898, 78.233, 19.8321))) * 43758.5453); } vec3 random3(vec3 v) { return vec3(random(v), random(v + 10000.0), random(v + 20000.0)); } vec3 colorBlocks(vec2 pos) { vec2 posIdx = floor(10.0 * pos); float timeIdx = floor(10.0 * time); return random3(vec3(posIdx, timeIdx)); } randomʹ࣌ؒ΋౉͢͜ͱͰ Ұఆ࣌ؒ͝ͱʹ৭͕มΘΔΑ͏ʹ͢Δ /src/ch2-random/color-blocks/step-3.glsl

Slide 45

Slide 45 text

ΧϥʔϒϩοΫ 4. ׬੒ vec3 colorBlocks(vec2 pos) { vec2 posIdx = floor(10.0 * pos); float timeIdx = floor(10.0 * (time + random(posIdx))); return random3(vec3(posIdx, timeIdx)); } timeIdxͷ஋ΛϒϩοΫ͝ͱʹม͑Δ͜ͱͰ ৭͕มΘΔλΠϛϯάΛͣΒ͢ /src/ch2-random/color-blocks/step-4.glsl

Slide 46

Slide 46 text

RGBγϑτ 1. float random(vec2 v) { return fract(sin(dot(v, vec2(12.9898, 78.233))) * 43758.5453); } float valueNoise(vec2 v) { vec2 i = floor(v); vec2 f = smoothstep(0.0, 1.0, fract(v)); return mix( mix(random(i), random(i + vec2(1.0, 0.0)), f.x), mix(random(i + vec2(0.0, 1.0)), random(i + vec2(1.0, 1.0)), f.x), f.y ); } float fbm(vec2 x) { float n = 0.0; float a = 0.5; for (int i = 0; i < 3; i++) { n += a * valueNoise(x); x *= 2.0; a *= 0.5; } return n; } vec3 rgbShift(vec2 pos) { float n = fbm(2.0 * pos); return vec3(smoothstep(0.5, 0.55, n)); } void main(void) { vec2 pos = gl_FragCoord.xy / min(resolution.x, resolution.y); vec3 col = rgbShift(pos); gl_FragColor = vec4(col, 1.0); } smoothstepͰΠΠײ͡ʹ͢Δ /src/ch2-random/rgb-shift/step-1.glsl

Slide 47

Slide 47 text

RGBγϑτ 2. float random(vec3 v) { return fract(sin(dot(v, vec3(12.9898, 78.233, 19.8321))) * 43758.5453); } float valueNoise(vec3 v) { vec3 i = floor(v); vec3 f = smoothstep(0.0, 1.0, fract(v)); return mix( mix( mix(random(i), random(i + vec3(1.0, 0.0, 0.0)), f.x), mix(random(i + vec3(0.0, 1.0, 0.0)), random(i + vec3(1.0, 1.0, 0.0)), f.x), f.y ), mix( mix(random(i + vec3(0.0, 0.0, 1.0)), random(i + vec3(1.0, 0.0, 1.0)), f.x), mix(random(i + vec3(0.0, 1.0, 1.0)), random(i + vec3(1.0, 1.0, 1.0)), f.x), f.y ), f.z ); } float fbm(vec3 x) { float n = 0.0; float a = 0.5; for (int i = 0; i < 3; i++) { n += a * valueNoise(x); x *= 2.0; a *= 0.5; } return n; } vec3 rgbShift(vec2 pos) { float n = fbm(vec3(2.0 * pos, 0.1 * time)); return vec3(smoothstep(0.5, 0.55, n)); } ϊΠζΛ3࣍ݩʹͯ͠
 ࣌ؒͰಈ͔͢ /src/ch2-random/rgb-shift/step-2.glsl

Slide 48

Slide 48 text

RGBγϑτ 3. ׬੒ vec3 rgbShift(vec2 pos) { vec3 n = vec3( fbm(vec3(2.0 * pos, 0.1 * (time - 1.0))), fbm(vec3(2.0 * pos, 0.1 * time)), fbm(vec3(2.0 * pos, 0.1 * (time + 1.0))) ); return smoothstep(0.5, 0.55, n); } RGBͷ֤ཁૉ͝ͱʹ ϊΠζͷ࣌ؒΛͣΒ͢ /src/ch2-random/rgb-shift/step-3.glsl

Slide 49

Slide 49 text

3. ਤܗ

Slide 50

Slide 50 text

ූ߸෇͖ڑ཭ؔ਺(Signed Distance Function; SDF) • ͋ΔҐஔ͔Βਤܗͷද໘·Ͱͷڑ཭Λฦؔ͢਺ • ਤܗ಺෦ͷ৔߹͸ෛͷ஋Λฦ͢ ԁͷڑ཭ؔ਺ float sdCircle(vec2 pos, float radius) { return length(pos) - radius; } + -

Slide 51

Slide 51 text

SDFʹΑΔਤܗͷඳը float sdCircle(vec2 pos, float radius) { return length(pos) - radius; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float d = sdCircle(pos, 0.5); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } ਤܗͷ಺෦͸നʹɺ֎෦͸ࠇʹ /src/ch3-shape/circle.glsl

Slide 52

Slide 52 text

࢛֯ܗ float sdRect(vec2 pos, vec2 size) { pos = abs(pos) - size; return length(max(pos, 0.0)) + min(max(pos.x, pos.y), 0.0); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float d = sdRect(pos, vec2(0.6, 0.4)); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } /src/ch3-shape/rect.glsl

Slide 53

Slide 53 text

࢛֯ܗͷڑ཭ؔ਺ͷΠϝʔδ ఺͕ڑ཭ΛٻΊΔҐஔ, ઢ͕࠷୹ڑ཭Λද͍ͯ͠Δ 1. ॳظҐஔ pos 2. abs(pos) 3. abs(pos) - size 4. max(abs(pos) - size, 0.0)

Slide 54

Slide 54 text

ͦͷଞͷਤܗ https://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm

Slide 55

Slide 55 text

Ҡಈ vec2 translate(vec2 pos, vec2 offset) { return pos - offset; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos = translate(pos, vec2(0.5, 0.3)); float d = sdCircle(pos, 0.5); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } ਤܗΛҠಈ͢ΔͨΊʹ͸ ࠲ඪΛ൓ରํ޲ʹಈ͔͢ /src/ch3-shape/translate.glsl

Slide 56

Slide 56 text

ճస #define PI 3.14159265359 vec2 rotate(vec2 pos, float radian) { float c = cos(-radian); float s = sin(-radian); return mat2(c, s, -s, c) * pos; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos = rotate(pos, PI / 3.0); float d = sdRect(pos, vec2(0.6, 0.4)); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } ਤܗΛճసͤ͞ΔͨΊʹ͸ ճసߦྻͰ࠲ඪΛ൓ରํ޲ʹճసͤ͞Δ /src/ch3-shape/rotate.glsl

Slide 57

Slide 57 text

֦େॖখ vec2 scale(vec2 pos, vec2 rate) { return pos /rate; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos = scale(pos, vec2(1.5, 0.5)); float d = sdCircle(pos, 0.5); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } ਤܗΛ֦େ(ॖখ)ͤ͞ΔͨΊʹ͸ ࠲ඪΛॖখ(֦େ)ͤ͞Δ /src/ch3-shape/scale.glsl

Slide 58

Slide 58 text

ϒʔϦΞϯԋࢉ —࿨ — float opUnion(float d1, float d2) { return min(d1, d2); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float rd = sdRect(pos, vec2(0.6, 0.4)); float cd = sdCircle(translate(pos, vec2(0.5, 0.3)), 0.5); float d = opUnion(rd, cd); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } 2ͭͷਤܗΛ݁߹͢Δ /src/ch3-shape/union.glsl

Slide 59

Slide 59 text

ϒʔϦΞϯԋࢉ —ࠩ — float opSubtraction(float d1, float d2) { return max(d1, -d2); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float rd = sdRect(pos, vec2(0.6, 0.4)); float cd = sdCircle(translate(pos, vec2(0.5, 0.3)), 0.5); float d = opSubtraction(rd, cd); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } ͋Δਤܗ͔ΒผͷਤܗΛҾ͘ /src/ch3-shape/subtraction.glsl

Slide 60

Slide 60 text

ϒʔϦΞϯԋࢉ —ੵ — float opIntersection(float d1, float d2) { return max(d1, d2); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float rd = sdRect(pos, vec2(0.6, 0.4)); float cd = sdCircle(translate(pos, vec2(0.5, 0.3)), 0.5); float d = opIntersection(rd, cd); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } 2ͭͷਤܗͷॏͳ͍ͬͯΔ ՕॴͷΈΛऔΓग़͢ /src/ch3-shape/intersection.glsl

Slide 61

Slide 61 text

׈Β͔ͳ݁߹ ࢀߟ: https://www.iquilezles.org/www/articles/smin/smin.htm float opSmoothUnion(float d1, float d2, float k) { return -log2(exp2(-k * d1) + exp2(-k * d2)) / k; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float rd = sdRect(pos, vec2(0.6, 0.4)); float cd = sdCircle(translate(pos, vec2(0.5, 0.3)), 0.5); float d = opSmoothUnion(rd, cd, 32.0); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } 2ͭͷਤܗΛ׈Β͔ʹ݁߹͢Δ /src/ch3-shape/smooth-union.glsl

Slide 62

Slide 62 text

܁Γฦ͠ vec2 repeat(vec2 pos, vec2 size) { return mod(pos, 2.0 * size) - size; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos = repeat(10.0 * pos, vec2(1.0)); float d = sdCircle(pos, 0.5); vec3 col = mix(vec3(1.0), vec3(0.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } ਤܗΛλΠϦϯά͢Δ /src/ch3-shape/repeat.glsl

Slide 63

Slide 63 text

࡞ྫ (ਤܗฤ) ϝλϘʔϧ ϞʔϑΟϯά /src/ch3-shape/metaballs/step-3.glsl /src/ch3-shape/morphing/step-4.glsl

Slide 64

Slide 64 text

ϝλϘʔϧ 1. float sdCircle(vec2 pos, float radius) { return length(pos) - radius; } vec2 translate(vec2 pos, vec2 offset) { return pos - offset; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos *= 8.0; vec2 offset = 5.0 * sin(vec2(1.0, 0.8) * time); float radius = 1.0; float d = sdCircle(translate(pos, offset), radius); vec3 col = mix(vec3(0.2, 0.6, 0.7), vec3(1.0, 0.8, 0.9), smoothstep(-0.05, 0.05, d)); gl_FragColor = vec4(col, 1.0); } ԁΛҰͭಈ͔͢ /src/ch3-shape/metaballs/step-1.glsl

Slide 65

Slide 65 text

ϝλϘʔϧ 2. float random(float v) { return fract(sin(v * 12.9898) * 43758.5453); } float opUnion(float d1, float d2) { return min(d1, d2); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos *= 8.0; float d = 1e6; for (float i = 1.0; i <= 10.0; i++) { vec2 offset = 5.0 * sin(2.0 * vec2(random(i), random(i * 10.0)) * time); float radius = mix(0.5, 2.0, random(i * 100.0)); float cd = sdCircle(translate(pos, offset), radius); d = opUnion(d, cd); } vec3 col = mix(vec3(0.2, 0.6, 0.7), vec3(1.0, 0.8, 0.9), smoothstep(-0.05, 0.05, d)); gl_FragColor = vec4(col, 1.0); } ϧʔϓͰෳ਺ͷԁΛಈ͔͢ /src/ch3-shape/metaballs/step-2.glsl

Slide 66

Slide 66 text

ϝλϘʔϧ 3. ׬੒ float opSmoothUnion(float d1, float d2, float k) { return -log2(exp2(-k * d1) + exp2(-k * d2)) / k; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos *= 8.0; float d = 1e6; for (float i = 1.0; i <= 10.0; i++) { vec2 offset = 5.0 * sin(2.0 * vec2(random(i), random(i * 10.0)) * time); float radius = mix(0.5, 2.0, random(i * 100.0)); float cd = sdCircle(translate(pos, offset), radius); d = opSmoothUnion(d, cd, 4.0); } vec3 col = mix(vec3(0.2, 0.6, 0.7), vec3(1.0, 0.8, 0.9), smoothstep(-0.05, 0.05, d)); gl_FragColor = vec4(col, 1.0); } ԁΛ׈Β͔ʹ݁߹͢Δ /src/ch3-shape/metaballs/step-3.glsl

Slide 67

Slide 67 text

ϥϯμϜͳਤܗ 1. float opSubtraction(float d1, float d2) { return max(d1, -d2); } float sdOutlineCircle(vec2 pos, float radius, float thickness) { return opSubtraction(sdCircle(pos, radius), sdCircle(pos, radius - thickness)); } float sdOutlineRect(vec2 pos, vec2 size, float thickness) { return opSubtraction(sdRect(pos, size), sdRect(pos, size - thickness)); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float d = sdOutlineCircle(pos, 0.5, 0.2); // float d = sdOutlineRect(pos, vec2(0.5), 0.2); vec3 col = mix( vec3(0.8, 0.0, 0.0), vec3(1.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } طଘͷڑ཭ؔ਺ͱ ϒʔϦΞϯԋࢉͰ ৽͍͠ڑ཭ؔ਺Λ࡞੒͢Δ /src/ch3-shape/morphing/step-1.glsl

Slide 68

Slide 68 text

ϥϯμϜͳਤܗ 2. void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); float cd = sdOutlineCircle(pos, 0.5, 0.2); float rd = sdOutlineRect(pos, vec2(0.5), 0.2); float t = mod(0.8 * time, 2.0); float s = smoothstep(0.8, 1.0, fract(t)); float d = mix(cd, rd, floor(t) == 0.0 ? s : (1.0 - s)); vec3 col = mix( vec3(0.8, 0.0, 0.0), vec3(1.0), smoothstep(-0.005, 0.005, d)); gl_FragColor = vec4(col, 1.0); } 2ͭͷڑ཭ؔ਺Λ mix͢Δ͜ͱͰ ਤܗΛϞʔϑΟϯά͢Δ /src/ch3-shape/morphing/step-2.glsl

Slide 69

Slide 69 text

ϥϯμϜͳਤܗ 3. vec2 repeat(vec2 pos, vec2 size) { return mod(pos, 2.0 * size) - size; } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); pos = repeat(5.0 * pos, vec2(1.0)); float cd = sdOutlineCircle(pos, 0.5, 0.2); float rd = sdOutlineRect(pos, vec2(0.5), 0.2); float t = mod(0.8 * time, 2.0); float s = smoothstep(0.8, 1.0, fract(t)); float d = mix(cd, rd, floor(t) == 0.0 ? s : (1.0 - s)); vec3 col = mix(vec3(0.8, 0.0, 0.0), vec3(1.0), smoothstep(-0.01, 0.01, d)); gl_FragColor = vec4(col, 1.0); } ܁Γฦ͠ͰਤܗΛෑ͖٧ΊΔ /src/ch3-shape/morphing/step-3.glsl

Slide 70

Slide 70 text

ϥϯμϜͳਤܗ 4. ׬੒ float random(vec2 v) { return fract(sin(dot(v, vec2(12.9898, 78.233))) * 43758.5453); } vec2 repeatIdx(vec2 pos, vec2 size) { return floor(pos / (2.0 * size)); } void main(void) { vec2 pos = (2.0 * gl_FragCoord.xy - resolution) / min(resolution.x, resolution.y); vec2 repIdx = repeatIdx(5.0 * pos, vec2(1.0)); pos = repeat(5.0 * pos, vec2(1.0)); float cd = sdOutlineCircle(pos, 0.5, 0.2); float rd = sdOutlineRect(pos, vec2(0.5), 0.2); float t = mod(0.8 * (time + 10.0 * random(repIdx)), 2.0); float s = smoothstep(0.8, 1.0, fract(t)); float d = mix(cd, rd, floor(t) == 0.0 ? s : (1.0 - s)); vec3 col = mix(vec3(0.8, 0.0, 0.0), vec3(1.0), smoothstep(-0.01, 0.01, d)); gl_FragColor = vec4(col, 1.0); } λΠϧ͝ͱʹλΠϛϯάΛͣΒ͢ /src/ch3-shape/morphing/step-4.glsl

Slide 71

Slide 71 text

4. 3D

Slide 72

Slide 72 text

• γΣʔμʔΞʔτͷ3DදݱͰओʹ࢖ΘΕΔख๏ • ූ߸෇͖ڑ཭ؔ਺ͰΦϒδΣΫτΛදݱ͢Δ • Χϝϥ͔Βඈ͹ͨ͠ϨΠΛΦϒδΣΫτͱͿ͔ͭΔ·ͰਐΊΔ • ࢀߟ • ຐ๏࢖͍ʹͳΓ͍ͨਓͷͨΊͷγΣʔμʔϥΠϒίʔσΟϯάೖ໳ - Qiita • https://qiita.com/kaneta1992/items/21149c78159bd27e0860 • γΣʔμ͚ͩͰੈքΛ૑Δʂthree.jsʹΑΔϨΠϚʔνϯά • https://www.slideshare.net/shohosoda9/threejs-58238484 (εϑΟΞ)ϨΠϚʔνϯά

Slide 73

Slide 73 text

(εϑΟΞ)ϨΠϚʔνϯά /src/ch4-3d/raymarching.glsl

Slide 74

Slide 74 text

ऴΘΓʹ

Slide 75

Slide 75 text

ΞυόΠε • ࠲ඪͱ਺஋Λৗʹҙࣝ͠Α͏ • جຊ͸ཁૉͷ૊Έ߹ΘͤɺҾ͖ग़͠Λ૿΍ͦ͏ • ଞͷਓͷιʔείʔυΛಡΉ • Shadertoy, GLSL • ผ෼໺ͷ஌ࣝΛ࣋ͪࠐΉ • Processing / p5.js, 3D, άϥϑΟοΫσβΠϯ…

Slide 76

Slide 76 text

͞ΒͳΔษڧͷͨΊͷϦϯΫू • The Book of Shaders • γΣʔμʔΛجૅ͔Βղઆ • https://thebookofshaders.com/?lan=jp • wgld.org GLSL contents • WebGLͷษڧͰ୭΋͕͓ੈ࿩ʹͳΔdoxasઌੜʹΑΔGLSLͷղઆ • ϑϥΫλϧ͔ΒϨΠϚʔνϯά·Ͱ • https://wgld.org/d/glsl/ • GLSL-Noise.md • GLSLʹΑΔϊΠζ࣮૷ͷ·ͱΊ • https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 • Inigo Quilez :: fractals, computer graphics, mathematics, shaders, demoscene and more • ಺༰͸೉͠Ί͕ͩ༗ӹͳ৘ใ͕ࡌ͍ͬͯΔɺiqਆ • https://www.iquilezles.org/index.html