もっと綺麗で写実的な絵作りがしたい!レイマーチング向けのシェーディング技術

452023224091040c47c3bcaa40935c53?s=47 がむ
March 10, 2018

 もっと綺麗で写実的な絵作りがしたい!レイマーチング向けのシェーディング技術

レイマーチングで大域照明を実現するための理論と実践を紹介します。
メガデモ勉強会! 2018で発表しました。
https://atnd.org/events/93843

452023224091040c47c3bcaa40935c53?s=128

がむ

March 10, 2018
Tweet

Transcript

  1. ϨΠϚʔνϯά޲͚ͷ
 γΣʔσΟϯάٕज़ 2018/03/10 ϝΨσϞษڧձ! 2018 @gam0022 / Sho HOSODA ΋ͬͱ៉ྷͰ࣮ࣸతͳֆ࡞Γ͕͍ͨ͠ʂ

  2. ࣗݾ঺հ • @gam0022 / Sho HOSODA • KLabגࣜձࣾ UnityΤϯδχΞ •

    TokyoDemoFest 2017
 GLSL Graphics Compo෦໳ 3Ґೖ৆ 2
  3. ൃදͷྲྀΕ • ຊ୊ͷલʹ ‣ ϨΠϚʔνϯάͷ͓͞Β͍ • ཧ࿦ ‣ େҬর໌ͱ͸Կ͔ •

    ࣮ફ ‣ ϨΠϚʔνϯάͰେҬর໌Λ࣮ݱ͢Δख๏ͷ঺հ • ͓·͚ ‣ ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ͷ
 ݸਓతϕετϓϥΫςΟεͷ঺հ 3
  4. ϨΠϚʔνϯάͷ͓͞Β͍ • ڑ཭ؔ਺ʢdistance functionʣͱ͍͏਺ࣜͰܗঢ়Λఆٛ ‣ 3DϞσϧΛ༻ҙ͢Δඞཁ͕ͳ͍ ‣ ݫ͍͠༰ྔͷ੍໿ͷ͋ΔϝΨσϞͱ૬ੑ͕ྑ͍ • TDFͷ্Ґ࡞඼΋ϨΠϚʔνϯάΛར༻

    4 Fusioned Bismuth by gam0022 @TDF2017 GLSL Graphics Compo 2nd stage BOSS by 0x4015&YET11 @TDF2016 PC 4K Intro Shift by FMS_Cat @TDF2017 Combined Demo Compo
  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. ϨΠϚʔνϯάͷ͓͞Β͍ • ϨΠϚʔνϯάʢraymarchingʣͰڑ཭ؔ਺ΛՄࢹԽ • ϨΠͱ෺ମ΁ͷަࠩ఺ΛٻΊΔํ๏ ‣ ڑ཭ؔ਺Λ͔ͭͬͯɺ࠷୹ڑ཭͚ͩϨΠΛਐΊΔ ‣ ͜ΕΛ܁Γฦ͢ ‣

    े෼ʹڑ཭͕খ͘͞ͳͬͨΒɺަࠩͨ͠ͱ൑ఆ 6
  7. ϨΠϚʔνϯάͷ͓͞Β͍ • ϨΠͷઌ୺͸ΧϝϥͷҐஔ͔Βελʔτ • ͕ϨΠͷઌ୺ 7

  8. ϨΠϚʔνϯάͷ͓͞Β͍ • ϨΠͷํ޲͸ͣͬͱಉ͡ 8

  9. ϨΠϚʔνϯάͷ͓͞Β͍ • ੺͍ઢ = ڑ཭ؔ਺ͷ஋ = ϨΠͷઌ୺͔Βͷ࠷୹ڑ཭ • Ұ൪͍ۙҐஔʹ͋Δͷ͸ԫ৭͍ٿମ 9

  10. ϨΠϚʔνϯάͷ͓͞Β͍ • ڑ཭ؔ਺ͷ஋͚ͩɺϨΠͷઌ୺ ΛਐΊΔ 10

  11. ϨΠϚʔνϯάͷ͓͞Β͍ • 2प໨ͷઌ୺ ͔Βɺ͞Βʹ࠷୹ڑ཭ΛٻΊΔ • 2प໨Ͱ΋ԫ৭͍ٿମ͕࠷୹ 11

  12. ϨΠϚʔνϯάͷ͓͞Β͍ • ࠷୹ڑ཭͚ͩϨΠΛਐΊͯɺ3प໨ͷϨΠͷઌ୺͕ٻ· Δ 12

  13. ϨΠϚʔνϯάͷ͓͞Β͍ • 3प໨Ͱ΋ԫ৭͍ٿମ͕࠷୹ 13

  14. ϨΠϚʔνϯάͷ͓͞Β͍ • 4प໨ͷϨΠͷઌ୺͕ٻ·Δ 14

  15. ϨΠϚʔνϯάͷ͓͞Β͍ • 4प໨Ͱɺ͍ͭʹ྘ͷശ͕࠷୹ʂʂ 15

  16. ϨΠϚʔνϯάͷ͓͞Β͍ • ϨΠͷઌ୺͕ແࣄʹ྘ͷശͷҐஔͱͳͬͨʂʂ 16

  17. ϨΠϚʔνϯάͷ͓͞Β͍ • ૢ࡞͸ͱͯ΋୯७ ‣ ࠷୹ͷڑ཭͚ͩϨΠΛਐΊΔͷΛ܁Γฦ͚ͩ͢ • Ͱ΋ɺ͏·͘ಈ͘ ‣ ަࠩ͢ΔέʔεͳΒɺ࠷୹ڑ཭ͣͭϨΠΛਐΊΕ͹ɺ ϨΠͷઌ୺͕ަࠩ఺ʹ͍͔ͭ͸౸ୡ͢Δ

    ‣ ࠷୹ڑ཭ͣͭਐΊΔͷͰɺϨΠ͕෺ମΛಥ͖ൈ͚Δ ͜ͱ͕ͳ͍ 17
  18. ϨΠϚʔνϯάͷ͓͞Β͍ • ϨΠτϨͱಉ͡Α͏Α͏ʹγΣʔσΟϯά • ๏ઢ͸ڑ཭ؔ਺ͷޯ഑͔Βܭࢉ 18 vec3 calcNormal(vec3 p) {

    return normalize(vec3( dScene(p + vec3( EPS, 0.0, 0.0)) - dScene(p + vec3( -EPS, 0.0, 0.0)), dScene(p + vec3(0.0, EPS, 0.0)) - dScene(p + vec3(0.0, -EPS, 0.0)), dScene(p + vec3(0.0, 0.0, EPS)) - dScene(p + vec3(0.0, 0.0, -EPS)) )); } ๏ઢ γΣʔσΟϯά
  19. ϨΠϚʔνϯάͷ͓͞Β͍ • ࢀߟࢿྉ ‣ σϞγʔϯ΁Α͏ͦ͜ʢCEDEC 2017ʣ ‣ γΣʔμ͚ͩͰੈքΛ૑Δʂthree.jsʹΑΔϨΠϚʔνϯά 19

  20. ͔͜͜Βຊ୊ 20

  21. X ࣮ࣸతͳϨϯμϦϯάʹෆՄܽͳཁૉ
 ͦΕ͸… େҬর໌ (MPCBM*MMVNJOBUJPO

  22. ίʔωϧϘοΫε • ෦԰͕͋ͬͯɺఱҪʹޫݯ͕1ͭ͋Δγʔϯ • ϥΠςΟϯάͷςετʹ༻͍ΒΕΔ 22

  23. ௚઀ޫ • ௚઀ޫ = ޫݯ͔Β෺ମද໘ʹ௚઀ಧ͘ޫ 23  

  24. ؒ઀ޫ • ؒ઀ޫ = ผͷ෺ମʹ൓ࣹ͔ͯ͠Βؒ઀తʹಧ͘ޫ 24   

  25. ؒ઀ޫͱ֦ࢄ • ޫ͸෺ମʹিಥ͢Δͱɺόϥόϥʹ֦ࢄ͢Δ • ද໘ͷ׈Β͔͞ʹΑ֦ͬͯࢄͷ౓߹͍͸ҟͳΔ • ؒ઀ޫΛ͢΂ͯγϛϡϨʔτ͢Δܭࢉίετ͸ߴ͍ 25 Sebastien Lagarde

    and Charles de Rousiers, “Moving Frostbite to Physically Based Rendering 2.0”, SIGGRAPH 2014 Course: Physically Based Shading in Theory and Practice, p.8
  26. େҬর໌ͱ͸ 26 େҬর໌ (MPCBM*MMVNJOBUJPO
 ௚઀ޫʴؒ઀ޫͷ྆ํΛߟྀ ہॴর໌ -PDBM*MMVNJOBUJPO ௚઀ޫͷΈߟྀ $(ͬΆ͘ෆࣗવ ៉ྷͰ࣮ࣸత

  27. େҬর໌Λ࣮ݱ͢Δख๏ • ΦϑϥΠϯϨϯμϦϯά޲͚ͳΒ ‣ ύετϨʔγϯά • ޫͷܦ࿏ʢύεʣΛ͢΂ͯ௥੻ͯ͠ɺ
 ؒ઀ޫΛܭࢉ • ڀۃͷख๏͕ͩɺ͕͔͔࣌ؒΔ

    • ϦΞϧλΠϜϨϯμϦϯά޲͚ͳΒ ‣ ؒ઀ޫΛΞϯϏΤϯτΦΫϧʔδϣϯͰۙࣅ 27 ϝΨσϞ͸ͬͪ͜
  28. ΞϯϏΤϯτΦΫϧʔδϣϯ • ΞϯϏΤϯτΦΫϧʔδϣϯʢAmbient Occlusion, AOʣ • ःṭʢΦΫϧʔδϣϯʣ͞Ε͍ͯΔ෦෼Λܭࢉͨ͠΋ͷ ‣ ΞϯϏΤϯτʢ؀ڥޫɺͭ·Γؒ઀ޫʣ͕ಧ͘ڧ౓ •

    ܭࢉͷख๏΍λΠϛϯά͸৭ʑ ‣ Unity • ࣄલܭࢉͨ݁͠ՌΛςΫενϟʹ
 ম͖ࠐΉEnlighten ‣ Unreal Engine • DepthόοϑΝ͔ΒϦΞϧλΠϜʹ
 ܭࢉ͢ΔSSAO • Ͱ͸ɺϨΠϚʔνϯάͰ͸Ͳ͏΍Δ͔ʁ 28 ΞϯϏΤϯτΦΫϧʔδϣϯͷΈ http://ambientocclusion.hatenablog.com/entry/2013/10/15/223302
  29. ϨΠϚʔνϯάʹΑΔAOܭࢉͷσϞ • https://www.shadertoy.com/view/Xdtyzj • ShadertoyͰAOܭࢉͷσϞΛ࣮૷ 29

  30. AOΛܭࢉͨ݁͠Ռ 30

  31. • ๏ઢํ޲ n ʹϨΠΛඈ͹ͯ͠ɺःṭ཰ occ Λܭࢉ • ϨΠͷઌ୺͸౳ִؒͰҠಈ AOΛܭࢉ͢ΔGLSLͷίʔυ 31

    float calcAo(in vec3 p, in vec3 n){ float k = 1.0, occ = 0.0; for(int i = 0; i < 5; i++){ float len = 0.15 + float(i) * 0.15; float distance = dScene(n * len + p); occ += (len - distance) * k; k *= 0.5; } return saturate(1.0 - occ); } n p
  32. ःṭ཰occͷܭࢉ 32 ःณ෺ͳ͠ EJTUBODFMFO ःณ෺͋Γ EJTUBODFMFO len distance len distance

    occ += (len - distance) * k;
  33. ϨΠϚʔνϯά޲͚ͷAOܭࢉख๏ 33 AO ϨϯμϦϯά݁Ռ AOͷΈ ϨϯμϦϯά݁Ռ AO͋Γ AOͳ͠

  34. ϨΠϚʔνϯάͷεςοϓ਺ʹΑΔAO • ܭࢉίετ͕௿͍͕ɺ඼࣭΋௿͍ ‣ ܗঢ়͕ෳࡶͳՕॴͰ͸ϨΠϚʔνϯάͷεςοϓ਺͕૿Ճ͢ Δ͜ͱΛར༻ͯ͠AOΛܭࢉ ‣ ःṭ͞Ε͍ͯͳ͍෦෼΋ࠇ͘ͳͬͯ͠·͏ ‣ ݸਓతʹ͸࢖Θͳ͍ख๏

    34
  35. ͓·͚ɿϨΠϚʔνϯά޲͚ͷ
 ϚςϦΞϧ࣮૷ͷ঺հ ৭ʑͳ΍Γํ͕͋Δ͔ͱࢥ͍·͢ɻ
 ͋͘·ͰݸਓతͳϕετϓϥΫςΟεͰ͢ɻ 35

  36. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ ృΓ෼͚͍ͨΦϒδΣΫτຖʹڑ཭ؔ਺Λఆٛ 36 float dSphere(vec3 p, float r) { return

    length(p) - r; } float dSphereCenter(vec3 p) { return dSphere(p - vec3(0.0, 1.0, -0.5), 1.0); } float dSphereLeft(vec3 p) { return dSphere(p - vec3(2.5, 1.0, 0.0), 1.0); } dSphereLeft dSphereCenter
  37. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ িಥ৘ใͷߏ଄ମ Intersection Λఆٛ 37 struct Intersection { bool hit;

    vec3 position; float distance; vec3 normal; vec2 uv; float count; vec3 ambient; vec3 diffuse; vec3 specular; float reflectance; vec3 color; };
  38. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • িಥ൑ఆΛߦ͏ intersectObjects ؔ਺ • ϨΠϚʔνϯάͰަ఺ΛٻΊͨޙ ‣ ΦϒδΣΫτຖͷڑ཭ؔ਺Λൺֱ͠ɺͲͷΦϒδΣΫτʹিಥ͔ͨ͠൑ఆ ‣

    Intersection ʹϚςϦΞϧ৘ใʢambient/diffuse/specularʣΛηοτ 38 void intersectObjects(inout Intersection intersection, inout Ray ray) { float d; float distance = 0.0; vec3 p = ray.origin; for (float i = 0.0; i < 100.0; i++) { d = dObjects(p); distance += d; p = ray.origin + distance * ray.direction; intersection.count = i; if (abs(d) < EPS || distance > 100.0) break; } if (abs(d) < EPS && distance < intersection.distance) { intersection.distance = distance; intersection.hit = true; intersection.position = p; intersection.normal = calcNormal(p, dScene); if (abs(dSphereLeft(p)) < EPS) { intersection.ambient = vec3(0.0); intersection.diffuse = vec3(0.0); intersection.specular = vec3(0.5); intersection.reflectance = 0.9; } else if (abs(dSphereCenter(p)) < EPS) { intersection.ambient = vec3(0.3, 0.3, 0.6) * 1.2; intersection.diffuse = vec3(0.3, 0.3, 0.6) * 0.5; intersection.specular = vec3(0.3); intersection.reflectance = 0.2; } else if (abs(dMengerSpongeRight(p)) < EPS) { intersection.ambient = vec3(0.1, 0.2, 0.1) * 2.0; intersection.diffuse = vec3(0.1, 0.2, 0.1) * 0.2; intersection.specular = vec3(0.0); intersection.reflectance = 0.0; } } } if (abs(dSphereLeft(p)) < EPS) { intersection.ambient = vec3(0.0); intersection.diffuse = vec3(0.0); intersection.specular = vec3(0.5); intersection.reflectance = 0.9; } else if (abs(dSphereCenter(p)) < EPS) { intersection.ambient = vec3(0.3, 0.3, 0.6) * 1.2; intersection.diffuse = vec3(0.3, 0.3, 0.6) * 0.5; intersection.specular = vec3(0.3); intersection.reflectance = 0.2; } else if (abs(dMengerSpongeRight(p)) < EPS) { intersection.ambient = vec3(0.1, 0.2, 0.1) * 2.0; intersection.diffuse = vec3(0.1, 0.2, 0.1) * 0.2; intersection.specular = vec3(0.0); intersection.reflectance = 0.0; }
  39. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • γΣʔσΟϯάΛߦ͏ calcRadiance ؔ਺ • Intersection ͷϚςϦΞϧ৘ใΛ༻͍ͯγΣʔσΟϯά • Phongͷ൓ࣹϞσϧͷܭࢉྫ

    39 void calcRadiance(inout Intersection intersection, inout Ray ray, int bounce) { intersection.hit = false; intersectScene(intersection, ray); if (intersection.hit) { // shading float diffuse = saturate(dot(lightDir, intersection.normal)); float specular = pow(saturate(dot(reflect(lightDir, intersection.normal), ray.direction)), 10.0); float ao = calcAo(intersection.position, intersection.normal); float shadow = calcShadow(intersection.position, lightDir); // mix intersection.color = intersection.ambient * ao + intersection.diffuse * diffuse * shadow + intersection.specular * specular * shadow; // fog intersection.color = mix(intersection.color, vec3(0.8), 1.0 - exp(-0.0001 * intersection.distance * intersection.distance * intersection.distance)); } else { intersection.color = texture(iChannel0, ray.direction).rgb; } }
  40. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • Phongͷ൓ࣹϞσϧ ‣ ϨϯμϦϯά݁Ռ = ؀ڥޫ+ ֦ࢄ൓ࣹ + ڸ໘൓ࣹ

    ‣ https://ja.wikipedia.org/wiki/Phongͷ൓ࣹϞσϧ 40 intersection.color = 
 intersection.ambient * ao + 
 intersection.diffuse * diffuse * shadow + intersection.specular * specular * shadow;
  41. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ Intersection ͷఆٛΛม͑Ε͹ɺ෺ཧϕʔεͷγΣʔσΟϯάʹ΋ରԠͰ͖Δ 41 struct Intersection { bool hit; vec3

    position; float distance; vec3 normal; vec2 uv; float count; vec3 ambient; vec3 diffuse; vec3 specular; float reflectance; vec3 color; }; struct Intersection { bool hit; vec3 position; float distance; vec3 normal; vec2 uv; float count; vec3 albedo; vec3 specular; float metalness; float roughness; vec3 color; }; Phongͷ൓ࣹϞσϧ༻ ෺ཧϕʔεͷ൓ࣹϞσϧ༻
  42. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • ϝϦοτ ‣ ൚༻ੑ΍Մಡੑ͸ߴ͍ • σϝϦοτ ‣ ίʔυ͕௕͘ͳΔ ‣

    4K introͷΑ͏ͳ༰ྔ੍ݶͩͱݫ͍͠ 42
  43. ·ͱΊ • ࣮ࣸతͳϨϯμϦϯάʹ͸େҬর໌ͷߟྀ͕ෆՄܽ • ϦΞϧλΠϜϨϯμϦϯάͰ͸ɺAOʢΞϯϏΤϯτΦ ΫϧʔδϣϯʣͰؒ઀ޫͷӨڹΛۙࣅ͠ɺେҬর໌Λ ߟྀͨ͠γΣʔσΟϯάΛߦ͏ • ϨΠϚʔνϯά޲͚ͷAOܭࢉख๏Λ঺հ •

    ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷Λ঺հ 43
  44. END. 44