Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

がむ
March 10, 2018

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

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

がむ

March 10, 2018
Tweet

More Decks by がむ

Other Decks in Technology

Transcript

  1. ϨΠϚʔνϯά޲͚ͷ

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

    View full-size slide

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

    GLSL Graphics Compo෦໳ 3Ґೖ৆
    2

    View full-size slide

  3. ൃදͷྲྀΕ
    • ຊ୊ͷલʹ
    ‣ ϨΠϚʔνϯάͷ͓͞Β͍
    • ཧ࿦
    ‣ େҬর໌ͱ͸Կ͔
    • ࣮ફ
    ‣ ϨΠϚʔνϯάͰେҬর໌Λ࣮ݱ͢Δख๏ͷ঺հ
    • ͓·͚
    ‣ ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷ͷ

    ݸਓతϕετϓϥΫςΟεͷ঺հ
    3

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  6. ϨΠϚʔνϯάͷ͓͞Β͍
    • ϨΠϚʔνϯάʢraymarchingʣͰڑ཭ؔ਺ΛՄࢹԽ
    • ϨΠͱ෺ମ΁ͷަࠩ఺ΛٻΊΔํ๏
    ‣ ڑ཭ؔ਺Λ͔ͭͬͯɺ࠷୹ڑ཭͚ͩϨΠΛਐΊΔ
    ‣ ͜ΕΛ܁Γฦ͢
    ‣ े෼ʹڑ཭͕খ͘͞ͳͬͨΒɺަࠩͨ͠ͱ൑ఆ
    6

    View full-size slide

  7. ϨΠϚʔνϯάͷ͓͞Β͍
    • ϨΠͷઌ୺͸ΧϝϥͷҐஔ͔Βελʔτ
    • ͕ϨΠͷઌ୺
    7

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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))
    ));
    }
    ๏ઢ γΣʔσΟϯά

    View full-size slide

  19. ϨΠϚʔνϯάͷ͓͞Β͍
    • ࢀߟࢿྉ
    ‣ σϞγʔϯ΁Α͏ͦ͜ʢCEDEC 2017ʣ
    ‣ γΣʔμ͚ͩͰੈքΛ૑Δʂthree.jsʹΑΔϨΠϚʔνϯά
    19

    View full-size slide

  20. ͔͜͜Βຊ୊
    20

    View full-size slide

  21. X
    ࣮ࣸతͳϨϯμϦϯάʹෆՄܽͳཁૉ

    ͦΕ͸…
    େҬর໌
    (MPCBM*MMVNJOBUJPO

    View full-size slide

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

    View full-size slide

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


    View full-size slide

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



    View full-size slide

  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

    View full-size slide

  26. େҬর໌ͱ͸
    26
    େҬর໌ (MPCBM*MMVNJOBUJPO

    ௚઀ޫʴؒ઀ޫͷ྆ํΛߟྀ
    ہॴর໌ -PDBM*MMVNJOBUJPO
    ௚઀ޫͷΈߟྀ
    $(ͬΆ͘ෆࣗવ ៉ྷͰ࣮ࣸత

    View full-size slide

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

    ؒ઀ޫΛܭࢉ
    • ڀۃͷख๏͕ͩɺ͕͔͔࣌ؒΔ
    • ϦΞϧλΠϜϨϯμϦϯά޲͚ͳΒ
    ‣ ؒ઀ޫΛΞϯϏΤϯτΦΫϧʔδϣϯͰۙࣅ
    27
    ϝΨσϞ͸ͬͪ͜

    View full-size slide

  28. ΞϯϏΤϯτΦΫϧʔδϣϯ
    • ΞϯϏΤϯτΦΫϧʔδϣϯʢAmbient Occlusion, AOʣ
    • ःṭʢΦΫϧʔδϣϯʣ͞Ε͍ͯΔ෦෼Λܭࢉͨ͠΋ͷ
    ‣ ΞϯϏΤϯτʢ؀ڥޫɺͭ·Γؒ઀ޫʣ͕ಧ͘ڧ౓
    • ܭࢉͷख๏΍λΠϛϯά͸৭ʑ
    ‣ Unity
    • ࣄલܭࢉͨ݁͠ՌΛςΫενϟʹ

    ম͖ࠐΉEnlighten
    ‣ Unreal Engine
    • DepthόοϑΝ͔ΒϦΞϧλΠϜʹ

    ܭࢉ͢ΔSSAO
    • Ͱ͸ɺϨΠϚʔνϯάͰ͸Ͳ͏΍Δ͔ʁ
    28
    ΞϯϏΤϯτΦΫϧʔδϣϯͷΈ
    http://ambientocclusion.hatenablog.com/entry/2013/10/15/223302

    View full-size slide

  29. ϨΠϚʔνϯάʹΑΔAOܭࢉͷσϞ
    • https://www.shadertoy.com/view/Xdtyzj
    • ShadertoyͰAOܭࢉͷσϞΛ࣮૷
    29

    View full-size slide

  30. AOΛܭࢉͨ݁͠Ռ
    30

    View full-size slide

  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

    View full-size slide

  32. ःṭ཰occͷܭࢉ
    32
    ःณ෺ͳ͠
    EJTUBODFMFO
    ःณ෺͋Γ
    EJTUBODFMFO
    len
    distance len
    distance
    occ += (len - distance) * k;

    View full-size slide

  33. ϨΠϚʔνϯά޲͚ͷAOܭࢉख๏
    33
    AO ϨϯμϦϯά݁Ռ
    AOͷΈ ϨϯμϦϯά݁Ռ
    AO͋Γ AOͳ͠

    View full-size slide

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

    View full-size slide

  35. ͓·͚ɿϨΠϚʔνϯά޲͚ͷ

    ϚςϦΞϧ࣮૷ͷ঺հ
    ৭ʑͳ΍Γํ͕͋Δ͔ͱࢥ͍·͢ɻ

    ͋͘·ͰݸਓతͳϕετϓϥΫςΟεͰ͢ɻ
    35

    View full-size slide

  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

    View full-size slide

  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;
    };

    View full-size slide

  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;
    }

    View full-size slide

  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;
    }
    }

    View full-size slide

  40. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷
    • Phongͷ൓ࣹϞσϧ
    ‣ ϨϯμϦϯά݁Ռ = ؀ڥޫ+ ֦ࢄ൓ࣹ + ڸ໘൓ࣹ
    ‣ https://ja.wikipedia.org/wiki/Phongͷ൓ࣹϞσϧ
    40
    intersection.color = 

    intersection.ambient * ao + 

    intersection.diffuse * diffuse * shadow +
    intersection.specular * specular * shadow;

    View full-size slide

  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ͷ൓ࣹϞσϧ༻ ෺ཧϕʔεͷ൓ࣹϞσϧ༻

    View full-size slide

  42. ϨΠϚʔνϯά޲͚ͷϚςϦΞϧ࣮૷
    • ϝϦοτ
    ‣ ൚༻ੑ΍Մಡੑ͸ߴ͍
    • σϝϦοτ
    ‣ ίʔυ͕௕͘ͳΔ
    ‣ 4K introͷΑ͏ͳ༰ྔ੍ݶͩͱݫ͍͠
    42

    View full-size slide

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

    View full-size slide