Unity×レイマーチングによる映像制作の実践手法 / KLab Tech Meetup 4

Unity×レイマーチングによる映像制作の実践手法 / KLab Tech Meetup 4

452023224091040c47c3bcaa40935c53?s=128

がむ

June 19, 2019
Tweet

Transcript

  1. 6OJUZºϨΠϚʔνϯά
 ʹΑΔө૾੍࡞ͷ࣮ફख๏ 2019/06/19 KLab TECH Meetup #4 @gam0022 / Sho

    HOSODA
  2. ࣗݾ঺հ • @gam0022 / Sho HOSODA • KLabגࣜձࣾ ৽ଔ5೥໨ •

    UnityΤϯδχΞ • γΣʔμʔ͕޷͖ 2
  3. WORMHOLE by gam0022 & sadakkey ʢൃදͷ୊ࡐʣ 2ͭͷੈքΛʮϫʔϜϗʔϧͰۭؒҠಈʯ͢ΔUnityʹΑΔө૾࡞඼ 3 ඇݱ࣮ͳσδλϧۭؒ ਫฏઢͷ޿͕Δࣗવۭؒ

    Tokyo Demo Fest 2018 ͷ Combined Demo Compo ༏উ࡞඼
  4. ϨΠϚʔνϯάͱσϞγʔϯ • ڑ཭ؔ਺ʢdistance functionʣͱ͍͏਺ࣜͰܗঢ়Λఆٛ ‣ 3DϞσϧΛ༻ҙ͢Δඞཁ͕ͳ͍ ‣ ݫ͍͠༰ྔͷ੍໿ͷ͋ΔσϞγʔϯͷ෦໳ʢ4k intro౳ʣͱ૬ੑ͕ྑ͍ •

    TDFʢTokyo Demo Festʣͷ্Ґ࡞඼΋ϨΠϚʔνϯάΛར༻ 4 WORMHOLE by gam0022 & sadakkey 1st place@Combined Demo Compo, TDF2018 2nd stage BOSS by 0x4015&YET11 1st place@Combined Demo Compo, TDF2016 Shift by FMS_Cat 1st place@Combined Demo Compo, TDF2017
  5. ڑ཭ؔ਺ͷ͓͞Β͍ ڑ཭ؔ਺ = ఺p͔Β෺ମද໘΁ͷ࠷୹ڑ཭Λฦؔ͢਺ 5 float sdSphere( vec3 p, float

    s ) { return length(p)-s; } float udBox( vec3 p, vec3 b ) { return length(max(abs(p)-b,0.0)); } http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
  6. ϨΠϚʔνϯάΛ׬શʹཧղͰ͖Δࢿྉ • σϞγʔϯ΁Α͏ͦ͜ʢCEDEC 2017ʣ • γΣʔμ͚ͩͰੈքΛ૑Δʂthree.jsʹΑΔϨΠϚʔνϯά 6

  7. ܗঢ়ɹ࣭ײɹԋग़ 7 ө૾Λߏ੒͢Δ3ཁૉ

  8. ܗঢ় 8

  9. ܗঢ়ϞσϦϯά 9

  10. τϯωϧʢඇݱ࣮ͳσδλϧۭؒʣ͸ڑ཭ؔ਺ʹΑΔϞσϦϯά 10

  11. τϯωϧͷڑ཭ؔ਺ͷઃܭΞϓϩʔν طଘͷϑϥΫλϧਤܗΛΞϨϯδ 11 MengerSponge IFSͷύϥϝʔλΛௐ੔ foldRotateΛద༻

  12. IFSʢIterated function systemʣͱ͸ • ࣗ਎ͷॖখίϐʔΛॏͶ߹ΘͤΔ͜ͱ ͰϑϥΫλϧਤܗΛͭ͘ΔςΫχοΫ • forϧʔϓ ͷதͰૢ࡞Λ܁Γฦ͢ ‣

    fold ‣ ֦େॖখ ‣ ฏߦҠಈ 12 // IFSʹΑΔMengerSpongeͷڑ཭ؔ਺ float dMenger(float3 z0, float3 offset, float scale) { float4 z = float4(z0, 1.0); for (int n = 0; n < 4; n++) { z = abs(z); if (z.x < z.y) z.xy = z.yx; if (z.x < z.z) z.xz = z.zx; if (z.y < z.z) z.yz = z.zy; z *= scale; z.xyz -= offset * (scale - 1.0); if (z.z < -0.5 * offset.z * (scale - 1.0)) z.z += offset.z * (scale - 1.0); } return (length(max(abs(z.xyz) - float3(1.0, 1.0, 1.0), 0.0)) - 0.05) / z.w; } sdBox ➞ fold ➞ ֦େॖখ ฏߦҠಈ ➞
  13. IFSʢIterated function systemʣͷΞϨϯδ • OffsetʢฏߦҠಈʣͱ Scaleʢ֦େॖখʣ
 ͷύϥϝʔλʹΑͬͯܗঢ়΋มԽ͢Δ 13 // IFSʹΑΔMengerSpongeͷڑ཭ؔ਺

    float dMenger(float3 z0, float3 offset, float scale) { float4 z = float4(z0, 1.0); for (int n = 0; n < 4; n++) { z = abs(z); if (z.x < z.y) z.xy = z.yx; if (z.x < z.z) z.xz = z.zx; if (z.y < z.z) z.yz = z.zy; z *= scale; z.xyz -= offset * (scale - 1.0); if (z.z < -0.5 * offset.z * (scale - 1.0)) z.z += offset.z * (scale - 1.0); } return (length(max(abs(z.xyz) - float3(1.0, 1.0, 1.0), 0.0)) - 0.05) / z.w; } Offset = (1, 1, 1) Scale = 3 Offset = (0.79, 1.1, 0.47) Scale = 2.31
  14. foldRotateͱ͸ ͋Δ࣠Λத৺ͱͯ͠Ұఆͷ֯౓Ͱճస͠ͳ͕ΒۭؒΛંΓͨͨΉૢ࡞ 14 n = 3 θ = 120° n

    = 4 θ = 90° n = 6 θ = 60° n = 8 θ = 45°
  15. alias foldRotate = polarMod ಉ͡ૢ࡞͕ͩɺݺͼํʢղऍʣʹ೿ൊʢफڭʣ͕͋Δ 15 GPME3PUBUFʢճసͷંΓͨͨΈʣ QPMBS.PEʢۃ࠲ඪͷ.PEʣ @gam0022 @kanetaaaaa

  16. foldRotateͷ࣮૷ • 2Dͷճసߦྻ 16 // 2Dͷճసߦྻͷੜ੒ float2x2 rotate(in float a)

    { float s = sin(a), c = cos(a); return float2x2(c, s, -s, c); } // ճస fold // https://www.shadertoy.com/view/Mlf3Wj float2 foldRotate(in float2 p, in float s) { float a = PI / s - atan2(p.x, p.y); float n = PI2 / s; a = floor(a / n) * n; p = mul(rotate(a), p); return p; } • foldRotate ‣ ۃ࠲ඪͷ֯౓ΛٻΊΔ ‣ ଐ͍ͯ͠ΔྖҬʹԠͯ͡ճస
  17. foldRotateͷৄࡉ͸ϒϩάͰ ڑ཭ؔ਺ͷfoldʢંΓͨͨΈʣʹΑΔܗঢ়ઃܭ | gam0022.net 17

  18. τϯωϧͷڑ཭ؔ਺ͷ׬੒ʂ 18 // IFSʹΑΔMengerSpongeͷڑ཭ؔ਺ float dMenger(float3 z0, float3 offset, float

    scale) { float4 z = float4(z0, 1.0); for (int n = 0; n < 4; n++) { z = abs(z); if (z.x < z.y) z.xy = z.yx; if (z.x < z.z) z.xz = z.zx; if (z.y < z.z) z.yz = z.zy; z *= scale; z.xyz -= offset * (scale - 1.0); if (z.z < -0.5 * offset.z * (scale - 1.0)) z.z += offset.z * (scale - 1.0); } return (length(max(abs(z.xyz) - float3(1.0, 1.0, 1.0), 0.0)) - 0.05) / z.w; } // 2Dͷճసߦྻͷੜ੒ float2x2 rotate(in float a) { float s = sin(a), c = cos(a); return float2x2(c, s, -s, c); } // ճస fold // https://www.shadertoy.com/view/Mlf3Wj float2 foldRotate(in float2 p, in float s) { float a = PI / s - atan2(p.x, p.y); float n = PI2 / s; a = floor(a / n) * n; p = mul(rotate(a), p); return p; } inline float DistanceFunction(float3 pos) { // ճసfoldͷద༻ pos.yx = foldRotate(pos.yx, _MengerFold); return dMenger(pos, _MengerOffset, _MengerScale); } Θ͔ͣߦͷίʔυͰෳࡶͳܗঢ়ΛఆٛͰ͖ͨʂ .FOHFS4QPOHF GPME3PUBUF
  19. ࣭ײ 19

  20. ࣭ײϥΠςΟϯάॲཧ 20

  21. σΟϑΝʔυϨϯμϦϯάΛ࠾༻ σΟϑΝʔυϨϯμϦϯά͸2ͭͷύεͰγʔϯΛඳը 21 G-Bufferύε ϥΠςΟϯάʹඞཁͳ৘ใʢGόοϑΝʣΛੜ੒ RT0: Diffuse color (RGB), occlusion

    (A). RT1: Specular color (RGB), roughness (A). ɹRT3: Emission + lighting + lightmaps + reflection probes buffer. RT2: World space normal (RGB), unused (A). Depth + Stencil Lightingύε GόοϑΝΛݩʹ
 ϥΠςΟϯάΛܭࢉ
  22. σΟϑΝʔυϨϯμϦϯάΛ࠾༻ͨ͠3ͭͷཧ༝ ᶃ ڑ཭ؔ਺ͱϙϦΰϯ͕ࠞࡏͨ͠γʔϯͷҰ؏ͨ͠ϥΠςΟϯάॲཧ͕Մೳ ‣ ϨΠϚʔνϯάͷ݁ՌΛG-Bufferʹॻ͖ࠐΉ
 G-BufferύεͷγΣʔμʔΛ࣮૷͢Ε͹OK ‣ @hecomi ͞Μͷ uRaymarching

    Λར༻͢Δͱָ ᶄ 6OJUZඪ४ͷ-JHIUJOHύεΛར༻Ͱ͖Δ ‣ ࣗ෼ͰϥΠςΟϯάॲཧΛ࣮૷͠ͳͯ͘΋
 Unityͷશछྨͷޫݯ΍ReflectionProbeʹରԠͰ͖Δ ᶅ େྔͷޫݯͳͲϦονͳϥΠςΟϯάʹڧ͍ 22 @hecomi
  23. σΟϑΝʔυϨϯμϦϯάͷϥΠςΟϯάΛΧελϚΠζ σΟϑΝʔυϨϯμϦϯάͷऑ఺ ‣ γʔϯશମΛಉ͡ॲཧͰϥΠςΟϯά͢ΔͨΊɺ
 ϚςϦΞϧ͝ͱʹϥΠςΟϯάΛΧελϚΠζ͠ʹ͍͘ ‣ LightingύεʹखΛՃ͑Δͷ͸Өڹൣғ͕େ͖͍ɾख͕͔͔ؒΔ ղܾࡦɿ&NJTTJWFΛ׆༻ ‣ EmissiveҎ֎ͷύϥϝʔλΛ0ʹ͢Δͱɺ


    Emissiveͷ৭͕ͦͷ··࠷ऴ݁ՌʹͳΔ ‣ ಠࣗͷϥΠςΟϯά݁ՌΛEmissiveʹ֨ೲ 23
  24. EmissiveʹΑΔσΟϑΝʔυϨϯμϦϯάͷϥΠςΟϯάͷௐ੔ ϑϨωϧ൓ࣹͷޮՌΛ Emissive ʹॻ͖ࠐΉ͜ͱͰɺϥΠςΟϯάΛௐ੔ 24 ϑϨωϧͳ͠ ϑϨωϧ͋Γ

  25. ԋग़ 25

  26. ԋग़㱩Ξχϝʔγϣϯ 26

  27. ςΩετͷΞχϝʔγϣϯ 27

  28. TextMeshProͱ͸ʁ • SDF(Signed Distance Field)Λ࢖ͬͯߴ඼࣭ʹϑΥϯτΛϨϯμϦϯά ‣ จࣈͷྠֲ·Ͱͷڑ཭Λըૉ஋ʹͨ͠ը૾ ‣ ֦େͯ͠΋δϟΪ͕໨ཱͨͳ͍ ‣

    ϨΠϚʔνϯάͷڑ཭ؔ਺ͱಉ֓͡೦ʢ2Dͱ3Dͷҧ͍ʣ 28 SDFςΫενϟ TextMeshProͷϨϯμϦϯά݁Ռ
  29. TextMeshProͷඳըͷ࢓૊Έ • CPUͰ1จࣈͣͭMeshΛੜ੒ʢSDFςΫενϟ༻ͷUV͸௖఺σʔλʹʣ • ϑϥάϝϯτγΣʔμʔͰSDFͷςΫενϟ͔Β
 ϑΥϯτͷ಺֎ͷ൑ఆͯ͠ϨϯμϦϯά 29 TextMeshProͷϫΠϠʔϑϨʔϜදࣔ

  30. γΣʔμʔΛॻ͚͹ɺ 5FYU.FTI1SPͷϨϯμϦϯάΛ ࣗ༝ʹΧελϚΠζͰ͖Δ 30

  31. TextMeshProͷγΣʔμʔͷΧελϚΠζํ๏ 1. TextMeshProͷγΣʔμʔΛίϐʔ ‣ TMP_SDF-Mobile.shader 
 ͕࣮૷͕γϯϓϧͳͷͰΦεεϝ 2. γΣʔμʔΛվ଄ ‣

    ৭Λܾఆ͢Δ෦෼ ‣ SDFͷϑΣον෦෼ 3. TextMeshProͷΠϯεϖΫλ͔Β
 վ଄ͨ͠γΣʔμʔΛઃఆ 31
  32. TextMeshProͷγΣʔμʔͷΧελϚΠζྫ 32 ϒϥ΢ϯ؅෩ sinؔ਺Ͱ໛༷ͱಈ͖Λ͚ͭΔ ϞʔϑΟϯά 2छྨͷSDFΛϒϨϯυ

  33. TextMeshProͷγΣʔμʔͷΧελϚΠζྫ จࣈΛύϥύϥͱग़ݱɾফࣦͤ͞ΔΤϑΣΫτ 33 // PIXEL SHADER fixed4 PixShader(pixel_t input) :

    SV_Target { - half d = tex2D(_MainTex, input.texcoord0.xy).a * input.param.x; + half2 uv = input.texcoord0.xy; + uv.y = clamp(uv.y, 0.0, 0.5 + 0.5 * sin(_Time.y)); + half d = tex2D(_MainTex, uv).a * input.param.x; half4 c = input.faceColor * saturate(d - input.param.w); SDFςΫενϟΛϑΣον͢Δ UVΛ࣌ؒͰ clamp ϑΥϯτΛҾ͖৳͹͢ޮՌ͕ੜ·ΕΔ
  34. ৄࡉ͸QiitaͰ [Unity] ΧελϜγΣʔμʔͰTextMeshProʹಠ૑తͳԋग़ΛՃ͑Δ 34

  35. ͜͜·Ͱͷ·ͱΊ γΣʔμʔΛ࢖͏ͱɺ୹͍ίʔυͰଟ࠼ͳදݱ͕Ͱ͖Δ 35 ෳࡶͳܗঢ় ϦΞϧͳ࣭ײ Χοί͍͍ԋग़

  36. Unity Timeline Λ ׆༻ͨ͠ԋग़ 36

  37. ԋग़ͷࢼߦࡨޡͷΠςϨʔγϣϯʹUnity TimelineΛ׆༻ Unity Timelineͷ׆༻ 37 Timeline Window

  38. Animation Track • ϨΠϚʔνϯά༻ͷϚςϦΞϧͷύϥϝʔλ੍ޚ • ϙετΤϑΣΫτ༻ͷϚςϦΞϧͷύϥϝʔλ੍ޚ 38

  39. Custom Track for TextMeshPro TextMeshProͷςΩετΛॻ͖׵͑ΔTrackΛࣗ࡞ ‣ ඪ४TrackͰ͸࣮ݱͰ͖ͳ͔ͬͨ 39

  40. Chinemachine Track ΧϝϥϫʔΫʹ͸ChinemachineΛར༻ 40

  41. ԋग़ͷ·ͱΊ • نଇతͳಈ͖͸γΣʔμʔ͕ಘҙ ‣ نଇత = ਺ࣜͰදݱ͕Ͱ͖Δ ‣ ྫ: ԻָͷBPMʹ߹ΘͤͯνΧνΧ఺໓ͤ͞Δ

    • ෆنଇͳಈ͖͸Unity Timeline͕ಘҙ ‣ ྫ: ΧϝϥϫʔΫ 41 ෳ਺ͷಓ۩Λ࢖͍෼͚Δ͜ͱͰɺ ࡞ۀޮ཰ΛUP͠Α͏✌
  42. WORMHOLEͷؔ࿈৘ใ • UnityϓϩδΣΫτΛGitHubʹެ։த ‣ https://github.com/gam0022/unity-demoscene ‣ Assets/Demoscene/Projects/2018-10-28-TDF2018/ • ϒϩά ‣

    Tokyo Demo Fest 2018ͷDemo Compo༏উ࡞඼ͷղઆʢάϥϑΟοΫฤʣ • KLab Tech Book Vol.4 ‣ ٕज़ॻయ6ͰಉਓࢽΛ൦෍͠·͢&ిࢠ൛μ΢ϯϩʔυϖʔδ 42
  43. γΣʔμʔ͸ຐ๏ͷಓ۩✨ ԿͰ΋Ͱ͖Δɹ࠷ڧ ΈΜͳγΣʔμʔΛ΍Ζ͏☺ 43