Slide 1

Slide 1 text

ϑϥάϝϯτγΣʔμͰ ༡΅͏ LET’S PLAY WITH FRAGMENT SHADER @ta_ka_tsu

Slide 2

Slide 2 text

ࣗݾ঺հ @ta_ka_tsu ▸ %$"%ܥϓϩάϥϚʔ ▸ %$".ܥϓϩάϥϚʔ ▸ ձࣾઃཱ ▸ ϑϦʔϥϯεɹˡࠓίί

Slide 3

Slide 3 text

લճ

Slide 4

Slide 4 text

IUUQTTQFBLFSEFDLDPNLB[VIJSPHFUUJOH TUBSUFEXJUINFUBMTIBEJOHMBOHVBHF

Slide 5

Slide 5 text

IUUQHMTMTBOECPYDPNF ͔Β.4-ʹҠ২ (-4-4BOECPY IUUQHMTMTBOECPYDPN 4IBEFSUPZ IUUQTXXXTIBEFSUPZDPN HMTMGBO IUUQTHMTMGBODPN ࢀߟɿ(-4-Λ࡞੒ˍ࣮ߦˍ౤ߘͰ͖ΔαΠτ ΍ͬͯΈͨ

Slide 6

Slide 6 text

.FUBMඳըͷ࢓૊Έ ௒؆қ൛

Slide 7

Slide 7 text

௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ύΠϓϥΠϯͷྲྀΕ

Slide 8

Slide 8 text

௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ύΠϓϥΠϯͷྲྀΕ ೖྗɿ ௖఺৘ใ௖఺ͷ࠲ඪʴЋ

Slide 9

Slide 9 text

௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ύΠϓϥΠϯͷྲྀΕ όʔςοΫεγΣʔμʔɿ ௖఺৘ใΛՃ޻͢Δ

Slide 10

Slide 10 text

௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ύΠϓϥΠϯͷྲྀΕ ϥελϥΠβɿ ֨ࢠঢ়ͷ৘ใʹม׵͢Δ

Slide 11

Slide 11 text

௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ύΠϓϥΠϯͷྲྀΕ ϑϥάϝϯτɿ ֨ࢠঢ়ʹ֨ೲ͞Εͨ৘ใ

Slide 12

Slide 12 text

௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ύΠϓϥΠϯͷྲྀΕ ϑϥάϝϯτγΣʔμʔɿ ϑϥάϝϯτ͔Β৭Λܾఆ͢Δ

Slide 13

Slide 13 text

ϑϥάϝϯτγΣʔμʔͰ ֆΛඳ͘ʹ͸ʁ

Slide 14

Slide 14 text

ը໘શମΛ෴͏Α͏ʹ ࡾ֯ܗΛͭඳը͢Δ͜ͱͰ શͯͷϐΫηϧΛϑϥάϝϯτγΣʔμʔͰ ੍ޚ͢Δɻ

Slide 15

Slide 15 text

// ߏ଄ମ struct VertexOut { float4 pos [[position]]; }; // όʔςοΫεγΣʔμʔ vertex VertexOut vertexShader( const device packed_float2* vertex_array [[buffer(0)]], unsigned int vid [[vertex_id]]) { VertexOut v; v.pos = float4(vertex_array[vid], 1.0, 1.0); return v; } // ϑϥάϝϯτγΣʔμʔ fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]]) { return half4(1.0, 0.0, 0.0, 1.0); } 3 ( # Ћ ˞Ҏޙߏ଄ମͱόʔςοΫεγΣʔμʔ͸লུ

Slide 16

Slide 16 text

fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]]) { return step(300.0, length(fragmentIn.pos.xy)); } ˞TUFQؔ਺ɿ ɹୈҰҾ਺ΑΓୈೋҾ਺͕খ͍͞৔߹Λฦ͢ ɹͦΕҎ֎͸Λฦ͢ ˞εΧϥʔ஋͸ϕΫτϧ஋ʹ҉໧తʹΩϟετ͞Ε ɹͦͷ੒෼͸શͯݩͷεΧϥʔ஋ͱͳΔɻ ɹFY IBMGDPMPS ԁΛඳ͘

Slide 17

