Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

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

がむ
March 10, 2018

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

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

がむ

March 10, 2018
Tweet

More Decks by がむ

Other Decks in Technology

Transcript

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

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

    ࣮ફ ‣ ϨΠϚʔνϯάͰେҬর໌Λ࣮ݱ͢Δख๏ͷ঺հ • ͓·͚ ‣ ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ͷ
 ݸਓతϕετϓϥΫςΟεͷ঺հ 3
  3. ϨΠϚʔνϯάͷ͓͞Β͍ • ڑ཭ؔ਺ʢ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
  4. ϨΠϚʔνϯάͷ͓͞Β͍ • ڑ཭ؔ਺ = ఺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
  5. ϨΠϚʔνϯάͷ͓͞Β͍ • ϨΠτϨͱಉ͡Α͏Α͏ʹγΣʔσΟϯά • ๏ઢ͸ڑ཭ؔ਺ͷޯ഑͔Βܭࢉ 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)) )); } ๏ઢ γΣʔσΟϯά
  6. ؒ઀ޫͱ֦ࢄ • ޫ͸෺ମʹিಥ͢Δͱɺόϥόϥʹ֦ࢄ͢Δ • ද໘ͷ׈Β͔͞ʹΑ֦ͬͯࢄͷ౓߹͍͸ҟͳΔ • ؒ઀ޫΛ͢΂ͯγϛϡϨʔτ͢Δܭࢉίετ͸ߴ͍ 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
  7. ΞϯϏΤϯτΦΫϧʔδϣϯ • ΞϯϏΤϯτΦΫϧʔδϣϯʢAmbient Occlusion, AOʣ • ःṭʢΦΫϧʔδϣϯʣ͞Ε͍ͯΔ෦෼Λܭࢉͨ͠΋ͷ ‣ ΞϯϏΤϯτʢ؀ڥޫɺͭ·Γؒ઀ޫʣ͕ಧ͘ڧ౓ •

    ܭࢉͷख๏΍λΠϛϯά͸৭ʑ ‣ Unity • ࣄલܭࢉͨ݁͠ՌΛςΫενϟʹ
 ম͖ࠐΉEnlighten ‣ Unreal Engine • DepthόοϑΝ͔ΒϦΞϧλΠϜʹ
 ܭࢉ͢ΔSSAO • Ͱ͸ɺϨΠϚʔνϯάͰ͸Ͳ͏΍Δ͔ʁ 28 ΞϯϏΤϯτΦΫϧʔδϣϯͷΈ http://ambientocclusion.hatenablog.com/entry/2013/10/15/223302
  8. • ๏ઢํ޲ 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
  9. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ ృΓ෼͚͍ͨΦϒδΣΫτຖʹڑ཭ؔ਺Λఆٛ 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
  10. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ িಥ৘ใͷߏ଄ମ 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; };
  11. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • িಥ൑ఆΛߦ͏ 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; }
  12. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • γΣʔσΟϯάΛߦ͏ 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; } }
  13. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ • Phongͷ൓ࣹϞσϧ ‣ ϨϯμϦϯά݁Ռ = ؀ڥޫ+ ֦ࢄ൓ࣹ + ڸ໘൓ࣹ

    ‣ https://ja.wikipedia.org/wiki/Phongͷ൓ࣹϞσϧ 40 intersection.color = 
 intersection.ambient * ao + 
 intersection.diffuse * diffuse * shadow + intersection.specular * specular * shadow;
  14. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ 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ͷ൓ࣹϞσϧ༻ ෺ཧϕʔεͷ൓ࣹϞσϧ༻