Slide 17 text

fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]]) { return smoothstep(300.0, 600.0, length(fragmentIn.pos.xy)); } ˞TNPPUITUFQؔ਺ɿ ɹୈҰҾ਺ΑΓୈࡾҾ਺͕খ͍͞৔߹Λฦ͢ ɹୈೋҾ਺ΑΓେ͖͍৔߹Λฦ͢ ɹୈҰҾ਺ͱୈೋҾ਺ͷؒ͸׈Β͔ʹิؒ ɹ Τϧϛʔτิؒ ԁΛ΅͔ͯ͠ඳ͘

Slide 18

Slide 18 text

࠲ඪͷਖ਼نԽ

Slide 19

Slide 19 text

ը໘αΠζʹରͯ͠ͷόϥϯε͕Θ͔Γʹ͍͘ ͔͠͠ϐΫηϧ࠲ඪ͔͠ೖྗ৘ใ͕ͳ͍ fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]]) { return step(300.0, length(fragmentIn.pos.xy)); }

Slide 20

Slide 20 text

γΣʔμʔʹ͸ όοϑΝΛ௨ͯ͠ ஋Λ౉͢͜ͱ͕Ͱ͖Δɻ ௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ όοϑΝ

Slide 21

Slide 21 text

ղ૾౓Λ౉͢ ௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ όοϑΝ ղ૾౓

Slide 22

Slide 22 text

ϑϥάϝϯτγΣʔμʔଆͰ͸ Ҿ਺ͱͯ͠ड͚औΔ fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]] ) { float2 p = fragmentIn.pos.xy/min(res.x, res.y); return half4(p.x, p.y, 0.0, 1.0); } (0.0, 0.0) (1.0, 1.0)

Slide 23

Slide 23 text

ը໘͍ͬͺ͍ʹԁΛඳ͘ float circle(float2 p) { // p - 0.5 ͸ɹp - float2(0.5, 0.5) ͱಉٛ return step(length(p - 0.5), 0.5); } fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]]) { float2 p = fragmentIn.pos.xy/min(res.x, res.y); return circle(p); }

Slide 24

Slide 24 text

ภ֯ʹԠͯ͡ᮢ஋Λม͑Δ float star(float2 p) { float2 c = p - 0.5; float a = atan2(c.y, c.x); return step(length(c) + 0.1*sin(5.0*a) + 0.1, 0.5); } fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]]) { float2 p = fragmentIn.pos.xy/min(res.x, res.y); return star(p); }

Slide 25

Slide 25 text

Ξχϝʔγϣϯ

Slide 26

Slide 26 text

ܦա࣌ؒ΋౉͢ ௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ղ૾౓ ܦա࣌ؒ όοϑΝ

Slide 27

Slide 27 text

࣌ؒΛҐ૬ͱͯ͠ภ֯ʹՃ͑Δ float star(float2 p, float phase) { float2 c = p - 0.5; float a = atan2(c.y, c.x) + phase; return step(length(c) + 0.1*sin(5.0*a) + 0.1, 0.5); } fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]], constant float &time [[buffer(1)]]) { float2 p = fragmentIn.pos.xy/min(res.x, res.y); return star(p, time); }

Slide 28

Slide 28 text

3(#ཁૉຖʹҐ૬Λม͑Δ float star(float2 p, float phase) { float2 c = p - 0.5; float a = atan2(c.y, c.x) + phase; return step(length(c) + 0.1*sin(5.0*a) + 0.1, 0.5); } fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]], constant float &time [[buffer(1)]]) { float2 p = fragmentIn.pos.xy/min(res.x, res.y); return half4(star(p, time), star(p, sin(time)), star(p, 2.0*time), 1.0); }

Slide 29

Slide 29 text

܁Γฦ͢ float star(float2 p, float time) { float2 c = p - 0.5; float a = atan2(c.y, c.x) + time; return step(length(c) + 0.1*sin(5.0*a) + 0.1, 0.5); } fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]], constant float &time [[buffer(1)]]) { float2 p = fragmentIn.pos.xy/min(res.x, res.y); float2 p1 = fract(p * 5.0); return half4(star(p1, time), star(p1, sin(time)), star(p1, 2.0*time), 1.0); } ˞GSBDU Y YqPPS Y

Slide 30

Slide 30 text

࣍ݩతͳදݱ

Slide 31

Slide 31 text

ϨΠϚʔνϯά આ໌͸ׂѪ ϨΠτϨʔγϯάͷҰछ Λ.4-ʹҠ২ˍΞχϝʔγϣϯΛ௥Ճ IUUQTXHMEPSHEHMTMHIUNM

Slide 32

Slide 32 text

float sphere(float3 p){ return length(p) - 1.0; } float3 getNormal(float3 p){ float d = 0.0001; return normalize( float3( sphere(p + float3( d, 0.0, 0.0)) - sphere(p + float3( -d, 0.0, 0.0)), sphere(p + float3(0.0, d, 0.0)) - sphere(p + float3(0.0, -d, 0.0)), sphere(p + float3(0.0, 0.0, d)) - sphere(p + float3(0.0, 0.0, -d)) ) ); } fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res[[buffer(0)]], constant float &time[[buffer(1)]]) { float2 p1 = (fragmentIn.pos.xy * 2.0 - res) / min(res.x, res.y); float2 p = p1 + float2(0.3*sin(time), 0.3*cos(time)); float angle = 90.0; float fov = angle * 0.5 * M_PI_F / 180.0; float3 cPos1 = float3(0.0, 0.0, 2.0); float3 lightDir = float3(-0.577, 0.577, 0.577); float phase1 = 0.7*sin(time); float phase2 = 0.5*sin(time*1.5); float3 ray1 = normalize(float3(sin(fov) * p.x, sin(fov) * p.y, -cos(fov))); float3x3 rotation = float3x3(cos(phase1), -sin(phase1), 0.0, sin(phase1), cos(phase1), 0.0, 0.0, 0.0, 1.0) * float3x3(1.0, 0.0, 0.0, 0.0, cos(phase2), -sin(phase2), 0.0, sin(phase2), cos(phase2)); float3 ray = rotation * ray1; float3 cPos = rotation * cPos1; float distance = 0.0; float rLen = 0.0; float3 rPos = cPos; for(int i = 0; i < 16; i++){ distance = sphere(rPos); rLen += distance; rPos = cPos + ray * rLen; } if(abs(distance) < 0.001){ float3 normal = getNormal(rPos); float diff = clamp(dot(lightDir, normal), 0.1, 1.0); return half4(diff, diff, diff, 1.0); } else{ return half4(0.0, 0.0, 0.0, 1.0); } }

Slide 33

Slide 33 text

͓·͚ˍ%&.0

Slide 34

Slide 34 text

΋ͬͱ৘ใΛ౉͢ ௖఺৘ใ όʔςοΫεγΣʔμʔ ௖఺৘ใ ϥελϥΠβ ϥελϥΠζ͞Εͨ௖఺৘ใ ϑϥάϝϯτ ϑϥάϝϯτγΣʔμʔ ৭ ղ૾౓ ܦա࣌ؒ όοϑΝ ϚΠΫԻྔ ʙ Ճ଎౓ηϯαʔ fragment half4 fragmentShader( VertexOut fragmentIn [[stage_in]], constant float2 &res [[buffer(0)]], constant float &time [[buffer(1)]], constant float &vol [[buffer(2)]], constant float3 &accel [[buffer(3)]]) { ɹ… }

Slide 35

Slide 35 text

༡ΜͰΈΑ͏! 4IBEFS1MBZHSPVOE IUUQTHJUIVCDPNUBLBUTV4IBEFS1MBZHSPVOE

Slide 36

Slide 36 text

ࢀߟ ָ͍͠ʂ6OJUZγΣʔμʔ͓ֆ͔͖ೖ໳ʂ IUUQTEPDTHPPHMFDPNQSFTFOUBUJPOE /.IY)8V/;TK/33MB'0VZTKP/HDQ'M&I[PE&3MH FEJUTMJEFJEHEB@@ IUUQTXHMEPSHEHMTM XHMEPSHc(-4-DPOUFOUT 5IF#PPLPG4IBEFST IUUQTUIFCPPLPGTIBEFSTDPN