<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>surkim 님의 블로그</title>
    <link>https://surkim.tistory.com/</link>
    <description>ksro0128@naver.com</description>
    <language>ko</language>
    <pubDate>Wed, 5 Aug 2026 18:28:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>surkim</managingEditor>
    <item>
      <title>pt - 15. rchit shader, rmiss shader</title>
      <link>https://surkim.tistory.com/160</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;앞에서 메모리 구조와 rgen shader를 설명했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rgen shader에서 레이를 쏘면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞지 않으면 -&amp;gt; rmiss&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞으면 -&amp;gt; rchit shader로 가고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 정보를 주고 받는 메모리는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;raypayload 구조체로 정의된다.&lt;/p&gt;
&lt;pre id=&quot;code_1755135209598&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct RayPayload {
	vec3 L;
	vec3 beta;
	vec3 nextOrigin;
	vec3 nextDir;
	int bounce;
	uint seed;
	int terminated;
	float pdf;
};


layout(location = 0) rayPayloadInEXT RayPayload payload;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 정의한 RayPayload 구조체이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이에 맞거나 맞지 않거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rchit 나 rmiss 셰이더로 들어오고 이 구조체의 값을 변경할 수 있어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 셰이더의 입출력이 되는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하게도 셰이더로 들어오는 구조체인 rayPayloadInEXT는 무조건 하나여야한다는게 중요하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rchit 셰이더 내부에서도 raypayload구조체를 만들어 자체적으로 레이를 쏠 수 있다. (shadow 판별할 때 썼다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 중요한 부분이라 다시 정리하자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.rgen shader&lt;/p&gt;
&lt;pre id=&quot;code_1755138426010&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	payload.L = vec3(0.0);
	payload.beta = vec3(1.0);
	payload.nextOrigin = origin;
	payload.nextDir = dir;
	payload.bounce = 0;
	payload.seed = initRandom(size, pixel, options.frameCount);
	payload.terminated = 0;


	for (int i = 0; i &amp;lt; 16; ++i) {
		payload.bounce = i;// 이때 payload는 초기화 상태
		traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xFF, 0, 0, 0,
					origin, 0.0001, dir, 1e30, 0);
		// 함수를 거친후 payload는 안의 값이 rchit or rmiss 셰이더로 인해 변경된 상태
		if (payload.terminated != 0) break;

		if (i &amp;gt; 2) {
			float p = clamp(max(payload.beta.r, max(payload.beta.g, payload.beta.b)), 0.05, 1.0);
			if (rand(payload.seed) &amp;gt; p) {
				break;
			}
			payload.beta /= p;
		}

		origin = payload.nextOrigin;
		dir = payload.nextDir;
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 traceRayEXT 함수로 레이를 쏘면 raypayload구조체가 rchit나 rmiss로 가게 되고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 구조체 내부의 변수를 셰이더 내부에서 변경하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 rgen 셰이더로 왔을 때 그 값이 변경되는 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 설명했으니 셰이더 코드를 봐보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.rmiss&lt;/p&gt;
&lt;pre id=&quot;code_1755138648905&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() {
    payload.terminated = 1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;miss는 쉬운게 그냥 terminated를 1로 조정하여 끝내버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광원까지 무조건 가야 계산되기 때문에 초기에 miss가 나든 몇번 튕겨 miss나든 똑같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.rchit&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 메인 흐름부터&lt;/p&gt;
&lt;pre id=&quot;code_1755138851307&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() {
    uint instanceID = gl_InstanceCustomIndexEXT;
    InstanceGPU instance = instances[instanceID];

    vec3 N, P;
    computeHitNormal(N, P);
    vec3 wo = -normalize(gl_WorldRayDirectionEXT);
    
    if (instance.lightIndex &amp;gt;= 0) {
        AreaLightGPU light = areaLights[instance.lightIndex];

        vec3 lightNormal = normalize(light.normal);

        if (dot(lightNormal, wo) &amp;lt; 0) {
            payload.terminated = 1;
            return ;
        }

        if (payload.bounce == 0) {
            payload.L = light.color;
            payload.terminated = 1;
            return ;
        }

        if (payload.bounce &amp;gt; 2) {
            payload.L += light.color * light.intensity * payload.beta;
            payload.terminated = 1;
            return ;
        }

        vec3 dir = P - gl_WorldRayOriginEXT;
        float dist = length(dir);
        float dist2 = dist * dist;
        vec3 L_wi = normalize(dir);

        float cosTheta = max(dot(lightNormal, -L_wi), 0.001);
        float areaPdf = 1.0 / light.area;
        float solidAnglePdf = dist2 / (cosTheta + 0.001) * areaPdf;
        float L_pdf = solidAnglePdf / float(options.lightCount);

        float w = L_pdf / (L_pdf + payload.pdf);

        payload.L += light.color * light.intensity * payload.beta * w;
        payload.terminated = 1;
        return;
    }

    // if (dot(N, wo) &amp;lt; 0) {
    //     payload.terminated = 1;
    //     return ;
    // }

    int matIdx = instance.materialIndex;
    MaterialGPU mat = materials[matIdx];


    vec2 uv = getUV();
    mat = copyMaterial(mat, uv);

    payload.beta *= mat.ao;

    if (payload.bounce == 0)
        sampleDirect(N, P, wo, mat);

    sampleIndirect(N, P, wo, mat);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한줄 한줄 설명 들어간다.&lt;/p&gt;
&lt;pre id=&quot;code_1755138895826&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;    uint instanceID = gl_InstanceCustomIndexEXT;
    InstanceGPU instance = instances[instanceID];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 TLAS 생성할 때 BLAS 인스턴스에 붙인 커스텀 정의값을 불러오는 함수이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해 rchit 셰이더에 들어왔으면 어디에든 레이가 오브젝트에 맞았다는 뜻이고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 오브젝트는 blas로 정의되어있고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 blas 정의할 때 커스텀 인덱스를 부여해놔서 이 인스턴스가 어떤 인스턴스인지 확인하는 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755139108196&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    vec3 N, P;
    computeHitNormal(N, P);
    vec3 wo = -normalize(gl_WorldRayDirectionEXT);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞은 지점과 그 지점의 표면의 법선 벡터를 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;wo는 표면에 들어온 레이 벡터 계산이다. gl_ 붙여있는거는 내장 변수들이다.&lt;/p&gt;
&lt;pre id=&quot;code_1755140034657&quot; class=&quot;cpp&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;    if (instance.lightIndex &amp;gt;= 0) {
        AreaLightGPU light = areaLights[instance.lightIndex];

        vec3 lightNormal = normalize(light.normal);

        if (dot(lightNormal, wo) &amp;lt; 0) {
            payload.terminated = 1;
            return ;
        }

        if (payload.bounce == 0) {
            payload.L = light.color;
            payload.terminated = 1;
            return ;
        }

        if (payload.bounce &amp;gt; 2) {
            payload.L += light.color * light.intensity * payload.beta;
            payload.terminated = 1;
            return ;
        }

        vec3 dir = P - gl_WorldRayOriginEXT;
        float dist = length(dir);
        float dist2 = dist * dist;
        vec3 L_wi = normalize(dir);

        float cosTheta = max(dot(lightNormal, -L_wi), 0.001);
        float areaPdf = 1.0 / light.area;
        float solidAnglePdf = dist2 / (cosTheta + 0.001) * areaPdf;
        float L_pdf = solidAnglePdf / float(options.lightCount);

        float w = L_pdf / (L_pdf + payload.pdf);

        payload.L += light.color * light.intensity * payload.beta * w;
        payload.terminated = 1;
        return;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스로 확인해봤을 때 표면에 맞은 부분이 광원일 때 계산이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;path tracing이 진행될 때마다 payload의 beta부분이 계속 갱신되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광원에 맞았을 때 그 광원의 정보를 가져와&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 계산했던 throughput(beta)와 계산하여 최종 샘플 색인 L을 구하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱 bounce가 1일때만 휴리스틱 벨런스(w)를 적용해줘야하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 바운스된곳에서 NEE를 딱 한번만 적용시켰기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;raypayload에 많은 정보를 넣을 수가 없어서 광원에 맞았을 때 레이가 발사된 지점을 역산해서 pdf를 구해줘야했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755142953613&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    int matIdx = instance.materialIndex;
    MaterialGPU mat = materials[matIdx];


    vec2 uv = getUV();
    mat = copyMaterial(mat, uv);

    payload.beta *= mat.ao;

    if (payload.bounce == 0)
        sampleDirect(N, P, wo, mat);

    sampleIndirect(N, P, wo, mat);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞은 표면의 material을 찾아서 처음 튕겼을 때는 직접광도 계산하고(NEE)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후부터는 간접광만 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간접광 계산부터 한번 봐보자&lt;/p&gt;
&lt;pre id=&quot;code_1755143041223&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void sampleIndirect(in vec3 N, in vec3 P, in vec3 wo, in MaterialGPU mat)
{
    vec3 baseColor = mat.baseColor.rgb;
    vec3 Kd = baseColor * (1.0 - mat.metallic);
    vec3 F0 = mix(vec3(0.04), baseColor, mat.metallic);
    float probSpec = max(max(F0.r, F0.g), F0.b);

    vec3 H = vec3(0.0);
    vec3 wi = vec3(0.0);
    vec3 f = vec3(0.0);
    float pdf = 1.0;
    float tpdf = 1.0;
    
    int sampledSpecular = rand(payload.seed) &amp;lt; probSpec ? 1 : 0;

    if (sampledSpecular != 0) {
        vec2 Xi = sample2D(payload.seed);
        H = importanceSampleGGX(Xi, N, mat.roughness);
        wi = normalize(reflect(-wo, H));
    } else {
        vec3 localWi = cosineSampleHemisphere(payload.seed);
        wi = normalize(toWorld(localWi, N));
        H = normalize(wo + wi);
    }

    float NdotL = max(dot(N, wi), 0.001);
    float NdotV = max(dot(N, wo), 0.001);
    float NdotH = max(dot(N, H), 0.001);
    float VdotH = max(dot(wo, H), 0.001);

    if (sampledSpecular == 1 &amp;amp;&amp;amp; dot(wo, N) * dot(wi, N) &amp;lt; 0.0) {
        payload.terminated = 1;
        return;
    }

    float D = distributionGGX(N, H, mat.roughness);
    float G = geometrySmith(N, wo, wi, mat.roughness);
    vec3 F_refl = fresnelSchlick(VdotH, F0);

    vec3 specularf = (D * G * F_refl) / max(4.0 * NdotV * NdotL, 1e-4);
    vec3 diffusef = Kd / PI;

    float pdf_diff = NdotL / PI * (1.0 - probSpec);
    float pdf_spec = D * NdotH / (4.0 * VdotH + 1e-4) * probSpec;

    float sumPdf = pdf_diff + pdf_spec;
    float misWeight = (sampledSpecular != 0) ? (pdf_spec / sumPdf) : (pdf_diff / sumPdf);

    f = (sampledSpecular != 0) ? specularf * misWeight : diffusef * misWeight;
    pdf = (sampledSpecular != 0) ? pdf_spec : pdf_diff;

    payload.beta *= f * NdotL / max(pdf, 1e-4);
    payload.nextOrigin = P + wi * 0.001;
    payload.nextDir = wi;
    payload.terminated = 0;
    payload.pdf = pdf;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143240403&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    vec3 baseColor = mat.baseColor.rgb;
    vec3 Kd = baseColor * (1.0 - mat.metallic);
    vec3 F0 = mix(vec3(0.04), baseColor, mat.metallic);
    float probSpec = max(max(F0.r, F0.g), F0.b);

    vec3 H = vec3(0.0);
    vec3 wi = vec3(0.0);
    vec3 f = vec3(0.0);
    float pdf = 1.0;
    float tpdf = 1.0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값들 초기화해주는 부분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143283484&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    int sampledSpecular = rand(payload.seed) &amp;lt; probSpec ? 1 : 0;

    if (sampledSpecular != 0) {
        vec2 Xi = sample2D(payload.seed);
        H = importanceSampleGGX(Xi, N, mat.roughness);
        wi = normalize(reflect(-wo, H));
    } else {
        vec3 localWi = cosineSampleHemisphere(payload.seed);
        wi = normalize(toWorld(localWi, N));
        H = normalize(wo + wi);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이의 출력방향 샘플링해주는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은 metallic성분으로 만든 probSpec 변수를 통해 출력 방향 로브를 랜덤으로 선택하는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 확률은 나중에 pdf 계산할 때 꼭 들어가야하므로 기억해두고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확률에 따라서 디퓨즈 로브를 선택할지 스페큘러 로브를 선택할지 정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOPWJh/btsPTzYAky5/bwWnxYBGnm8Q69I4qLQGTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOPWJh/btsPTzYAky5/bwWnxYBGnm8Q69I4qLQGTK/img.png&quot; data-alt=&quot;예시로서 딱 좋은 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOPWJh/btsPTzYAky5/bwWnxYBGnm8Q69I4qLQGTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOPWJh%2FbtsPTzYAky5%2FbwWnxYBGnm8Q69I4qLQGTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;585&quot; height=&quot;166&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;166&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예시로서 딱 좋은 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143597870&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    float NdotL = max(dot(N, wi), 0.001);
    float NdotV = max(dot(N, wo), 0.001);
    float NdotH = max(dot(N, H), 0.001);
    float VdotH = max(dot(wo, H), 0.001);

    if (sampledSpecular == 1 &amp;amp;&amp;amp; dot(wo, N) * dot(wi, N) &amp;lt; 0.0) {
        payload.terminated = 1;
        return;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산을 위한 사전 작업과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력방향이 혹여 표면 반구의 반대방향이 나올 수도 있는 것을 방지하는 코드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143654114&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    float D = distributionGGX(N, H, mat.roughness);
    float G = geometrySmith(N, wo, wi, mat.roughness);
    vec3 F_refl = fresnelSchlick(VdotH, F0);

    vec3 specularf = (D * G * F_refl) / max(4.0 * NdotV * NdotL, 1e-4);
    vec3 diffusef = Kd / PI;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ggx 마이크로패싯 계산 + diffuse 램버트 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143727480&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    float pdf_diff = NdotL / PI * (1.0 - probSpec);
    float pdf_spec = D * NdotH / (4.0 * VdotH + 1e-4) * probSpec;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이를 결정했을 때 이걸 선택한 확률을 구해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은 디퓨즈 스페큘러 로브를 probSpec 변수로 나눴으니 이것도 꼭 곱해서 적용해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143824968&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    float sumPdf = pdf_diff + pdf_spec;
    float misWeight = (sampledSpecular != 0) ? (pdf_spec / sumPdf) : (pdf_diff / sumPdf);

    f = (sampledSpecular != 0) ? specularf * misWeight : diffusef * misWeight;
    pdf = (sampledSpecular != 0) ? pdf_spec : pdf_diff;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구한 pdf로 밸런스 휴리스틱 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;f와 pdf 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1755143976863&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    payload.beta *= f * NdotL / max(pdf, 1e-4);
    payload.nextOrigin = P + wi * 0.001;
    payload.nextDir = wi;
    payload.terminated = 0;
    payload.pdf = pdf;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throughput 업데이트와 다음 바운스 세팅을 하면 끝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접광계산은 비슷하지만 다른부분이 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1755145183940&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void sampleDirect(in vec3 N, in vec3 P, in vec3 wo, in MaterialGPU mat)
{
    vec3 Kd = mat.baseColor.rgb * (1.0 - mat.metallic);
    vec3 F0 = mix(vec3(0.04), mat.baseColor.rgb, mat.metallic);
    float probSpec = max(max(F0.r, F0.g), F0.b);

    // Light sampling
    int lightIdx = int(mod(rand(payload.seed) * float(options.lightCount), float(options.lightCount)));
    AreaLightGPU light = areaLights[lightIdx];

    // sample point on quad (light.p0~p3)
    float u = rand(payload.seed);
    float v = rand(payload.seed);
    vec3 sampledPos;
    if (u + v &amp;lt;= 1.0) {
        sampledPos = light.p0 * (1.0 - u - v) + light.p1 * u + light.p2 * v;
    } else {
        u = 1.0 - u;
        v = 1.0 - v;
        sampledPos = light.p2 * (1.0 - u - v) + light.p3 * u + light.p0 * v;
    }

    vec3 lightNormal = normalize(light.normal);
    vec3 dir = sampledPos - P;
    float dist = length(dir);
    float dist2 = dist * dist;
    vec3 L_wi = normalize(dir);

    float cosTheta = max(dot(lightNormal, -L_wi), 0.001);
    float areaPdf = 1.0 / light.area;
    float solidAnglePdf = dist2 / (cosTheta + 0.001) * areaPdf;
    float L_pdf = solidAnglePdf / float(options.lightCount);

    // Shadow test
    isShadowed = true;
    traceRayEXT(topLevelAS, 
        gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT,
        0xFF, 0, 0, 1, 
        P + N * 0.0001, 0.0001, L_wi, dist * 0.99, 1);

    if (isShadowed || dot(L_wi, N) &amp;lt; 0.0 || L_pdf &amp;lt;= 0.0)
        return;

    // BRDF evaluation
    vec3 H = normalize(wo + L_wi);

    float NdotL = max(dot(N, L_wi), 0.001);
    float NdotV = max(dot(N, wo), 0.001);
    float NdotH = max(dot(N, H), 0.001);
    float VdotH = max(dot(wo, H), 0.001);

    float D = distributionGGX(N, H, mat.roughness);
    float G = geometrySmith(N, wo, L_wi, mat.roughness);
    vec3 F  = fresnelSchlick(VdotH, F0);

    vec3 specularf = (D * G * F) / max(4.0 * NdotV * NdotL, 0.001);
    vec3 diffusef = Kd / PI;

    float pdf_diff = NdotL / PI * (1.0 - probSpec);
    float pdf_spec = D * NdotH / (4.0 * VdotH + 0.001) * probSpec;

    vec3 f = specularf + diffusef;
    float pdfBRDF = max(pdf_diff + pdf_spec, 0.001);

    // Final contribution with MIS weight
    vec3 direct = (f * light.color * light.intensity * NdotL) / L_pdf;
    float w = L_pdf / (L_pdf + pdfBRDF);
    payload.L += payload.beta * direct * w;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산은 비슷하니 전체적으로 설명하자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접광은 광원을 직접 샘플링해야하기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광원 인덱스에서 랜덤으로 하나를 뽑았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 가까운 광원이나 더 영향을 많이 줄 것 같은 광원에 확률를 높게주는 기법이 있긴한데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 그냥 고른 분포로 뽑게 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뽑은 광원의 한 지점을 결정하여 레이의 방향을 결정하고 레이를 한번 쏴서 그림자인지 아닌지 판단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림자가 아니라고 판단되면 (광원에 레이를 쏴서 그 중간에 아무것도 맞지 않으면)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 광원에 대한 brdf를 평가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때는 보통의 광원 계산과 같이 diffuse와 specular를 같이 평가하여 더하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MIS 보정을 위해 광원 선택확률과 brdf평가 확률로 보정계수 w를 계산하고 직접광 계산에 곱해주면 끝!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/160</guid>
      <comments>https://surkim.tistory.com/160#entry160comment</comments>
      <pubDate>Thu, 14 Aug 2025 12:25:41 +0900</pubDate>
    </item>
    <item>
      <title>pt - 14. gltf를 지원하는 path tracing 렌더러</title>
      <link>https://surkim.tistory.com/159</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;재질 통합을 완료하고 gltf를 지원하는 렌더러로 바꿨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;ui 상 왼쪽 위는 오브젝트, 아래는 area light를 조정할 수 있는 ui이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다중 광원 역시 지원 가능하다. (물론 area light 중 사각형만..!)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-08-12 170936.png&quot; data-origin-width=&quot;2878&quot; data-origin-height=&quot;1798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIibGX/btsPQGjIlXN/ZKMbIi6m4mSQImXK72kYS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIibGX/btsPQGjIlXN/ZKMbIi6m4mSQImXK72kYS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIibGX/btsPQGjIlXN/ZKMbIi6m4mSQImXK72kYS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIibGX%2FbtsPQGjIlXN%2FZKMbIi6m4mSQImXK72kYS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2878&quot; height=&quot;1798&quot; data-filename=&quot;화면 캡처 2025-08-12 170936.png&quot; data-origin-width=&quot;2878&quot; data-origin-height=&quot;1798&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산식 통합이야 계속 해왔던거라 쉬웠는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오히려 오브젝트 추가 제거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;area light도 오브젝트 취급인데 light 속성을 지니고 있으니 이걸 구분지어주는 것에 애먹었었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각해보니 내 path tracing 계산식에 대한 코드와 메모리들 설명을 여기다가 안적어서 정리해서 적어 놔야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오브젝트, arealight, material, camera, options 전부 gpu에 올려 놓았고 메모리 구조는 이렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 카메라&lt;/p&gt;
&lt;pre id=&quot;code_1754986970924&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;layout (set = 0, binding = 0) uniform CameraGPU {
    vec3 camPos;
    float pad0;
    vec3 camDir;
    float pad1;
    vec3 camUp;
    float pad2;
    vec3 camRight;
    float fovY;
} camera;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 빡빡하게 메모리 정렬을 맞춰주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 역량 부족인지 뭔지 작업하는 컴퓨터가 각각 스펙이 다른 3대(rtx2060 super, rtx3060, rtx4070labtop)여서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;돌려가며 작업했었는데 왜인지 정렬을 굉장히 빡빡하게 안맞춰주면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어디선가 항상 삑사리가 났고 화딱지 나서 정확하게 16바이트씩 맞춰줬었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특별할 거 없는 카메라 정보이고 위치, 방향, up, right, fov를 gpu에 올려둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 옵션&lt;/p&gt;
&lt;pre id=&quot;code_1754987283799&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;layout (set = 0, binding = 1) uniform OptionsGPU {
    int frameCount;
    int maxSpp;
    int currentSpp;
    int lightCount;
} options;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션은 일단 만들어두고 그때그때 필요할 때마다 추가해주는 형식으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 친화적으로 만든 구조체였고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 frame count, 최대 spp, 현재 spp, light 개수가 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 인스턴스 (오브젝트)&lt;/p&gt;
&lt;pre id=&quot;code_1754987399982&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct InstanceGPU {
    mat4 transform;

    uint64_t vertexAddress;
    uint64_t indexAddress;

    int lightIndex;
    int materialIndex;
    int meshIndex;
    float pad0;
};
layout(set = 3, binding = 0) buffer InstanceBuffer {
    InstanceGPU instances[];
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 transform을 가지고 있는 오브젝트들 묶음이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 오브젝트도 light도 될 수가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;blas에 직접적으로 1대1 대응하는 인스턴스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이에 맞았을 때 이 인스턴스를 찾아서 무엇에 맞는지 알아내는 용도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각 인덱스를 가지고 있고 자발광이 아닐때는 lightIndex 가 -1로 초기화 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요 인덱스를 가지고 bindless형태로 각 세부정보를 확인하여 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞은 표면의 노말값과 uv값을 정확하게 알기위해 vetexAddress와 indexAddress를 cpu단에서 먼저 보내줘야 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. material&lt;/p&gt;
&lt;pre id=&quot;code_1754987760277&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct MaterialGPU {
    vec4 baseColor;
    vec3 emissiveFactor;
    float roughness;

    float metallic;
    float ao;
    int albedoTexIndex;
    int normalTexIndex;

    int metallicTexIndex;
    int roughnessTexIndex;
    int aoTexIndex;
    int emissiveTexIndex;

    int doubleSided;
    float transmissionFactor;
    float ior;
    float pad0;
};

layout (set = 1, binding = 0) buffer MaterialBuffer {
    MaterialGPU materials[];
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;path tracing 계산에 필요한 material 정보이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 bindless 형태로 gpu에 보내고 인덱스로 확인하는 구조로 짰고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통합재질이라 + gltf의 특성에 맞춰 메모리를 구성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱히 어려울 건 없고 여기서 중요한 포인트는 texture 인덱스를 또 bindless 형태로 찾아 들어간다는 점?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;doubleSided는 이때 알게 되었는데 렌더링중에 특정 오브젝트가 특히 군데군데만 깜해서 찾아봤더니 doubleSided가 켜져있는 gltf파일은 뒷면에 맞아도 렌더링해야한다는 점을 알게되었었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 밑의 transmissionFactor와 ior은 투과의 잔재이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. texture&lt;/p&gt;
&lt;pre id=&quot;code_1754988000770&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;layout(set = 2, binding = 0) uniform sampler2D textures[];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스쳐도 bindless형태로 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트 부터 bindless를 알게되어서 아주 적극적으로 사용해준 기억이 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 프로젝트에선 디스크립터 셋 구조가 난리가 났었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. areaLight&lt;/p&gt;
&lt;pre id=&quot;code_1754988092202&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct AreaLightGPU {
    vec3 color;
    float intensity;

    vec3 p0;
    float area;
    vec3 p1;
    float pad0;
    vec3 p2;
    float pad1;
    vec3 p3;
    float pad2;

    vec3 normal;
    float pad3;
};
layout(set = 3, binding = 1) buffer AreaLightBuffer {
    AreaLightGPU areaLights[];
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 사각형만 했고 직접광을 샘플링하기위해 점 4개가 다 필요했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 좋은 방법이 있긴 할텐데 그냥 모든 정보를 올리는 방법으로 쉽게 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스에서 타고 들어가 인덱스로 light정보를 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이정도가 얼추 path tracing에서 필요한 정보들이고 이 외에도 tlas, 그리고 출력용 이미지가 gpu에 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 렌더링이 시작되면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rgen shader에서 시작된다.&lt;/p&gt;
&lt;pre id=&quot;code_1754988320284&quot; class=&quot;glsl&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;void main() {

	if (options.currentSpp &amp;gt;= options.maxSpp) {
		return;
	}


    uvec2 pixel = gl_LaunchIDEXT.xy;
    uvec2 size = gl_LaunchSizeEXT.xy;
    
	// vec2 uv = (vec2(pixel) + vec2(0.5)) / vec2(size);

    uint seed = initRandom(size, pixel, options.frameCount);
	vec2 jitter = vec2(rand(seed), rand(seed));
	vec2 uv = (vec2(pixel) + jitter) / vec2(size);

    vec2 screen = uv * 2.0 - 1.0;
    screen.y = -screen.y;
    float aspect = float(size.x) / float(size.y);
    float scale = tan(radians(camera.fovY) * 0.5);

    vec3 dir = normalize(
        screen.x * aspect * scale * camera.camRight +
        screen.y * scale * camera.camUp +
        camera.camDir
    );
	vec3 origin = camera.camPos;


	payload.L = vec3(0.0);
	payload.beta = vec3(1.0);
	payload.nextOrigin = origin;
	payload.nextDir = dir;
	payload.bounce = 0;
	payload.seed = initRandom(size, pixel, options.frameCount);
	payload.terminated = 0;


	for (int i = 0; i &amp;lt; 16; ++i) {
		payload.bounce = i;
		traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xFF, 0, 0, 0,
					origin, 0.0001, dir, 1e30, 0);
		
		if (payload.terminated != 0) break;

		if (i &amp;gt; 2) {
			float p = clamp(max(payload.beta.r, max(payload.beta.g, payload.beta.b)), 0.05, 1.0);
			if (rand(payload.seed) &amp;gt; p) {
				break;
			}
			payload.beta /= p;
		}

		origin = payload.nextOrigin;
		dir = payload.nextDir;
	}

	ivec2 ipixel = ivec2(pixel);

	// 누적 버퍼
	vec4 prevAccum = vec4(0.0);
	if (options.currentSpp &amp;gt; 0) {
		prevAccum = imageLoad(accumPrevImage, ipixel);
	}
	vec4 newAccum = prevAccum + vec4(payload.L, 1.0);
	imageStore(accumCurImage, ipixel, newAccum);

	// 현재 샘플 수로 정규화된 출력
	vec3 finalColor = newAccum.rgb / (float(options.currentSpp) + 1.0f);
	imageStore(outputImage, ipixel, vec4(finalColor, 1.0));

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ray가 생성되는 곳이고 딱히 어렵다할 부분은 없는데 하나씩 설명하자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&lt;/p&gt;
&lt;pre id=&quot;code_1754988395670&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (options.currentSpp &amp;gt;= options.maxSpp) {
		return;
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어오자마자 현재와 맥스 spp를 확인하여 이미 max에 도달했다면 별다른 일 없이 리턴이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&lt;/p&gt;
&lt;pre id=&quot;code_1754988501202&quot; class=&quot;mel&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;    uvec2 pixel = gl_LaunchIDEXT.xy;
    uvec2 size = gl_LaunchSizeEXT.xy;
    
	// vec2 uv = (vec2(pixel) + vec2(0.5)) / vec2(size);

    uint seed = initRandom(size, pixel, options.frameCount);
	vec2 jitter = vec2(rand(seed), rand(seed));
	vec2 uv = (vec2(pixel) + jitter) / vec2(size);

    vec2 screen = uv * 2.0 - 1.0;
    screen.y = -screen.y;
    float aspect = float(size.x) / float(size.y);
    float scale = tan(radians(camera.fovY) * 0.5);

    vec3 dir = normalize(
        screen.x * aspect * scale * camera.camRight +
        screen.y * scale * camera.camUp +
        camera.camDir
    );
	vec3 origin = camera.camPos;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 들어온 곳이 화면의 어느 픽셀인지 계산을 하여 카메라의 위치와 화면을 고려하여 레이의 위치와 방향을 결정하는 단계이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 jitter부분은 서브픽셀의 렌덤위치에서 레이를 생성하여 엘리어싱을 방지해주는 기법을 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&lt;/p&gt;
&lt;pre id=&quot;code_1754988640269&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	payload.L = vec3(0.0);
	payload.beta = vec3(1.0);
	payload.nextOrigin = origin;
	payload.nextDir = dir;
	payload.bounce = 0;
	payload.seed = initRandom(size, pixel, options.frameCount);
	payload.terminated = 0;


	for (int i = 0; i &amp;lt; 16; ++i) {
		payload.bounce = i;
		traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xFF, 0, 0, 0,
					origin, 0.0001, dir, 1e30, 0);
		
		if (payload.terminated != 0) break;

		if (i &amp;gt; 2) {
			float p = clamp(max(payload.beta.r, max(payload.beta.g, payload.beta.b)), 0.05, 1.0);
			if (rand(payload.seed) &amp;gt; p) {
				break;
			}
			payload.beta /= p;
		}

		origin = payload.nextOrigin;
		dir = payload.nextDir;
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;payload는 rgen 셰이더와 rchit, rmiss 셰이더간 정보 교환이 일어나는 구조체다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rgen에서 payload를 생성하여 초기화해준뒤 레이를 쏘면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;blas로 생성된 오브젝트가 맞았을때 rchit 셰이더로 들어가는 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쏠 때 거리를 지정해줄 수 있는데 그 거리만큼 레이가 갔는데도 blas구조에 맞지 않으면 rmiss 셰이더로 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 payload 초기화와 직접적으로 path tracing이 일어나는 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 16번을 튕기면서 레이를 쏘는데 쏘면 rchit나 rmiss 셰이더에 들어가고 payload구조체가 갱신되고 다시 레이를 쏘는 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안에 if문은 러시안 룰렛 기법으로 기여도가 너무 없는 레이를 확률적으로 삭제하는 로직이다. 이게 없으면 끝까지 16번 돌것이고 이러면 1spp를 생성하는데 너무 많은 계산이 들어가게 된다. (1번의 샘플을 만들기 위해 해상도 x 16번의 path tracing 계산)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.&lt;/p&gt;
&lt;pre id=&quot;code_1754989078175&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	ivec2 ipixel = ivec2(pixel);

	// 누적 버퍼
	vec4 prevAccum = vec4(0.0);
	if (options.currentSpp &amp;gt; 0) {
		prevAccum = imageLoad(accumPrevImage, ipixel);
	}
	vec4 newAccum = prevAccum + vec4(payload.L, 1.0);
	imageStore(accumCurImage, ipixel, newAccum);

	// 현재 샘플 수로 정규화된 출력
	vec3 finalColor = newAccum.rgb / (float(options.currentSpp) + 1.0f);
	imageStore(outputImage, ipixel, vec4(finalColor, 1.0));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다 계산이 되면&amp;nbsp; payload의 L부분이 그 픽셀의 샘플 색이 되는 거고 이를 누적하여 출력용 이미지에 적재하면 path tracing 종료이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 여기까지 하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음은 레이를 발사해서 오브젝트 어딘가에 맞았을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드의&lt;/p&gt;
&lt;pre id=&quot;code_1755134716604&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xFF, 0, 0, 0,
					origin, 0.0001, dir, 1e30, 0);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이부분 이후의 rchit 또는 rmiss 셰이더에서 일어나는 일을 써야겠다.&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/159</guid>
      <comments>https://surkim.tistory.com/159#entry159comment</comments>
      <pubDate>Tue, 12 Aug 2025 18:02:48 +0900</pubDate>
    </item>
    <item>
      <title>pt - 13. svgf 폐기</title>
      <link>https://surkim.tistory.com/158</link>
      <description>&lt;p data-end=&quot;149&quot; data-start=&quot;36&quot; data-ke-size=&quot;size16&quot;&gt;호기롭게 SVGF(Screen Space Variance Guided Filtering) 적용을 시도했지만,&lt;br /&gt;원하는 퍼포먼스가 나오지 않아 폐기하기로 했다.&lt;br /&gt;필터 자체의 한계도 명확히 보였다.&lt;/p&gt;
&lt;p data-end=&quot;149&quot; data-start=&quot;36&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;228&quot; data-start=&quot;151&quot; data-ke-size=&quot;size16&quot;&gt;그래도 얻은 건 있었다.&lt;br /&gt;논문을 찾아 읽고 직접 구현해본 경험,&lt;br /&gt;그리고 구현 과정에서 여러 문제를 맞닥뜨리고 해결해본 경험이다.&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;가장 기억남는것중 하나가 알베도 디모듈레이션(demodulation) 과정에서 생긴 문제다.&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;필터 적용 전에 알베도 성분이 날아가는 것을 방지하여&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;빛 성분을 알베도로 나누는 방식인데, 처음에는 모든 픽셀에 그대로 적용했다.&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;그 결과, 알베도가 0에 가깝거나 아예 없는 픽셀에서도 나눗셈이 일어나 값이 튀었고,&lt;br /&gt;히스토리 버퍼가 오염되면서 노이즈가 크게 발생했다.&lt;/p&gt;
&lt;p data-end=&quot;503&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;특히 Path Tracing에서는 완전 스펙큘러 반사나 광원 직접 샘플링, 그리고 디퓨즈 스페큘러 섞여 있는 재질에서도 확률상 스페큘러만 계산되는 것도 있어서 결국 알베도 개념이 없는 픽셀이 많다.&lt;/p&gt;
&lt;p data-end=&quot;503&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;이런 경우까지 나눗셈을 하니 깨끗해야 할 값이 망가졌다.&lt;/p&gt;
&lt;p data-end=&quot;611&quot; data-start=&quot;505&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;611&quot; data-start=&quot;505&quot; data-ke-size=&quot;size16&quot;&gt;마지막에는 조건을 걸어, 알베도가 존재하고 일정 값 이상일 때만 나누도록 수정했다.&lt;/p&gt;
&lt;p data-end=&quot;611&quot; data-start=&quot;505&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 해서 문제는 해결했지만, 전체적인 구조와 성능 문제로 SVGF 자체는 사용하지 않기로 했다.&lt;/p&gt;
&lt;p data-end=&quot;800&quot; data-start=&quot;613&quot; data-ke-size=&quot;size16&quot;&gt;성능 면에서는 Path Tracing 원본 출력은 노이즈가 있어도 현실감이 강하게 느껴졌는데,&lt;br /&gt;SVGF를 적용하면 노이즈는 줄지만 화면이 부드럽게 뭉개져서 오히려 밋밋해 보였다.&lt;/p&gt;
&lt;p data-end=&quot;800&quot; data-start=&quot;613&quot; data-ke-size=&quot;size16&quot;&gt;특히 디모듈 모듈 문제에서 스페큘러 부분이 많이 없어져버리는 문제가 심했다.&lt;/p&gt;
&lt;p data-end=&quot;800&quot; data-start=&quot;613&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;게다가 필터 과정이 생각보다 느려, 기대했던 프레임 향상 효과도 없었다.&lt;br /&gt;결국 효과와 성능 모두 만족스럽지 않다는 결론을 내리고 폐기했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2124&quot; data-origin-height=&quot;1114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HHf6Z/btsPPLFy2cx/CRDdtR7wmGjGwf4Zz3doRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HHf6Z/btsPPLFy2cx/CRDdtR7wmGjGwf4Zz3doRk/img.png&quot; data-alt=&quot;총 정리 ppt 중 일부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HHf6Z/btsPPLFy2cx/CRDdtR7wmGjGwf4Zz3doRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHHf6Z%2FbtsPPLFy2cx%2FCRDdtR7wmGjGwf4Zz3doRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2124&quot; height=&quot;1114&quot; data-origin-width=&quot;2124&quot; data-origin-height=&quot;1114&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;총 정리 ppt 중 일부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃에는 PBRT-bathroom-renderer 로 옮겨서 path tracing 만 적용된 버전으로 따로 옮기고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소개문을 작성해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/ksro0128/PBRT_bathroom_renderer&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/ksro0128/PBRT_bathroom_renderer&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1754983317105&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - ksro0128/PBRT_bathroom_renderer&quot; data-og-description=&quot;Contribute to ksro0128/PBRT_bathroom_renderer development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ksro0128/PBRT_bathroom_renderer&quot; data-og-url=&quot;https://github.com/ksro0128/PBRT_bathroom_renderer&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/swFAr/hyZzKhJ8mV/uGJiBIUrHWeKka9J3aj6c0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/CTuLD/hyZuF3J4gj/3Jg8JwsVpQQoCkJDBGy1ik/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/ksro0128/PBRT_bathroom_renderer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ksro0128/PBRT_bathroom_renderer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/swFAr/hyZzKhJ8mV/uGJiBIUrHWeKka9J3aj6c0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/CTuLD/hyZuF3J4gj/3Jg8JwsVpQQoCkJDBGy1ik/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - ksro0128/PBRT_bathroom_renderer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to ksro0128/PBRT_bathroom_renderer development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지는 .pbrt 파일만 지원하는 렌더러 였는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 .gltf를 지원하는 패스트레이싱 렌더러를 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재질별 계산식을 통합식으로 수정했고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투과는 하고있는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gltf 특성상 투과를 얇은 재질, 두꺼운 재질 2가지를 지원하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 통합적으로 생각하다가 지금은 흐지부지 되었었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단은 빼고 ui만 수정해서 마무리짓고 정리해서 글 올려야겠다.&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/158</guid>
      <comments>https://surkim.tistory.com/158#entry158comment</comments>
      <pubDate>Tue, 12 Aug 2025 16:35:01 +0900</pubDate>
    </item>
    <item>
      <title>pt - 12. taa 적용</title>
      <link>https://surkim.tistory.com/154</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;taa 약적용.PNG&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SMzBg/btsN1ghgfYK/FuG5KGqVYiWKpCXbOuB5k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SMzBg/btsN1ghgfYK/FuG5KGqVYiWKpCXbOuB5k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SMzBg/btsN1ghgfYK/FuG5KGqVYiWKpCXbOuB5k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSMzBg%2FbtsN1ghgfYK%2FFuG5KGqVYiWKpCXbOuB5k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;329&quot; data-filename=&quot;taa 약적용.PNG&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;208&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Path &lt;/span&gt;&lt;span&gt;Tracing &lt;/span&gt;&lt;span&gt;파이프라인에서 &lt;/span&gt;&lt;span&gt;서브픽셀 &lt;/span&gt;&lt;span&gt;단위로 &lt;/span&gt;&lt;span&gt;지터링된 &lt;/span&gt;&lt;span&gt;primary &lt;/span&gt;&lt;span&gt;ray&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;생성하여 &lt;/span&gt;&lt;span&gt;샘플을 &lt;/span&gt;&lt;span&gt;수집하고&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;208&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이를 &lt;/span&gt;&lt;span&gt;프레임마다 &lt;/span&gt;&lt;span&gt;누적하는 &lt;/span&gt;&lt;span&gt;방식으로 &lt;/span&gt;&lt;span&gt;TAA&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;적용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;208&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;349&quot; data-start=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;레스터라이제이션을 &lt;/span&gt;&lt;span&gt;활용한 g&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span&gt;생성 &lt;/span&gt;&lt;span&gt;방식을 &lt;/span&gt;&lt;span&gt;고려해보았지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;349&quot; data-start=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;primary &lt;/span&gt;&lt;span&gt;ray &lt;/span&gt;&lt;span&gt;생성 &lt;/span&gt;&lt;span&gt;로직 &lt;/span&gt;&lt;span&gt;자체를 &lt;/span&gt;&lt;span&gt;변경하지 &lt;/span&gt;&lt;span&gt;않는 &lt;/span&gt;&lt;span&gt;이상 &lt;/span&gt;&lt;span&gt;구조적으로 &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;349&quot; data-start=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오히려 &lt;/span&gt;&lt;span&gt;성능 &lt;/span&gt;&lt;span&gt;저하 &lt;/span&gt;&lt;span&gt;요인이 &lt;/span&gt;&lt;span&gt;된다고 &lt;/span&gt;&lt;span&gt;판단하여 &lt;/span&gt;&lt;span&gt;해당 &lt;/span&gt;&lt;span&gt;방식은 일단 &lt;/span&gt;&lt;span&gt;폐기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/154</guid>
      <comments>https://surkim.tistory.com/154#entry154comment</comments>
      <pubDate>Mon, 19 May 2025 10:15:44 +0900</pubDate>
    </item>
    <item>
      <title>pt - 11. svgf 로직 수정 (샘플 수 적을 때)</title>
      <link>https://surkim.tistory.com/153</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;spp가 적을때 로직을 수정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필터 적용시 픽셀의 분산 샘플이 적으면 루미넌스를 제외한 depth, normal 인자로 7x7 bilateral 필터를 적용해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;atorus 1step만 적용했었는데 1step이 아니라 5step 전부 7x7 bilateral 필터로 적용해야 했었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ssss.png&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;769&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Peq8I/btsNZYMVIwI/RgZZBVaclTDfiNxnv7k3C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Peq8I/btsNZYMVIwI/RgZZBVaclTDfiNxnv7k3C0/img.png&quot; data-alt=&quot;고치기 전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Peq8I/btsNZYMVIwI/RgZZBVaclTDfiNxnv7k3C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPeq8I%2FbtsNZYMVIwI%2FRgZZBVaclTDfiNxnv7k3C0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;321&quot; data-filename=&quot;ssss.png&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;769&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;고치기 전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        </description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/153</guid>
      <comments>https://surkim.tistory.com/153#entry153comment</comments>
      <pubDate>Fri, 16 May 2025 10:13:13 +0900</pubDate>
    </item>
    <item>
      <title>pt - 10. NEE 계산 수정, svgf 디모듈레이션 수정, 필터에서 거울만 수정</title>
      <link>https://surkim.tistory.com/152</link>
      <description>&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;106&quot; data-end=&quot;266&quot;&gt;&lt;span&gt;Path&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Tracing&lt;/span&gt;&lt;span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Next&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Event&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Estimation (&lt;/span&gt;&lt;span&gt;NEE)&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;도입하면&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;106&quot; data-end=&quot;266&quot;&gt;&lt;span&gt;직접광&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;샘플링과&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;BRDF&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;샘플링이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;동시에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;조명을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;설명하게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;되므로&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;106&quot; data-end=&quot;266&quot;&gt;&lt;span&gt;Multiple&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Importance&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Sampling (&lt;/span&gt;&lt;span&gt;MIS)&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;두&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;샘플링&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;방식의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;중복&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;기여를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;보정해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;106&quot; data-end=&quot;266&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;268&quot; data-end=&quot;396&quot;&gt;&lt;span&gt;NEE&lt;/span&gt;&lt;span&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;적용한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;이후&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;직접광&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;샘플에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;대해서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;MIS weight&lt;span&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;올바르게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;적용했지만&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;268&quot; data-end=&quot;396&quot;&gt;&lt;span&gt;간접광 (&lt;/span&gt;&lt;span&gt;BRDF&lt;/span&gt;&lt;span&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;따라간&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;bounce)&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;대해서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;MIS weight&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;계산이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;누락&lt;/span&gt;&lt;span&gt;된&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;것을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;확인했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;268&quot; data-end=&quot;396&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;268&quot; data-end=&quot;396&quot;&gt;&lt;span&gt;때문에 NEE를 추가했을때 MIS 보정이 들어가지 않아서 과하게 밝아지는 문제가 발생했던 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과적으로 간접광만 누적한것과&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;NEE를 추가해서 누적한 이미지는 같아야하는데 (수렴속도만 차이나야하는데)&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;NEE를 추가하면서 과하게 밝아진 부분을 해결했다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 밝아지는 게 맞다고 생각했어서 이 문제를 자각하지 못했다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-start=&quot;268&quot; data-end=&quot;396&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;250508 noNEE + anti + no bloom + SPP 4096.PNG&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dabRhH/btsNXDbJLlF/pufFwsTJKe94VqZIAKZgw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dabRhH/btsNXDbJLlF/pufFwsTJKe94VqZIAKZgw0/img.png&quot; data-alt=&quot;NEE 적용 전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dabRhH/btsNXDbJLlF/pufFwsTJKe94VqZIAKZgw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdabRhH%2FbtsNXDbJLlF%2FpufFwsTJKe94VqZIAKZgw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;330&quot; data-filename=&quot;250508 noNEE + anti + no bloom + SPP 4096.PNG&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NEE 적용 전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 4096.PNG&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE9nCM/btsNXEhpIoO/ojIluaNRV4NhQAlfOK7hBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE9nCM/btsNXEhpIoO/ojIluaNRV4NhQAlfOK7hBk/img.png&quot; data-alt=&quot;NEE를 적용했지만 간접광에는 mis적용이 안된 이전 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE9nCM/btsNXEhpIoO/ojIluaNRV4NhQAlfOK7hBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE9nCM%2FbtsNXEhpIoO%2FojIluaNRV4NhQAlfOK7hBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;330&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 4096.PNG&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NEE를 적용했지만 간접광에는 mis적용이 안된 이전 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nee와 간접광 mis 적용 제대로된 4096.PNG&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;793&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0pR4P/btsNYnTCmFJ/wbShIb6WsDKSWgnrb3H5A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0pR4P/btsNYnTCmFJ/wbShIb6WsDKSWgnrb3H5A0/img.png&quot; data-alt=&quot;전부 적용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0pR4P/btsNYnTCmFJ/wbShIb6WsDKSWgnrb3H5A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0pR4P%2FbtsNYnTCmFJ%2FwbShIb6WsDKSWgnrb3H5A0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;330&quot; data-filename=&quot;nee와 간접광 mis 적용 제대로된 4096.PNG&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;793&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;전부 적용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZu03W/btsNWt11Pcc/xTzRKKcViWYrro301DMpnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZu03W/btsNWt11Pcc/xTzRKKcViWYrro301DMpnk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;792&quot; data-filename=&quot;250508 noNee + anti + no bloom + SPP 1.PNG&quot; style=&quot;width: 32.6129%; margin-right: 10px;&quot; data-widthpercent=&quot;33.39&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZu03W/btsNWt11Pcc/xTzRKKcViWYrro301DMpnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZu03W%2FbtsNWt11Pcc%2FxTzRKKcViWYrro301DMpnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dS2yTA/btsNYuSMiYS/5B3pF19pSFAaurkZYgLAt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dS2yTA/btsNYuSMiYS/5B3pF19pSFAaurkZYgLAt1/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;795&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 1.PNG&quot; style=&quot;width: 32.4898%; margin-right: 10px;&quot; data-widthpercent=&quot;33.26&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dS2yTA/btsNYuSMiYS/5B3pF19pSFAaurkZYgLAt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdS2yTA%2FbtsNYuSMiYS%2F5B3pF19pSFAaurkZYgLAt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBiYlq/btsNXnNJAGU/TODQshlSVZG4xBftXELXnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBiYlq/btsNXnNJAGU/TODQshlSVZG4xBftXELXnK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;793&quot; data-filename=&quot;nee와 간접광 mis 적용 제대로된 1.PNG&quot; width=&quot;500&quot; height=&quot;330&quot; style=&quot;width: 32.5717%;&quot; data-widthpercent=&quot;33.35&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBiYlq/btsNXnNJAGU/TODQshlSVZG4xBftXELXnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBiYlq%2FbtsNXnNJAGU%2FTODQshlSVZG4xBftXELXnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;793&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;1: nee 적용전, 2: 잘못된 적용, 3: 제대로 적용 (1spp)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/myIK9/btsNXX13FA1/a0wS4ZEPuJaASycfCaJ2F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/myIK9/btsNXX13FA1/a0wS4ZEPuJaASycfCaJ2F1/img.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;795&quot; data-is-animation=&quot;false&quot; data-filename=&quot;asdf.PNG&quot; style=&quot;width: 48.368%; margin-right: 10px;&quot; data-widthpercent=&quot;48.94&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/myIK9/btsNXX13FA1/a0wS4ZEPuJaASycfCaJ2F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmyIK9%2FbtsNXX13FA1%2Fa0wS4ZEPuJaASycfCaJ2F1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFW9jN/btsNW57i7PN/gFVE0HEd7Yv38qeSbVj8r0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFW9jN/btsNW57i7PN/gFVE0HEd7Yv38qeSbVj8r0/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;760&quot; data-filename=&quot;bathroom.jpg&quot; style=&quot;width: 50.4693%;&quot; data-widthpercent=&quot;51.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFW9jN/btsNW57i7PN/gFVE0HEd7Yv38qeSbVj8r0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFW9jN%2FbtsNW57i7PN%2FgFVE0HEd7Yv38qeSbVj8r0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: 샘플 수 많이 늘렸을 때, 오른쪽: 레퍼런스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;svgf 디모듈레이션 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접광, 간접광을 따로 샘플링하고&amp;nbsp;정확하게 알베도의 영향을 디모듈레이션 해줘야하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간접광 (brdf 따라간 bounce)샘플링은 재질 특성에 따라 확률적으로 디퓨즈, 스펙큘러중 하나를 선택해 적용하기 때문에 알베도를 제거하기가 쉬웠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접광은 샘플링할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디퓨즈, 스펙큘러 혼합재질일 경우 한 샘플링 광원에 대해 각각 계산한 후 합해서 사용했었기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알베도를 정확하게 제거하기가 어려웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 간접광 계산할 때 처럼 재질 특성에 따라 확률적으로 디퓨즈, 스펙큘러를 하나 선택해 적용하는 것으로 바꿨고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디퓨즈일 때만 알베도를 디모듈 해주는 방식으로 바꿨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이렇게 해도 NEE 샘플링자체가 간접광의 패스를 따라서 샘플링이 진행되기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번째 바운스 이후부터는 직접광 누적에 간접광의 throughput이 들어가는 구조라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알베도의 영향을 전부 제거하지는 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 영향도가 매우 낮아 이상한 색이 나오진 않는 거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 모듈레이션도 지금 그냥 알베도를 곱하는 형식으로 하고있는데 이러면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필터링된 디퓨즈 + 스펙큘러 영향에 그냥 albedo를 곱하는 형식이라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확한 계산이 아닌거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확하게 하려면 직접광의 디퓨즈 스펙큘러, 간접광의 디퓨즈 스펙큘러&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;싹 다 나눠서 디모듈 -&amp;gt; 필터링 -&amp;gt; 모듈레이션 해야 정확할 거 같은데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 논문에 제시한 방법도 아니거니와&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필터링 자체가 무거운데 그걸 두번 더 해야하는 거라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고민이 필요한거 같다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cztnJb/btsNYCiIIvx/yLQ7bKWWyyzLEI4JPzf7m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cztnJb/btsNYCiIIvx/yLQ7bKWWyyzLEI4JPzf7m1/img.png&quot; data-alt=&quot;고치기 전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cztnJb/btsNYCiIIvx/yLQ7bKWWyyzLEI4JPzf7m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcztnJb%2FbtsNYCiIIvx%2FyLQ7bKWWyyzLEI4JPzf7m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;329&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;고치기 전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;일단은 푸른빛 돌던게 사라졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼합재질에서 스펙큘러 부분이 거의 사라져버렸는데 이게 지금 잘 적용이 되서 이런건지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 계산부분에서 누락된 부분이 있는건지 확인해봐야 할것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거울 재질 조정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;씬의 4분의 1이 거울인데 흐릿하게 나와 안이쁜 것 같아서 이 부분만 조금 조정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 흐릿하게 나오는 이유가 필터링 거칠 때 사용하는 인자들이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 표면의 법선벡터, 2. 뎁스, 3. 루미넌스 값인데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거울 재질에서 보이는 부분은 법선벡터와 뎁스차이가 거의 없으니깐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강한 필터링을 거치게 되어 생긴 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거울일 때만 gbuffer를 튕겨 보이는 부분의 정보로 바꿔서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선명하게 보이도록 바꿨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가까이 가면 전프레임에 있는 부분이었지만 갱신되는 부분은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일치도 검사할 때 depth차이에 대한 부분을 너무 강하게 잡아서 생긴 문제였고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약간 느슨하게 바꿔줘서 해결했다.&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/152</guid>
      <comments>https://surkim.tistory.com/152#entry152comment</comments>
      <pubDate>Thu, 15 May 2025 10:38:13 +0900</pubDate>
    </item>
    <item>
      <title>pt - 9. 푸른 빛 원인 찾음</title>
      <link>https://surkim.tistory.com/150</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;250513.PNG&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eklfc8/btsNWqv33nU/i2Wwz3Uv9IJ2OwZbTHZjt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eklfc8/btsNWqv33nU/i2Wwz3Uv9IJ2OwZbTHZjt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eklfc8/btsNWqv33nU/i2Wwz3Uv9IJ2OwZbTHZjt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feklfc8%2FbtsNWqv33nU%2Fi2Wwz3Uv9IJ2OwZbTHZjt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;329&quot; data-filename=&quot;250513.PNG&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;직접광 / 간접광을 분리하여 샘플링하고 디모듈레이션 하는 과정에서 &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;잘못된 방법을 사용하여 푸른빛이 도는 결과가 나온 것이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;간접광 계산할 때 디퓨즈와 스페큘러 샘플링을 확률적으로 선택하여 진행되는데 &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 중 디퓨즈 샘플링일때만 albedo 영향을 받기 때문에 일괄적으로 albedo를 나누면 안되고 &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제 albedo영향을 받는 픽셀만 선택하여 디모듈레이션 해줘야했다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;250514 아침보고용.PNG&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duopW5/btsNW0wVZLt/KQmH1jmSvVmt8ixiJx2FB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duopW5/btsNW0wVZLt/KQmH1jmSvVmt8ixiJx2FB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duopW5/btsNW0wVZLt/KQmH1jmSvVmt8ixiJx2FB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduopW5%2FbtsNW0wVZLt%2FKQmH1jmSvVmt8ixiJx2FB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;331&quot; data-filename=&quot;250514 아침보고용.PNG&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이미지는 정확한 결과 이미지는 아니고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간접광에서는 정확하게 albedo영향을 계산해서 빼줬는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접광 영향은 아직 정확하게 계산을 못해서 직접광은 잠시 albedo 성분을 vec3(1.0)으로 없애고 실험해보았다.&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/150</guid>
      <comments>https://surkim.tistory.com/150#entry150comment</comments>
      <pubDate>Wed, 14 May 2025 10:41:14 +0900</pubDate>
    </item>
    <item>
      <title>pt - 8. 전반적인 정리 (NEE 개념, svgf 개념), 현재 문제점들</title>
      <link>https://surkim.tistory.com/147</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;레퍼런스&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bathroom.jpg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cthp16/btsNVAY8Hrs/kPZyGkX05S82BYzeKR126k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cthp16/btsNVAY8Hrs/kPZyGkX05S82BYzeKR126k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cthp16/btsNVAY8Hrs/kPZyGkX05S82BYzeKR126k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcthp16%2FbtsNVAY8Hrs%2FkPZyGkX05S82BYzeKR126k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;317&quot; data-filename=&quot;bathroom.jpg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복습&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq5LEV/btsNTkxcUBt/frg3mXW9XsvyQvkDZKRilk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq5LEV/btsNTkxcUBt/frg3mXW9XsvyQvkDZKRilk/img.png&quot; data-alt=&quot;렌더링 방정식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq5LEV/btsNTkxcUBt/frg3mXW9XsvyQvkDZKRilk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq5LEV%2FbtsNTkxcUBt%2Ffrg3mXW9XsvyQvkDZKRilk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;536&quot; height=&quot;73&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;렌더링 방정식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 렌더링은 이 렌더링 방정식을 푸는 것으로 시작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;렌더링 방정식은 순환 적분식 구조이므로 직접푸는 것은 불가능&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l4mXR/btsNTkRwlQN/7zJX8TIOxabQXXP8i76AyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l4mXR/btsNTkRwlQN/7zJX8TIOxabQXXP8i76AyK/img.png&quot; data-alt=&quot;렌더링 방정식 몬테카를로 근사&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l4mXR/btsNTkRwlQN/7zJX8TIOxabQXXP8i76AyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl4mXR%2FbtsNTkRwlQN%2F7zJX8TIOxabQXXP8i76AyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;88&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;렌더링 방정식 몬테카를로 근사&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 몬테카를로와 같은 근사식으로 렌더링 방정식을 근사&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTWD8a/btsNUUYgCSY/O6t4JfUKtzmNFLEYKdGjv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTWD8a/btsNUUYgCSY/O6t4JfUKtzmNFLEYKdGjv1/img.png&quot; data-alt=&quot;path tracing 진행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTWD8a/btsNUUYgCSY/O6t4JfUKtzmNFLEYKdGjv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTWD8a%2FbtsNUUYgCSY%2FO6t4JfUKtzmNFLEYKdGjv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;817&quot; height=&quot;293&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;path tracing 진행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;path tracing은 경로 하나만 샘플링하여 그 경로하나가 전체 적분 값을 대표하도록 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;169&quot; data-start=&quot;154&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;169&quot; data-start=&quot;154&quot; data-ke-size=&quot;size18&quot;&gt;기존 구현 방식&lt;/p&gt;
&lt;p data-end=&quot;169&quot; data-start=&quot;154&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;311&quot; data-start=&quot;171&quot; data-ke-size=&quot;size16&quot;&gt;초기에는 BRDF 중요도 기반 샘플링을 통해 path tracing을 구성&lt;br /&gt;BRDF로 샘플링한 방향이 우연히 광원에 도달하면&lt;br /&gt;그때만 throughput &amp;times; radiance를 계산하는 방식&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;383&quot; data-start=&quot;318&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;345&quot; data-start=&quot;318&quot;&gt;BRDF 샘플링 &amp;rarr; 경로 따라 ray를 쏨&lt;/li&gt;
&lt;li data-end=&quot;367&quot; data-start=&quot;346&quot;&gt;광원에 닿을 때까지 bounce&lt;/li&gt;
&lt;li data-end=&quot;383&quot; data-start=&quot;368&quot;&gt;맞으면 그때만 기여 누적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;394&quot; data-start=&quot;385&quot; data-ke-size=&quot;size18&quot;&gt;문제점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;530&quot; data-start=&quot;418&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;454&quot; data-start=&quot;418&quot;&gt;1 SPP에서 광원에 도달하지 못하면 그 샘플이 버려짐&lt;/li&gt;
&lt;li data-end=&quot;479&quot; data-start=&quot;455&quot;&gt;노이즈가 심하고 수렴이 느림&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;NEE (Next Event Estimation) 추가&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s3Qiv/btsNUueLGi6/nIym1pOWwJ2ujJztUFxwOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s3Qiv/btsNUueLGi6/nIym1pOWwJ2ujJztUFxwOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s3Qiv/btsNUueLGi6/nIym1pOWwJ2ujJztUFxwOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs3Qiv%2FbtsNUueLGi6%2FnIym1pOWwJ2ujJztUFxwOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;863&quot; height=&quot;300&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;673&quot; data-start=&quot;588&quot; data-ke-size=&quot;size16&quot;&gt;NEE는 ray가 광원에 맞을 때를 기다리지 않고&lt;br /&gt;맞은 지점에서 직접광을 샘플링하여 즉시 조명 기여를 평가하는 방식&lt;/p&gt;
&lt;p data-end=&quot;673&quot; data-start=&quot;588&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;685&quot; data-start=&quot;675&quot; data-ke-size=&quot;size16&quot;&gt;기대 효과&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;748&quot; data-start=&quot;686&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;723&quot; data-start=&quot;686&quot;&gt;1 SPP에서도 광원이 보이는 위치라면 직접광 기여를 누적 가능&lt;/li&gt;
&lt;li data-end=&quot;748&quot; data-start=&quot;724&quot;&gt;따라서 노이즈가 줄고 수렴이 훨씬 빨라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;790&quot; data-start=&quot;769&quot; data-ke-size=&quot;size16&quot;&gt;NEE는 다음과 같은 순서로 수행&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;987&quot; data-start=&quot;792&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;831&quot; data-start=&quot;792&quot;&gt;현재 위치에서 scene 내 광원 중 하나를 무작위로 선택 (광원에 모양이 있어 삼각형으로 전부 쪼개서 저장) 즉 광원 삼각형을 선택&lt;/li&gt;
&lt;li data-end=&quot;876&quot; data-start=&quot;832&quot;&gt;선택한 광원의 면적 중 한 점을 sampling&lt;/li&gt;
&lt;li data-end=&quot;911&quot; data-start=&quot;877&quot;&gt;해당 위치를 향해 shadow ray를 하나 발사&lt;/li&gt;
&lt;li data-end=&quot;952&quot; data-start=&quot;912&quot;&gt;그 경로가 가려지지 않았다면 &amp;rarr; BRDF를 통해 기여량 계산&lt;/li&gt;
&lt;li data-end=&quot;987&quot; data-start=&quot;953&quot;&gt;계산된 조명 기여를 현재 throughput에 곱해 누적&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0xSvV/btsNTaVyEW9/k95qmjgGRRe2FOOAck2te0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0xSvV/btsNTaVyEW9/k95qmjgGRRe2FOOAck2te0/img.png&quot; data-alt=&quot;직접광 계산&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0xSvV/btsNTaVyEW9/k95qmjgGRRe2FOOAck2te0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0xSvV%2FbtsNTaVyEW9%2Fk95qmjgGRRe2FOOAck2te0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;280&quot; height=&quot;56&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;직접광 계산&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pdf 계산&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;167&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWu3GJ/btsNTCqR5pX/BsQoJ9oz3m5ag5pAMQz4m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWu3GJ/btsNTCqR5pX/BsQoJ9oz3m5ag5pAMQz4m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWu3GJ/btsNTCqR5pX/BsQoJ9oz3m5ag5pAMQz4m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWu3GJ%2FbtsNTCqR5pX%2FBsQoJ9oz3m5ag5pAMQz4m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;167&quot; height=&quot;52&quot; data-origin-width=&quot;167&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광원중 하나 x 면적&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HPv8R/btsNUrWE8nV/HoRcZfZBjI5ZmlcqPDVbBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HPv8R/btsNUrWE8nV/HoRcZfZBjI5ZmlcqPDVbBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HPv8R/btsNUrWE8nV/HoRcZfZBjI5ZmlcqPDVbBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHPv8R%2FbtsNUrWE8nV%2FHoRcZfZBjI5ZmlcqPDVbBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;260&quot; height=&quot;68&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후에 나올 brdf의 계산은 입체각 기준이기 때문에 입체각 기준으로 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;252&quot; data-origin-height=&quot;69&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nFMms/btsNVbevLv8/w7B5lBtlWrIVrM30LCdIrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nFMms/btsNVbevLv8/w7B5lBtlWrIVrM30LCdIrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nFMms/btsNVbevLv8/w7B5lBtlWrIVrM30LCdIrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnFMms%2FbtsNVbevLv8%2Fw7B5lBtlWrIVrM30LCdIrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;252&quot; height=&quot;69&quot; data-origin-width=&quot;252&quot; data-origin-height=&quot;69&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;403&quot; data-end=&quot;458&quot;&gt;cos x 레이를 쏘려는 지점에서 법선 방향과 레이의 내적&lt;/li&gt;
&lt;li data-start=&quot;459&quot; data-end=&quot;514&quot;&gt;cos y 광원 지점에서의 법선 방향과 레이의 내적&lt;/li&gt;
&lt;li data-start=&quot;459&quot; data-end=&quot;514&quot;&gt;pdf: light sampling 시 해당 방향으로 샘플될 확률&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의점&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;884&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9JZHf/btsNUQO64It/bVmNOkKk4p2dgnCq9Zd7lK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9JZHf/btsNUQO64It/bVmNOkKk4p2dgnCq9Zd7lK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9JZHf/btsNUQO64It/bVmNOkKk4p2dgnCq9Zd7lK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9JZHf%2FbtsNUQO64It%2FbVmNOkKk4p2dgnCq9Zd7lK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;884&quot; height=&quot;296&quot; data-origin-width=&quot;884&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 조명 기여가 두 경로에서 중복 계산 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과가 편향될 수 있음 -&amp;gt; 노이즈 증가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 MIS(Multiple Importance Sampling) 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MIS란? 여러 샘플링 전략이 동일한 기여를 만들 수 있을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복 없이, 편향 없이 합산하기위한 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Balance Heuristic&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;179&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PGdfl/btsNVk953ob/9k5x4uqTFVpN0UqjWkb8nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PGdfl/btsNVk953ob/9k5x4uqTFVpN0UqjWkb8nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PGdfl/btsNVk953ob/9k5x4uqTFVpN0UqjWkb8nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPGdfl%2FbtsNVk953ob%2F9k5x4uqTFVpN0UqjWkb8nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;179&quot; height=&quot;49&quot; data-origin-width=&quot;179&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플링한 레이를 brdf 기준으로 계산한 pdf와 balance heuristic&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 최종 NEE기여는&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgHBZw/btsNVgtcHEJ/0Qt2KDLwxv8ZOaKG4BPANK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgHBZw/btsNVgtcHEJ/0Qt2KDLwxv8ZOaKG4BPANK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgHBZw/btsNVgtcHEJ/0Qt2KDLwxv8ZOaKG4BPANK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgHBZw%2FbtsNVgtcHEJ%2F0Qt2KDLwxv8ZOaKG4BPANK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;290&quot; height=&quot;63&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NEE추가해서 나온 이미지&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM9wMr/btsNUvSkg4H/6PFWJ83NpkmHfouxfLCkek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM9wMr/btsNUvSkg4H/6PFWJ83NpkmHfouxfLCkek/img.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;794&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.3358%; margin-right: 10px;&quot; data-widthpercent=&quot;49.92&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM9wMr/btsNUvSkg4H/6PFWJ83NpkmHfouxfLCkek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM9wMr%2FbtsNUvSkg4H%2F6PFWJ83NpkmHfouxfLCkek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd22nx/btsNTHlaASZ/3iDwBYZfp5IJGIMnjOIJRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd22nx/btsNTHlaASZ/3iDwBYZfp5IJGIMnjOIJRK/img.png&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;792&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.5015%;&quot; data-widthpercent=&quot;50.08&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd22nx/btsNTHlaASZ/3iDwBYZfp5IJGIMnjOIJRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd22nx%2FbtsNTHlaASZ%2F3iDwBYZfp5IJGIMnjOIJRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1204&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: 추가 전, 오른쪽: 추가 후 spp 4096&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EvL5S/btsNUzNE0aq/GbGBXNRkmtiIYZxdFaKvp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EvL5S/btsNUzNE0aq/GbGBXNRkmtiIYZxdFaKvp1/img.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;792&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.512%; margin-right: 10px;&quot; data-widthpercent=&quot;50.09&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EvL5S/btsNUzNE0aq/GbGBXNRkmtiIYZxdFaKvp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEvL5S%2FbtsNUzNE0aq%2FGbGBXNRkmtiIYZxdFaKvp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NXVHo/btsNTGsY1pU/HXatZtjSSs9dB2ryT8Mug0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NXVHo/btsNTGsY1pU/HXatZtjSSs9dB2ryT8Mug0/img.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;795&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.3252%;&quot; data-widthpercent=&quot;49.91&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NXVHo/btsNTGsY1pU/HXatZtjSSs9dB2ryT8Mug0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNXVHo%2FbtsNTGsY1pU%2FHXatZtjSSs9dB2ryT8Mug0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: 추가 전, 오른쪽: 추가 후 spp 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;svgf 도입 중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 path tracing 결과를 기반으로 실시간 렌더링을 노려보고자 SVGF를 도입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문을 열심히 읽고 구현하긴 했는데 자의적으로 해석한 부분이 있을 수도 있음,,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현 목표&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 낮은 샘플 수에서 빠르게 수렴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 카메라 이동이나 씬 변화에도 노이즈가 안정적으로 억제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 전체적인 개요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rFtb5/btsNS7j7KMh/vmoa12Tw0gCka6lAlhh2G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rFtb5/btsNS7j7KMh/vmoa12Tw0gCka6lAlhh2G0/img.png&quot; data-alt=&quot;전체 개요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rFtb5/btsNS7j7KMh/vmoa12Tw0gCka6lAlhh2G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrFtb5%2FbtsNS7j7KMh%2Fvmoa12Tw0gCka6lAlhh2G0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;824&quot; height=&quot;225&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;전체 개요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;204&quot; data-start=&quot;126&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;204&quot; data-start=&quot;126&quot; data-ke-size=&quot;size16&quot;&gt;path tracing 결과는 직접광과 간접광으로 나눠서 처리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;338&quot; data-start=&quot;218&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;271&quot; data-start=&quot;218&quot;&gt;직접광은 NEE를 통해 직접 샘플되기 때문에 신뢰도가 높고, variance가 낮음&lt;/li&gt;
&lt;li data-end=&quot;338&quot; data-start=&quot;272&quot;&gt;간접광은 bounce를 여러 번 거쳐 얻어진 결과이므로 variance가 높고, 노이즈도 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;376&quot; data-start=&quot;340&quot; data-ke-size=&quot;size16&quot;&gt;따라서 두 성분을 같은 필터 강도로 처리하면 비효율적이기 때문에 나눠서 처리&lt;/p&gt;
&lt;p data-end=&quot;376&quot; data-start=&quot;340&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;553&quot; data-start=&quot;498&quot; data-ke-size=&quot;size16&quot;&gt;필터링을 하기 전, 먼저 radiance를 albedo로 나눈다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;745&quot; data-start=&quot;567&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;608&quot; data-start=&quot;567&quot;&gt;radiance에는 texture 색 정보가 곱해져 있는데 이 상태로 필터링하면 텍스처 디테일까지 뭉개짐&lt;/li&gt;
&lt;li data-end=&quot;695&quot; data-start=&quot;651&quot;&gt;따라서 필터링 전에는 albedo를 제거해서 색 정보를 분리 -&amp;gt; 필터링 후에는 다시 albedo를 곱해서 원래 색을 복원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;792&quot; data-start=&quot;747&quot; data-ke-size=&quot;size16&quot;&gt;이 과정을 통해 노이즈는 줄이되 텍스처 디테일은 유지할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에 직접광 간접광 각각 필터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 필터링한 두 이미지를 합치고 다시 albedo를 곱해서 원래 색을 복원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 뒤 톤 매핑과 안티엘리어싱&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1r9na/btsNUSssG8Y/42o4qbFOOKUpudx6ykRUB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1r9na/btsNUSssG8Y/42o4qbFOOKUpudx6ykRUB0/img.png&quot; data-alt=&quot;필터링&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1r9na/btsNUSssG8Y/42o4qbFOOKUpudx6ykRUB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1r9na%2FbtsNUSssG8Y%2F42o4qbFOOKUpudx6ykRUB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;202&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;필터링&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Temporal Accumulation&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 1 spp path tracing 결과를 프레임 간 누적&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;381&quot; data-start=&quot;352&quot;&gt;이때 단순히 과거 프레임 색을 복사하지 않고,&lt;/li&gt;
&lt;li data-end=&quot;476&quot; data-start=&quot;382&quot;&gt;Motion Vector, Normal, Depth, Mesh ID를 이용해 이전 프레임 값이 현재 픽셀과 같은 지점에서 온 값인지 판단&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;495&quot; data-start=&quot;478&quot; data-ke-size=&quot;size16&quot;&gt;일치도 판단 방식&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;676&quot; data-start=&quot;497&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;539&quot; data-start=&quot;497&quot;&gt;재투영된 위치를 기준으로 2&amp;times;2 주변 픽셀을 bilinear 보간&lt;/li&gt;
&lt;li data-end=&quot;578&quot; data-start=&quot;540&quot;&gt;각 픽셀의 Normal, Depth, Mesh ID를 비교&lt;/li&gt;
&lt;li data-end=&quot;612&quot; data-start=&quot;579&quot;&gt;4개 중 하나라도 일치하면 &amp;rarr; 가중 평균으로 누적&lt;/li&gt;
&lt;li data-end=&quot;646&quot; data-start=&quot;613&quot;&gt;4개 모두 일치 안 하면 &amp;rarr; 3&amp;times;3으로 범위 확장&lt;/li&gt;
&lt;li data-end=&quot;676&quot; data-start=&quot;647&quot;&gt;그래도 없으면 &amp;rarr; 재시작 (이전 값 무시)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누적 방식: EMA (Exponential Moving Average)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;33&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjkCnk/btsNUGsfBEp/tRx5IcTxUtIrmui95mHRNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjkCnk/btsNUGsfBEp/tRx5IcTxUtIrmui95mHRNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjkCnk/btsNUGsfBEp/tRx5IcTxUtIrmui95mHRNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjkCnk%2FbtsNUGsfBEp%2FtRx5IcTxUtIrmui95mHRNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;238&quot; height=&quot;33&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;33&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;alpha;&lt;/span&gt;&lt;/span&gt;: blending weight&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ci-1: history color 이미지 (필터의 1step 결과물)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 오래된 샘플은 점점 희석되지만 빠르게 수렴하기 때문에 실시간 렌더링에 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 이제 많이 누적된다고 화면 개선이 되진 않는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 분산 추정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;단계에서는 &lt;/span&gt;&lt;span&gt;누적된 &lt;/span&gt;&lt;span&gt;샘플들의 &lt;/span&gt;&lt;span&gt;시간 &lt;/span&gt;&lt;span&gt;변화량을 &lt;/span&gt;&lt;span&gt;분석하여, &lt;/span&gt;&lt;span&gt;해당 &lt;/span&gt;&lt;span&gt;픽셀에 &lt;/span&gt;&lt;span&gt;노이즈가 &lt;/span&gt;&lt;span&gt;얼마나 &lt;/span&gt;&lt;span&gt;있는지를 &lt;/span&gt;&lt;span&gt;판단&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;325&quot; data-start=&quot;270&quot;&gt;&lt;span&gt;분산이 &lt;/span&gt;&lt;span&gt;크다&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;샘플들이 &lt;/span&gt;&lt;span&gt;시간에 &lt;/span&gt;&lt;span&gt;따라 &lt;/span&gt;&lt;span&gt;많이 &lt;/span&gt;&lt;span&gt;흔들렸다 &amp;rarr; &lt;/span&gt;&lt;span&gt;노이즈가 &lt;/span&gt;&lt;span&gt;많을 &lt;/span&gt;&lt;span&gt;가능성 &lt;/span&gt;&lt;span&gt;높음&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;371&quot; data-start=&quot;326&quot;&gt;&lt;span&gt;분산이 &lt;/span&gt;&lt;span&gt;작다&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;결과가 &lt;/span&gt;&lt;span&gt;시간에 &lt;/span&gt;&lt;span&gt;따라 &lt;/span&gt;&lt;span&gt;안정적이다 &amp;rarr; &lt;/span&gt;&lt;span&gt;노이즈가 &lt;/span&gt;&lt;span&gt;적음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분산을 &lt;/span&gt;&lt;span&gt;추정하기 &lt;/span&gt;&lt;span&gt;위해, &lt;/span&gt;&lt;span&gt;다음 &lt;/span&gt;&lt;span&gt;두 &lt;/span&gt;&lt;span&gt;값을 &lt;/span&gt;&lt;span&gt;시간 &lt;/span&gt;&lt;span&gt;축 &lt;/span&gt;&lt;span&gt;누적 &lt;/span&gt;&lt;span&gt;방식으로 &lt;/span&gt;&lt;span&gt;저장&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;626&quot; data-start=&quot;553&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;588&quot; data-start=&quot;553&quot;&gt;&lt;span&gt;휘도의 &lt;/span&gt;&lt;span&gt;평균 (&lt;/span&gt;&lt;span&gt;mean &lt;/span&gt;&lt;span&gt;of &lt;/span&gt;&lt;span&gt;luminance)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;626&quot; data-start=&quot;589&quot;&gt;&lt;span&gt;휘도의 &lt;/span&gt;&lt;span&gt;제곱 &lt;/span&gt;&lt;span&gt;평균 (&lt;/span&gt;&lt;span&gt;mean &lt;/span&gt;&lt;span&gt;of &lt;/span&gt;&lt;span&gt;luminance&amp;sup2;)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;653&quot; data-start=&quot;628&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;두 &lt;/span&gt;&lt;span&gt;값을 &lt;/span&gt;&lt;span&gt;가지고 &lt;/span&gt;&lt;span&gt;고전적인 &lt;/span&gt;&lt;span&gt;분산 &lt;/span&gt;&lt;span&gt;계산 &lt;/span&gt;&lt;span&gt;방식&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;50&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ACgfz/btsNTRankBC/gnbRqeT27o2v9N2ojagWS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ACgfz/btsNTRankBC/gnbRqeT27o2v9N2ojagWS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ACgfz/btsNTRankBC/gnbRqeT27o2v9N2ojagWS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FACgfz%2FbtsNTRankBC%2FgnbRqeT27o2v9N2ojagWS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;240&quot; height=&quot;50&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;50&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;710&quot; data-start=&quot;696&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;을 &lt;/span&gt;&lt;span&gt;통해 &lt;/span&gt;&lt;span&gt;분산을 구함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이전 &lt;/span&gt;&lt;span&gt;프레임에서 &lt;/span&gt;&lt;span&gt;누적해둔 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;휘도의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;평균 &lt;/span&gt;&lt;span&gt;, &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;휘도의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;제곱&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;평균&lt;/span&gt;&lt;span&gt;을 &lt;/span&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;프레임에서 &lt;/span&gt;&lt;span&gt;motion &lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;로 &lt;/span&gt;&lt;span&gt;재투영하여 &lt;/span&gt;&lt;span&gt;불러온 뒤&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;재투영 &lt;/span&gt;&lt;span&gt;유효성 &lt;/span&gt;&lt;span&gt;판별(=&lt;/span&gt;&lt;span&gt;일치도 &lt;/span&gt;&lt;span&gt;검사)&lt;/span&gt;&lt;span&gt;은 &lt;/span&gt;&lt;span&gt;Temporal &lt;/span&gt;&lt;span&gt;Accumulation&lt;/span&gt;&lt;span&gt;과 &lt;/span&gt;&lt;span&gt;동일하게 &lt;/span&gt;&lt;span&gt;수행하고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;결과를 &lt;/span&gt;&lt;span&gt;바탕으로 &lt;/span&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;픽셀의 &lt;/span&gt;&lt;span&gt;분산을 &lt;/span&gt;&lt;span&gt;계산&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 계산된 분산은 뒤에 필터에서 weight 계산하기위해 들어 간다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플수가 적을 때 (spp &amp;lt; 4)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;누적된 &lt;/span&gt;&lt;span&gt;샘플 &lt;/span&gt;&lt;span&gt;수가 &lt;/span&gt;&lt;span&gt;너무 &lt;/span&gt;&lt;span&gt;적다면 &lt;/span&gt;&lt;span&gt;분산 &lt;/span&gt;&lt;span&gt;값은 &lt;/span&gt;&lt;span&gt;신뢰할 &lt;/span&gt;&lt;span&gt;수 &lt;/span&gt;&lt;span&gt;없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우엔 분산 기반 필터를 사용하지 않고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7x7 bilateral 필터를 fallback으로 적용 (depth, normal만 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. a-torus wavelet 필터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노이즈를 제거하면서도 경계를 보존하는 필터링 기법&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;특징은 픽셀 사이를 건너뛰며 필터링 커널을 적용하는 방식을 사용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBltLo/btsNVK1Pp52/N41BhQCQHIw9IMDf0NlwX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBltLo/btsNVK1Pp52/N41BhQCQHIw9IMDf0NlwX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBltLo/btsNVK1Pp52/N41BhQCQHIw9IMDf0NlwX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBltLo%2FbtsNVK1Pp52%2FN41BhQCQHIw9IMDf0NlwX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;92&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;463&quot; data-end=&quot;495&quot;&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;스텝&lt;/span&gt;&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;이웃한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;픽셀 (&lt;/span&gt;&lt;span&gt;stride =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;1)&lt;/span&gt;&lt;/li&gt;
&lt;li data-start=&quot;496&quot; data-end=&quot;535&quot;&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;스텝&lt;/span&gt;&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;칸&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;건너뛰며&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;필터&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;적용 (&lt;/span&gt;&lt;span&gt;stride =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;2)&lt;/span&gt;&lt;/li&gt;
&lt;li data-start=&quot;536&quot; data-end=&quot;572&quot;&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;스텝&lt;/span&gt;&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;칸&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;건너뛰며&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;적용 (&lt;/span&gt;&lt;span&gt;stride =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;4)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스텝이 진행될수록 더 넓은 범위를 필터링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;A-&lt;/span&gt;&lt;span&gt;Trous&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;필터는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;픽셀&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;주변&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;이웃들과의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;유사도를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;판단해&lt;/span&gt;&lt;br /&gt;&lt;span&gt;가중&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;평균(&lt;/span&gt;&lt;span&gt;weighted&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;average)&lt;/span&gt;&lt;span&gt;을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;radiance&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;값을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;보간&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;578&quot; data-end=&quot;622&quot;&gt;&lt;span&gt;Normal&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;weight&lt;/span&gt;&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;물체&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;표면의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;방향이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;비슷할수록&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;높은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;가중치&lt;/span&gt;&lt;/li&gt;
&lt;li data-start=&quot;623&quot; data-end=&quot;661&quot;&gt;&lt;span&gt;Depth&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;weight&lt;/span&gt;&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;깊이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;차이가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;작을수록&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;높은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;가중치&lt;/span&gt;&lt;/li&gt;
&lt;li data-start=&quot;662&quot; data-end=&quot;708&quot;&gt;&lt;span&gt;Variance&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;weight&lt;/span&gt;&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;노이즈가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;적을수록&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;더&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;신뢰할&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;수&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;샘플&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;41&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFsRRF/btsNUKOZ4yl/GGnYqEuyF7VywpXgncUHJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFsRRF/btsNUKOZ4yl/GGnYqEuyF7VywpXgncUHJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFsRRF/btsNUKOZ4yl/GGnYqEuyF7VywpXgncUHJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFsRRF%2FbtsNUKOZ4yl%2FGGnYqEuyF7VywpXgncUHJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;210&quot; height=&quot;41&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;41&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;995&quot; data-start=&quot;925&quot;&gt;&lt;span&gt;&lt;span&gt;h(q)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;커널 &lt;/span&gt;&lt;span&gt;내 &lt;/span&gt;&lt;span&gt;위치 &lt;/span&gt;&lt;span&gt;&lt;span&gt;q&lt;/span&gt;&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;대한 &lt;/span&gt;&lt;span&gt;spatial &lt;/span&gt;&lt;span&gt;weight, h = {1/16, 1/4, 3/8, 1/4, 1/16}&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1056&quot; data-start=&quot;996&quot;&gt;&lt;span&gt;&lt;span&gt;w(p,q)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;normal / &lt;/span&gt;&lt;span&gt;depth / &lt;/span&gt;&lt;span&gt;variance &lt;/span&gt;&lt;span&gt;기반 &lt;/span&gt;&lt;span&gt;유사도 &lt;/span&gt;&lt;span&gt;가중치&lt;/span&gt;&lt;b&gt;&lt;span&gt;,&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;23&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wnvCf/btsNVsf2ltO/Un86uCUOj24YDIPkObTJb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wnvCf/btsNVsf2ltO/Un86uCUOj24YDIPkObTJb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wnvCf/btsNVsf2ltO/Un86uCUOj24YDIPkObTJb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwnvCf%2FbtsNVsf2ltO%2FUn86uCUOj24YDIPkObTJb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;119&quot; height=&quot;23&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;23&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1104&quot; data-start=&quot;1057&quot;&gt;&lt;span&gt;&lt;span&gt;ci(q)는 이전 스텝의 radiance 값&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;수식은 &lt;/span&gt;&lt;span&gt;주변 &lt;/span&gt;&lt;span&gt;픽셀들과의 &lt;/span&gt;&lt;span&gt;유사도(&lt;/span&gt;&lt;span&gt;weight)&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;기반으로 &lt;/span&gt;&lt;span&gt;한 &lt;/span&gt;&lt;span&gt;가중 &lt;/span&gt;&lt;span&gt;평균 &lt;/span&gt;&lt;span&gt;필터&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;A-&lt;/span&gt;&lt;span&gt;Trous &lt;/span&gt;&lt;span&gt;필터는 &lt;/span&gt;&lt;span&gt;radiance &lt;/span&gt;&lt;span&gt;값뿐 &lt;/span&gt;&lt;span&gt;아니라, &lt;/span&gt;&lt;span&gt;해당 &lt;/span&gt;&lt;span&gt;radiance&lt;/span&gt;&lt;span&gt;의 &lt;/span&gt;&lt;span&gt;신뢰도인 &lt;/span&gt;&lt;span&gt;분산(&lt;/span&gt;&lt;span&gt;variance)&lt;/span&gt;&lt;span&gt;도 &lt;/span&gt;&lt;span&gt;함께 &lt;/span&gt;&lt;span&gt;필터링&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0hQMZ/btsNVYFCijd/i8H1VK6csI8xxAHvncFp11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0hQMZ/btsNVYFCijd/i8H1VK6csI8xxAHvncFp11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0hQMZ/btsNVYFCijd/i8H1VK6csI8xxAHvncFp11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0hQMZ%2FbtsNVYFCijd%2Fi8H1VK6csI8xxAHvncFp11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;253&quot; height=&quot;45&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;필터링이 &lt;/span&gt;&lt;span&gt;반복될수록 &lt;/span&gt;&lt;span&gt;각 &lt;/span&gt;&lt;span&gt;픽셀의 &lt;/span&gt;&lt;span&gt;값은 &lt;/span&gt;&lt;span&gt;주변과 &lt;/span&gt;&lt;span&gt;섞여서 &lt;/span&gt;&lt;span&gt;바뀌기 &lt;/span&gt;&lt;span&gt;때문에,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;그에 &lt;/span&gt;&lt;span&gt;맞게 &lt;/span&gt;&lt;span&gt;분산도 &lt;/span&gt;&lt;span&gt;새로 &lt;/span&gt;&lt;span&gt;계산되어야 &lt;/span&gt;&lt;span&gt;정확한 &lt;/span&gt;&lt;span&gt;weight &lt;/span&gt;&lt;span&gt;추정이 &lt;/span&gt;&lt;span&gt;가능하기 &lt;/span&gt;&lt;span&gt;때문&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;550&quot; data-start=&quot;470&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;총 5스텝까지 적용&lt;/span&gt;&lt;br /&gt;&lt;span&gt;각 &lt;/span&gt;&lt;span&gt;스텝마다 &lt;/span&gt;&lt;span&gt;stride&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;키우면서 &lt;/span&gt;&lt;span&gt;더 &lt;/span&gt;&lt;span&gt;넓은 &lt;/span&gt;&lt;span&gt;영역까지 &lt;/span&gt;&lt;span&gt;노이즈를 &lt;/span&gt;&lt;span&gt;억제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;615&quot; data-start=&quot;552&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;580&quot; data-start=&quot;552&quot;&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;스텝: &lt;/span&gt;&lt;span&gt;가까운 &lt;/span&gt;&lt;span&gt;노이즈 &lt;/span&gt;&lt;span&gt;제거 (&lt;/span&gt;&lt;span&gt;디테일 &lt;/span&gt;&lt;span&gt;유지) -&amp;gt; history color 이미지로 저장&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;615&quot; data-start=&quot;581&quot;&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;스텝&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;넓은 &lt;/span&gt;&lt;span&gt;영역의 &lt;/span&gt;&lt;span&gt;저주파 &lt;/span&gt;&lt;span&gt;노이즈까지 &lt;/span&gt;&lt;span&gt;제거 -&amp;gt; 출력 이미지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;4. Edge-stopping functions&lt;/p&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;여기서 시그마는 보정 계수인데&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;&amp;sigma;z = 1, &amp;sigma;n = 128, &amp;sigma;l = 4,&lt;/p&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;225&quot; data-start=&quot;199&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. d&lt;/span&gt;&lt;span&gt;epth&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;34&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C993q/btsNTxb85Rq/wBftPAZ5qfk9kgHuW94yr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C993q/btsNTxb85Rq/wBftPAZ5qfk9kgHuW94yr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C993q/btsNTxb85Rq/wBftPAZ5qfk9kgHuW94yr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC993q%2FbtsNTxb85Rq%2FwBftPAZ5qfk9kgHuW94yr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;34&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;34&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;553&quot; data-start=&quot;340&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;405&quot; data-start=&quot;340&quot;&gt;&lt;span&gt; &amp;sigma;z = 1&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;405&quot; data-start=&quot;340&quot;&gt;&lt;span&gt;깊&lt;/span&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;차이가 &lt;/span&gt;&lt;span&gt;클수록 &lt;/span&gt;&lt;span&gt;weight&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;낮게 &lt;/span&gt;&lt;span&gt;설정&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;485&quot; data-start=&quot;406&quot;&gt;&lt;span&gt;분모에 &lt;/span&gt;&lt;span&gt;있는 &lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nabla;z&amp;sdot;(p&amp;minus;q)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;로컬 &lt;/span&gt;&lt;span&gt;depth &lt;/span&gt;&lt;span&gt;gradient&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;따른 &lt;/span&gt;&lt;span&gt;보정&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;485&quot; data-start=&quot;406&quot;&gt;depth 차이만 보면 무조건 경계인데&lt;/li&gt;
&lt;li data-end=&quot;485&quot; data-start=&quot;406&quot;&gt;원래 그방향이 깊이 변화가 좀 있는 방향이면 그만큼 더 허용해줌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. normal&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;138&quot; data-origin-height=&quot;28&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwWXkS/btsNUtNRMLJ/QUNhH1RfUAtFUvt4opP8KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwWXkS/btsNUtNRMLJ/QUNhH1RfUAtFUvt4opP8KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwWXkS/btsNUtNRMLJ/QUNhH1RfUAtFUvt4opP8KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwWXkS%2FbtsNUtNRMLJ%2FQUNhH1RfUAtFUvt4opP8KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;138&quot; height=&quot;28&quot; data-origin-width=&quot;138&quot; data-origin-height=&quot;28&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;sigma;n = 128&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;법선 방향이 다르면 같은 표면이 아닐 가능성이 높으므로 weight를 급격히 줄여 강하게 억제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. luminance&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;203&quot; data-origin-height=&quot;44&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7elTv/btsNTaOXPNk/izOYrV9cMSeYp5AFsKjtd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7elTv/btsNTaOXPNk/izOYrV9cMSeYp5AFsKjtd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7elTv/btsNTaOXPNk/izOYrV9cMSeYp5AFsKjtd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7elTv%2FbtsNTaOXPNk%2FizOYrV9cMSeYp5AFsKjtd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;203&quot; height=&quot;44&quot; data-origin-width=&quot;203&quot; data-origin-height=&quot;44&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;665&quot; data-start=&quot;616&quot;&gt;&lt;span&gt;분산 자체가 노이즈가 커서 가우시안 블러로 먼저 부드럽게 적용 후 사용&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;665&quot; data-start=&quot;616&quot;&gt;a torus 들어가기 직전에만 사용 -&amp;gt; 갱신될 때마다 사용하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;665&quot; data-start=&quot;616&quot;&gt;&lt;span&gt;분산이 &lt;/span&gt;&lt;span&gt;크면 &amp;rarr; &lt;/span&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;픽셀 &lt;/span&gt;&lt;span&gt;자체가 &lt;/span&gt;&lt;span&gt;noisy &amp;rarr; &lt;/span&gt;&lt;span&gt;밝기 &lt;/span&gt;&lt;span&gt;차이에 &lt;/span&gt;&lt;span&gt;덜 &lt;/span&gt;&lt;span&gt;민감하게 &lt;/span&gt;&lt;span&gt;필터링&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;710&quot; data-start=&quot;666&quot;&gt;&lt;span&gt;분산이 &lt;/span&gt;&lt;span&gt;작으면 &amp;rarr; &lt;/span&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;픽셀은 &lt;/span&gt;&lt;span&gt;안정됨 &amp;rarr; &lt;/span&gt;&lt;span&gt;밝기 &lt;/span&gt;&lt;span&gt;차이에 &lt;/span&gt;&lt;span&gt;더 &lt;/span&gt;&lt;span&gt;민감하게 &lt;/span&gt;&lt;span&gt;대응&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0hQMZ/btsNVYFCijd/i8H1VK6csI8xxAHvncFp11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0hQMZ/btsNVYFCijd/i8H1VK6csI8xxAHvncFp11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0hQMZ/btsNVYFCijd/i8H1VK6csI8xxAHvncFp11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0hQMZ%2FbtsNVYFCijd%2Fi8H1VK6csI8xxAHvncFp11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;253&quot; height=&quot;45&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 정리했듯 분산은 필터내에서 스텝마다 갱신된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 구현된 내 파이프라인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;240&quot; data-start=&quot;221&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. &lt;/span&gt;&lt;span&gt;Path &lt;/span&gt;&lt;span&gt;Tracing&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;564&quot; data-start=&quot;242&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;313&quot; data-start=&quot;242&quot;&gt;&lt;span&gt;G-&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span&gt;생성 - primary ray로 gbuffer생성&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;313&quot; data-start=&quot;264&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;274&quot; data-start=&quot;264&quot;&gt;&lt;span&gt;Normal&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;286&quot; data-start=&quot;277&quot;&gt;&lt;span&gt;Depth&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;299&quot; data-start=&quot;289&quot;&gt;&lt;span&gt;Albedo&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;313&quot; data-start=&quot;302&quot;&gt;&lt;span&gt;Mesh &lt;/span&gt;&lt;span&gt;ID&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이전 카메라 정보를 받아 이전 프레임의 normal depth meshID과 일치도 판별을 하여 누적or갱신 판단
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 픽셀 월드 위치 -&amp;gt; 이전 카메라로 스크린 변환을 거쳐 -&amp;gt; 이전 픽셀 좌표 예측&lt;/li&gt;
&lt;li&gt;픽셀 기준으로 먼저 2x2개의 픽셀 가져옴 -&amp;gt; 조건 만족하는 픽셀만 누적 평균&lt;/li&gt;
&lt;li&gt;없으면 3x3 -&amp;gt; 이래도 없으면 초기화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;315&quot;&gt;&lt;span&gt;누적/&lt;/span&gt;&lt;span&gt;분산 &lt;/span&gt;&lt;span&gt;계산을 &lt;/span&gt;&lt;span&gt;위한 &lt;/span&gt;&lt;span&gt;이미지 &lt;/span&gt;&lt;span&gt;생성&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;440&quot; data-start=&quot;345&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;363&quot; data-start=&quot;345&quot;&gt;Sample Count: 픽셀당 분산이 얼마나 누적되었는지 저장&lt;/li&gt;
&lt;li data-end=&quot;400&quot; data-start=&quot;366&quot;&gt;Moment1&lt;span&gt;: &lt;/span&gt;&lt;span&gt;직접광 / &lt;/span&gt;&lt;span&gt;간접광 &lt;/span&gt;&lt;span&gt;각각 &lt;/span&gt;&lt;span&gt;휘도의 &lt;/span&gt;&lt;span&gt;평균&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;403&quot;&gt;Moment2&lt;span&gt;: &lt;/span&gt;&lt;span&gt;직접광 / &lt;/span&gt;&lt;span&gt;간접광 &lt;/span&gt;&lt;span&gt;각각 &lt;/span&gt;&lt;span&gt;휘도의 &lt;/span&gt;&lt;span&gt;제곱 &lt;/span&gt;&lt;span&gt;평균&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;564&quot; data-start=&quot;442&quot;&gt;&lt;span&gt;출력 &lt;/span&gt;&lt;span&gt;결과&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;564&quot; data-start=&quot;458&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;493&quot; data-start=&quot;458&quot;&gt;&lt;span&gt;Direct &lt;/span&gt;&lt;span&gt;history + &lt;/span&gt;&lt;span&gt;1spp &lt;/span&gt;&lt;span&gt;direct &lt;/span&gt;&lt;span&gt;샘플 ema누적 결과, a = 0.05&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;535&quot; data-start=&quot;496&quot;&gt;&lt;span&gt;Indirect &lt;/span&gt;&lt;span&gt;history + &lt;/span&gt;&lt;span&gt;1spp &lt;/span&gt;&lt;span&gt;indirect &lt;/span&gt;&lt;span&gt;샘플 ema누적 결과, a = 0.05 &lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;564&quot; data-start=&quot;538&quot;&gt;&lt;span&gt;Direct/&lt;/span&gt;&lt;span&gt;Indirect &lt;/span&gt;&lt;span&gt;각각의 &lt;/span&gt;&lt;span&gt;분산 &lt;/span&gt;&lt;span&gt;맵 + 샘플에 누적된 픽셀 수 -&amp;gt; (spp &amp;lt; 4) 판단&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;593&quot; data-start=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2. &lt;/span&gt;&lt;span&gt;3&amp;times;&lt;/span&gt;&lt;span&gt;3 &lt;/span&gt;&lt;span&gt;Gaussian &lt;/span&gt;&lt;span&gt;필터&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;666&quot; data-start=&quot;595&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;629&quot; data-start=&quot;595&quot;&gt;&lt;span&gt;직접광, &lt;/span&gt;&lt;span&gt;간접광 &lt;/span&gt;&lt;span&gt;각각의 &lt;/span&gt;&lt;span&gt;분산 &lt;/span&gt;&lt;span&gt;이미지에 &lt;/span&gt;&lt;span&gt;한 &lt;/span&gt;&lt;span&gt;번만 &lt;/span&gt;&lt;span&gt;적용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;698&quot; data-start=&quot;673&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3. &lt;/span&gt;&lt;span&gt;A-&lt;/span&gt;&lt;span&gt;Trous &lt;/span&gt;&lt;span&gt;Wavelet &lt;/span&gt;&lt;span&gt;필터&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;863&quot; data-start=&quot;700&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;739&quot; data-start=&quot;700&quot;&gt;&lt;span&gt;Direct / &lt;/span&gt;&lt;span&gt;Indirect &lt;/span&gt;&lt;span&gt;각각 &lt;/span&gt;&lt;span&gt;독립적으로 &lt;/span&gt;&lt;span&gt;필터링 &lt;/span&gt;&lt;span&gt;수행&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;783&quot; data-start=&quot;740&quot;&gt;&lt;span&gt;총 &lt;/span&gt;&lt;span&gt;5 &lt;/span&gt;&lt;span&gt;스텝 &lt;/span&gt;&lt;span&gt;반복&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;stride&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;1 &amp;rarr; &lt;/span&gt;&lt;span&gt;2 &amp;rarr; &lt;/span&gt;&lt;span&gt;4 &amp;rarr; &lt;/span&gt;&lt;span&gt;8 &amp;rarr; &lt;/span&gt;&lt;span&gt;16&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;829&quot; data-start=&quot;784&quot;&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;스텝 &lt;/span&gt;&lt;span&gt;결과는 &lt;/span&gt;&lt;span&gt;history &lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;로 &lt;/span&gt;&lt;span&gt;저장&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;다음 &lt;/span&gt;&lt;span&gt;프레임 &lt;/span&gt;&lt;span&gt;누적용)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;863&quot; data-start=&quot;830&quot;&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;스텝 &lt;/span&gt;&lt;span&gt;결과가 &lt;/span&gt;&lt;span&gt;최종 &lt;/span&gt;&lt;span&gt;필터링된 &lt;/span&gt;&lt;span&gt;radiance &lt;/span&gt;&lt;span&gt;출력&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;863&quot; data-start=&quot;830&quot;&gt;&lt;span&gt;spp &amp;lt; 4 일 경우 normal, depth 로만 7x7필터 &lt;s&gt;1step 만 진행 &lt;/s&gt;로 5step 진행&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;886&quot; data-start=&quot;870&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;4. &lt;/span&gt;&lt;span&gt;Composite&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;956&quot; data-start=&quot;888&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;922&quot; data-start=&quot;888&quot;&gt;&lt;span&gt;필터링된 &lt;/span&gt;&lt;span&gt;Direct + &lt;/span&gt;&lt;span&gt;Indirect &lt;/span&gt;&lt;span&gt;결과를 &lt;/span&gt;&lt;span&gt;합산하고,&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;956&quot; data-start=&quot;923&quot;&gt;&lt;span&gt;최종적으로 &lt;/span&gt;&lt;span&gt;Albedo&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;곱해서 &lt;/span&gt;&lt;span&gt;최종 &lt;/span&gt;&lt;span&gt;색을 &lt;/span&gt;&lt;span&gt;복원&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재는 &lt;/span&gt;&lt;span&gt;Tonemapping&lt;/span&gt;&lt;span&gt;과 &lt;/span&gt;&lt;span&gt;TAA(&lt;/span&gt;&lt;span&gt;Temporal &lt;/span&gt;&lt;span&gt;Anti-&lt;/span&gt;&lt;span&gt;Aliasing)&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;아직 &lt;/span&gt;&lt;span&gt;미구현 &lt;/span&gt;&lt;span&gt;상태&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd22nx/btsNTHlaASZ/3iDwBYZfp5IJGIMnjOIJRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd22nx/btsNTHlaASZ/3iDwBYZfp5IJGIMnjOIJRK/img.png&quot; style=&quot;width: 49.4597%; margin-right: 10px;&quot; data-widthpercent=&quot;50.04&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;792&quot; data-origin-width=&quot;1204&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd22nx/btsNTHlaASZ/3iDwBYZfp5IJGIMnjOIJRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd22nx%2FbtsNTHlaASZ%2F3iDwBYZfp5IJGIMnjOIJRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1204&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uwTZF/btsNVePUORl/3jrjk1z6yoaXgbm7uU3xI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uwTZF/btsNVePUORl/3jrjk1z6yoaXgbm7uU3xI0/img.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;792&quot; data-is-animation=&quot;false&quot; data-filename=&quot;250513.PNG&quot; width=&quot;500&quot; height=&quot;329&quot; style=&quot;width: 49.3775%;&quot; data-widthpercent=&quot;49.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uwTZF/btsNVePUORl/3jrjk1z6yoaXgbm7uU3xI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuwTZF%2FbtsNVePUORl%2F3jrjk1z6yoaXgbm7uU3xI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1202&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: svgf 적용 전, 오른쪽: 적용 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전반적으로 문제인데 가장 도드라지는 문제점 몇가지를 뽑아보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;151&quot; data-start=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1. 색 &lt;/span&gt;&lt;span&gt;번짐 (&lt;/span&gt;&lt;span&gt;Albedo &lt;/span&gt;&lt;span&gt;복원 &lt;/span&gt;&lt;span&gt;후 &lt;/span&gt;&lt;span&gt;문제)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;바닥이나 &lt;/span&gt;&lt;span&gt;세면대처럼 &lt;/span&gt;&lt;span&gt;색이 &lt;/span&gt;&lt;span&gt;있는 &lt;/span&gt;&lt;span&gt;오브젝트에서&lt;/span&gt;&lt;br /&gt;&lt;span&gt;알베도를 &lt;/span&gt;&lt;span&gt;나눴다 &lt;/span&gt;&lt;span&gt;다시 &lt;/span&gt;&lt;span&gt;곱하면 &lt;/span&gt;&lt;span&gt;푸른빛이 &lt;/span&gt;&lt;span&gt;번진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 &lt;/span&gt;&lt;span&gt;normal&lt;/span&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;비슷한 &lt;/span&gt;&lt;span&gt;엣지 &lt;/span&gt;&lt;span&gt;주변에서 &lt;/span&gt;&lt;span&gt;색상이 &lt;/span&gt;&lt;span&gt;번짐&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;rarr; &lt;/span&gt;&lt;span&gt;필터 &lt;/span&gt;&lt;span&gt;가중치 &lt;/span&gt;&lt;span&gt;계산식 &lt;/span&gt;&lt;span&gt;확인 &lt;/span&gt;&lt;span&gt;필요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;301&quot; data-start=&quot;278&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2. &lt;/span&gt;&lt;span&gt;수렴 &lt;/span&gt;&lt;span&gt;불안정 / &lt;/span&gt;&lt;span&gt;잔상 &lt;/span&gt;&lt;span&gt;울렁거림&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;한 &lt;/span&gt;&lt;span&gt;샘플의 &lt;/span&gt;&lt;span&gt;영향이 &lt;/span&gt;&lt;span&gt;크다 &lt;/span&gt;&lt;span&gt;보니 &lt;/span&gt;&lt;span&gt;전체 &lt;/span&gt;&lt;span&gt;화면이 &lt;/span&gt;&lt;span&gt;울렁거린다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;EMA &lt;/span&gt;&lt;span&gt;계수를 &lt;/span&gt;&lt;span&gt;0.05&lt;/span&gt;&lt;span&gt;까지 &lt;/span&gt;&lt;span&gt;낮춰도 &lt;/span&gt;&lt;span&gt;완전한 &lt;/span&gt;&lt;span&gt;안정성은 &lt;/span&gt;&lt;span&gt;부족하다.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;rarr; &lt;/span&gt;&lt;span&gt;샘플링 &lt;/span&gt;&lt;span&gt;전략과 &lt;/span&gt;&lt;span&gt;누적 &lt;/span&gt;&lt;span&gt;방식 &lt;/span&gt;&lt;span&gt;재검토 &lt;/span&gt;&lt;span&gt;필요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;431&quot; data-start=&quot;410&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3. &lt;/span&gt;&lt;span&gt;거울 &lt;/span&gt;&lt;span&gt;반사 &lt;/span&gt;&lt;span&gt;영역 &lt;/span&gt;&lt;span&gt;블러 &lt;/span&gt;&lt;span&gt;현상&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;거울이나 &lt;/span&gt;&lt;span&gt;반사 &lt;/span&gt;&lt;span&gt;재질의 &lt;/span&gt;&lt;span&gt;결과가 &lt;/span&gt;&lt;span&gt;흐려지고 &lt;/span&gt;&lt;span&gt;퍼져 &lt;/span&gt;&lt;span&gt;보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;날카로운 &lt;/span&gt;&lt;span&gt;반사 &lt;/span&gt;&lt;span&gt;디테일이 &lt;/span&gt;&lt;span&gt;유지되지 않음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;rarr; &lt;/span&gt;&lt;span&gt;재질별 &lt;/span&gt;&lt;span&gt;필터 &lt;/span&gt;&lt;span&gt;강도 &lt;/span&gt;&lt;span&gt;조정 &lt;/span&gt;&lt;span&gt;또는 &lt;/span&gt;&lt;span&gt;제외 &lt;/span&gt;&lt;span&gt;처리 &lt;/span&gt;&lt;span&gt;고려&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/147</guid>
      <comments>https://surkim.tistory.com/147#entry147comment</comments>
      <pubDate>Mon, 12 May 2025 19:01:03 +0900</pubDate>
    </item>
    <item>
      <title>pt - 7. svgf 필터 추가</title>
      <link>https://surkim.tistory.com/146</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;SVGF&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;기법을 &lt;/span&gt;&lt;span&gt;Path &lt;/span&gt;&lt;span&gt;Tracing &lt;/span&gt;&lt;span&gt;렌더러에 &lt;/span&gt;&lt;span&gt;단계적으로 &lt;/span&gt;&lt;span&gt;도입 &lt;/span&gt;&lt;span&gt;중이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재는 &lt;/span&gt;&lt;span&gt;초기 &lt;/span&gt;&lt;span&gt;구현 &lt;/span&gt;&lt;span&gt;단계로, &lt;/span&gt;&lt;span&gt;카메라 &lt;/span&gt;&lt;span&gt;정지 &lt;/span&gt;&lt;span&gt;상태에서의 &lt;/span&gt;&lt;span&gt;샘플 &lt;/span&gt;&lt;span&gt;누적 &lt;/span&gt;&lt;span&gt;및 &lt;/span&gt;&lt;span&gt;A-&lt;/span&gt;&lt;span&gt;Trous &lt;/span&gt;&lt;span&gt;필터 &lt;/span&gt;&lt;span&gt;기반의 &lt;/span&gt;&lt;span&gt;분산 &lt;/span&gt;&lt;span&gt;가이드 &lt;/span&gt;&lt;span&gt;블러링이 &lt;/span&gt;&lt;span&gt;구현된 &lt;/span&gt;&lt;span&gt;상태다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;405&quot; data-start=&quot;389&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;구현된 &lt;/span&gt;&lt;span&gt;구조&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;405&quot; data-start=&quot;389&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;422&quot; data-start=&quot;407&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. &lt;/span&gt;&lt;span&gt;기본 &lt;/span&gt;&lt;span&gt;구조&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;590&quot; data-start=&quot;423&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;482&quot; data-start=&quot;423&quot;&gt;&lt;span&gt;G-&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span&gt;구성&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;482&quot; data-start=&quot;445&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;482&quot; data-start=&quot;445&quot;&gt;&lt;span&gt;Normal, &lt;/span&gt;&lt;span&gt;Depth, &lt;/span&gt;&lt;span&gt;Albedo&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;G-&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;출력&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;590&quot; data-start=&quot;484&quot;&gt;&lt;span&gt;조명 &lt;/span&gt;&lt;span&gt;분리&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;590&quot; data-start=&quot;498&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;536&quot; data-start=&quot;498&quot;&gt;&lt;span&gt;직접광(&lt;/span&gt;&lt;span&gt;Direct)&lt;/span&gt;&lt;span&gt;과 &lt;/span&gt;&lt;span&gt;간접광(&lt;/span&gt;&lt;span&gt;Indirect)&lt;/span&gt;&lt;span&gt;을 &lt;/span&gt;&lt;span&gt;분리하여 &lt;/span&gt;&lt;span&gt;샘플링&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;590&quot; data-start=&quot;539&quot;&gt;&lt;span&gt;각 &lt;/span&gt;&lt;span&gt;결과에 &lt;/span&gt;&lt;span&gt;대해 &lt;/span&gt;&lt;span&gt;Albedo &lt;/span&gt;&lt;span&gt;디모듈레이션&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;수행 (&lt;/span&gt;&lt;span&gt;Radiance / &lt;/span&gt;&lt;span&gt;Albedo)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;631&quot; data-start=&quot;592&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2. &lt;/span&gt;&lt;span&gt;Temporal &lt;/span&gt;&lt;span&gt;Accumulation (&lt;/span&gt;&lt;span&gt;단순 &lt;/span&gt;&lt;span&gt;방식)&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;743&quot; data-start=&quot;632&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;687&quot; data-start=&quot;632&quot;&gt;&lt;span&gt;이전 &lt;/span&gt;&lt;span&gt;프레임의 &lt;/span&gt;&lt;span&gt;누적 &lt;/span&gt;&lt;span&gt;버퍼가 &lt;/span&gt;&lt;span&gt;존재할 &lt;/span&gt;&lt;span&gt;경우, &lt;/span&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;프레임과 &lt;/span&gt;&lt;span&gt;8:&lt;/span&gt;&lt;span&gt;2 &lt;/span&gt;&lt;span&gt;비율&lt;/span&gt;&lt;span&gt;로 &lt;/span&gt;&lt;span&gt;선형 &lt;/span&gt;&lt;span&gt;보간하여 &lt;/span&gt;&lt;span&gt;누적&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;743&quot; data-start=&quot;688&quot;&gt;&lt;span&gt;현재는 &lt;/span&gt;&lt;span&gt;카메라 &lt;/span&gt;&lt;span&gt;이동 &lt;/span&gt;&lt;span&gt;시 &lt;/span&gt;&lt;span&gt;모든 &lt;/span&gt;&lt;span&gt;히스토리 &lt;/span&gt;&lt;span&gt;삭제&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;정확한 &lt;/span&gt;&lt;span&gt;모션 &lt;/span&gt;&lt;span&gt;벡터 &lt;/span&gt;&lt;span&gt;기반 &lt;/span&gt;&lt;span&gt;일치는 &lt;/span&gt;&lt;span&gt;미도입 &lt;/span&gt;&lt;span&gt;상태)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;775&quot; data-start=&quot;745&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3. &lt;/span&gt;&lt;span&gt;Variance &lt;/span&gt;&lt;span&gt;Computation&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;867&quot; data-start=&quot;776&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;825&quot; data-start=&quot;776&quot;&gt;&lt;span&gt;각 &lt;/span&gt;&lt;span&gt;픽셀에 &lt;/span&gt;&lt;span&gt;대해 &lt;/span&gt;&lt;span&gt;누적 &lt;/span&gt;&lt;span&gt;평균과 &lt;/span&gt;&lt;span&gt;제곱 &lt;/span&gt;&lt;span&gt;평균을 &lt;/span&gt;&lt;span&gt;저장하여 &lt;/span&gt;&lt;span&gt;분산(&lt;/span&gt;&lt;span&gt;variance)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;계산&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;867&quot; data-start=&quot;826&quot;&gt;&lt;span&gt;계산된 &lt;/span&gt;&lt;span&gt;분산은 &lt;/span&gt;&lt;span&gt;3x3 &lt;/span&gt;&lt;span&gt;Gaussian &lt;/span&gt;&lt;span&gt;필터&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;통해 &lt;/span&gt;&lt;span&gt;보간&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;897&quot; data-start=&quot;869&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;4. &lt;/span&gt;&lt;span&gt;A-&lt;/span&gt;&lt;span&gt;Trous &lt;/span&gt;&lt;span&gt;기반 &lt;/span&gt;&lt;span&gt;가이드 &lt;/span&gt;&lt;span&gt;필터링&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1138&quot; data-start=&quot;898&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;930&quot; data-start=&quot;898&quot;&gt;&lt;span&gt;직접광, &lt;/span&gt;&lt;span&gt;간접광 &lt;/span&gt;&lt;span&gt;각각에 &lt;/span&gt;&lt;span&gt;대해 &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;단계 &lt;/span&gt;&lt;span&gt;필터링 &lt;/span&gt;&lt;span&gt;수행&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1077&quot; data-start=&quot;931&quot;&gt;&lt;span&gt;각 &lt;/span&gt;&lt;span&gt;단계에서:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1077&quot; data-start=&quot;943&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;975&quot; data-start=&quot;943&quot;&gt;&lt;span&gt;샘플 &lt;/span&gt;&lt;span&gt;간격(&lt;/span&gt;&lt;span&gt;step &lt;/span&gt;&lt;span&gt;size)&lt;/span&gt;&lt;span&gt;은 &lt;/span&gt;&lt;span&gt;점진적으로 &lt;/span&gt;&lt;span&gt;증가&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1040&quot; data-start=&quot;978&quot;&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;프레임의 &lt;/span&gt;&lt;span&gt;Normal, &lt;/span&gt;&lt;span&gt;Depth, &lt;/span&gt;&lt;span&gt;Variance &lt;/span&gt;&lt;span&gt;정보&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;사용하여 &lt;/span&gt;&lt;span&gt;주변 &lt;/span&gt;&lt;span&gt;픽셀과의 &lt;/span&gt;&lt;span&gt;유사도를 &lt;/span&gt;&lt;span&gt;계산&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1077&quot; data-start=&quot;1043&quot;&gt;&lt;span&gt;유사도에 &lt;/span&gt;&lt;span&gt;따라 &lt;/span&gt;&lt;span&gt;필터의 &lt;/span&gt;&lt;span&gt;가중치를 &lt;/span&gt;&lt;span&gt;조절 (&lt;/span&gt;&lt;span&gt;edge-&lt;/span&gt;&lt;span&gt;aware)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1138&quot; data-start=&quot;1079&quot;&gt;&lt;span&gt;Step &lt;/span&gt;&lt;span&gt;1 &lt;/span&gt;&lt;span&gt;결과는 &lt;/span&gt;&lt;span&gt;History &lt;/span&gt;&lt;span&gt;버퍼로 &lt;/span&gt;&lt;span&gt;저장&lt;/span&gt;&lt;span&gt;되어 &lt;/span&gt;&lt;span&gt;다음 &lt;/span&gt;&lt;span&gt;프레임에서 &lt;/span&gt;&lt;span&gt;temporal &lt;/span&gt;&lt;span&gt;합성에 &lt;/span&gt;&lt;span&gt;사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1155&quot; data-start=&quot;1140&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;5. &lt;/span&gt;&lt;span&gt;최종 &lt;/span&gt;&lt;span&gt;출력&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1233&quot; data-start=&quot;1156&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1187&quot; data-start=&quot;1156&quot;&gt;&lt;span&gt;Step5&lt;/span&gt;&lt;span&gt;의 &lt;/span&gt;&lt;span&gt;직접광, &lt;/span&gt;&lt;span&gt;간접광 &lt;/span&gt;&lt;span&gt;결과를 &lt;/span&gt;&lt;span&gt;합산&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;후,&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1216&quot; data-start=&quot;1188&quot;&gt;&lt;span&gt;다시 &lt;/span&gt;&lt;span&gt;Albedo&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;곱해 &lt;/span&gt;&lt;span&gt;최종 &lt;/span&gt;&lt;span&gt;색상 &lt;/span&gt;&lt;span&gt;복원&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1233&quot; data-start=&quot;1217&quot;&gt;&lt;span&gt;결과 &lt;/span&gt;&lt;span&gt;이미지를 &lt;/span&gt;&lt;span&gt;화면에 &lt;/span&gt;&lt;span&gt;출력&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;까지 했는데 결과가 생각대로 안나온 상태&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과 &lt;/span&gt;&lt;span&gt;이미지까지 &lt;/span&gt;&lt;span&gt;출력하는 &lt;/span&gt;&lt;span&gt;단계까지 &lt;/span&gt;&lt;span&gt;구현을 &lt;/span&gt;&lt;span&gt;마쳤으나, &lt;/span&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;결과가 &lt;/span&gt;&lt;span&gt;예상한 &lt;/span&gt;&lt;span&gt;품질과 &lt;/span&gt;&lt;span&gt;일치하지 &lt;/span&gt;&lt;span&gt;않는 &lt;/span&gt;&lt;span&gt;상태다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/146</guid>
      <comments>https://surkim.tistory.com/146#entry146comment</comments>
      <pubDate>Mon, 12 May 2025 10:39:24 +0900</pubDate>
    </item>
    <item>
      <title>pt - 6. 푸른빛 해결, 안티 엘리어싱, 러시안룰렛 추가</title>
      <link>https://surkim.tistory.com/144</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. NEE 이상 고침&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;250507 NEE적용 후 이상.PNG&quot; data-origin-width=&quot;1205&quot; data-origin-height=&quot;790&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M5Z1n/btsNMgaHd04/DiTRD0Wpi8vVQs7wcku3mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M5Z1n/btsNMgaHd04/DiTRD0Wpi8vVQs7wcku3mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M5Z1n/btsNMgaHd04/DiTRD0Wpi8vVQs7wcku3mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM5Z1n%2FbtsNMgaHd04%2FDiTRD0Wpi8vVQs7wcku3mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;328&quot; data-filename=&quot;250507 NEE적용 후 이상.PNG&quot; data-origin-width=&quot;1205&quot; data-origin-height=&quot;790&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플중 r 값만, (실질적으로 앞의 4bytes만) 0이 되어버려 전반적인 색이 푸르게 변하는 문제가 있었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확히 말하자면 .rgen 파일과 .rchit파일간 데이터를 raypayload 구조체로 주고 받는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조체가 참까다롭다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명확한 레퍼런스는 결국 못찾아 확실하지 않은데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경험상 128bytes를 넘으면 예상하지 못한 에러가 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 에러가 정말 예상을 못하는게 명확한 에러가 나는게 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부분적으로 특정 메모리 지역에 null이 채워진다 던가 하는 에러가 나서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인 찾기가 쉽지가 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 &lt;/span&gt;&lt;span&gt;BRDF &lt;/span&gt;&lt;span&gt;기반 &lt;/span&gt;&lt;span&gt;경로 &lt;/span&gt;&lt;span&gt;추적 &lt;/span&gt;&lt;span&gt;과정에 &lt;/span&gt;&lt;span&gt;Next &lt;/span&gt;&lt;span&gt;Event &lt;/span&gt;&lt;span&gt;Estimation(&lt;/span&gt;&lt;span&gt;NEE)&lt;/span&gt;&lt;span&gt;을 &lt;/span&gt;&lt;span&gt;도입하여,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;레이가 &lt;/span&gt;&lt;span&gt;표면에 &lt;/span&gt;&lt;span&gt;도달했을 &lt;/span&gt;&lt;span&gt;때 &lt;/span&gt;&lt;span&gt;광원을 &lt;/span&gt;&lt;span&gt;샘플링해 &lt;/span&gt;&lt;span&gt;직접광을 &lt;/span&gt;&lt;span&gt;계산하고&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;그 &lt;/span&gt;&lt;span&gt;기여를 &lt;/span&gt;&lt;span&gt;휴리스틱 밸런스를 &lt;/span&gt;&lt;span&gt;통해 &lt;/span&gt;&lt;span&gt;보정한 &lt;/span&gt;&lt;span&gt;뒤 &lt;/span&gt;&lt;span&gt;최종 &lt;/span&gt;&lt;span&gt;radiance&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;반영&lt;/span&gt;&lt;span&gt;하도록 &lt;/span&gt;&lt;span&gt;구현했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtitHi/btsNN9VxaTw/xRDFNT6f6TuAgbbn2FPKNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtitHi/btsNN9VxaTw/xRDFNT6f6TuAgbbn2FPKNk/img.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;794&quot; data-is-animation=&quot;false&quot; data-filename=&quot;250508 noNEE + anti + no bloom + SPP 4096.PNG&quot; width=&quot;500&quot; height=&quot;330&quot; style=&quot;width: 49.3358%; margin-right: 10px;&quot; data-widthpercent=&quot;49.92&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtitHi/btsNN9VxaTw/xRDFNT6f6TuAgbbn2FPKNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtitHi%2FbtsNN9VxaTw%2FxRDFNT6f6TuAgbbn2FPKNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WwQAV/btsNNRt1pSQ/tyYPSKtEAMz2ikwUqrUJDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WwQAV/btsNNRt1pSQ/tyYPSKtEAMz2ikwUqrUJDK/img.png&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;792&quot; data-is-animation=&quot;false&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 4096.PNG&quot; style=&quot;width: 49.5015%;&quot; data-widthpercent=&quot;50.08&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WwQAV/btsNNRt1pSQ/tyYPSKtEAMz2ikwUqrUJDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWwQAV%2FbtsNNRt1pSQ%2FtyYPSKtEAMz2ikwUqrUJDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1204&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: NEE 추가 전, 오른쪽: NEE 추가 후 (SPP 4096)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;brdf기반으로 path tracing 과정에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이가 닿는 모든 표면에 대해 라이트를 샘플링 하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모든 &lt;/span&gt;&lt;span&gt;라이트에 대해 기여를 전부 계산하지는 않고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 있는 모든 &lt;/span&gt;&lt;span&gt;라이트를 &lt;/span&gt;&lt;span&gt;삼각형 &lt;/span&gt;&lt;span&gt;단위로 &lt;/span&gt;&lt;span&gt;분해한 &lt;/span&gt;&lt;span&gt;뒤&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 &lt;/span&gt;&lt;span&gt;삼각형들 &lt;/span&gt;&lt;span&gt;중 &lt;/span&gt;&lt;span&gt;하나를 &lt;/span&gt;&lt;span&gt;유니폼하게 &lt;/span&gt;&lt;span&gt;선택하고&lt;/span&gt;&lt;br /&gt;&lt;span&gt;선택된 &lt;/span&gt;&lt;span&gt;삼각형 &lt;/span&gt;&lt;span&gt;내부에서 &lt;/span&gt;&lt;span&gt;면적 &lt;/span&gt;&lt;span&gt;기반 &lt;/span&gt;&lt;span&gt;샘플링&lt;/span&gt;&lt;span&gt;을 &lt;/span&gt;&lt;span&gt;통해 &lt;/span&gt;&lt;span&gt;한 &lt;/span&gt;&lt;span&gt;점을 &lt;/span&gt;&lt;span&gt;고르는 &lt;/span&gt;&lt;span&gt;방식으로 &lt;/span&gt;&lt;span&gt;구현했다.&lt;/span&gt; &lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;샘플링된 &lt;/span&gt;&lt;span&gt;위치가 &lt;/span&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;지점에서 &lt;/span&gt;&lt;span&gt;가시적인 &lt;/span&gt;&lt;span&gt;경우에만&lt;/span&gt;&lt;br /&gt;&lt;span&gt;BSDF&lt;/span&gt;&lt;span&gt;와 &lt;/span&gt;&lt;span&gt;geometric &lt;/span&gt;&lt;span&gt;term&lt;/span&gt;&lt;span&gt;을 &lt;/span&gt;&lt;span&gt;고려하여 &lt;/span&gt;&lt;span&gt;직접광 &lt;/span&gt;&lt;span&gt;기여를 &lt;/span&gt;&lt;span&gt;계산&lt;/span&gt;&lt;span&gt;하고&lt;/span&gt;&lt;br /&gt;&lt;span&gt;light &lt;/span&gt;&lt;span&gt;pdf&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;기반한 &lt;/span&gt;&lt;span&gt;MIS &lt;/span&gt;&lt;span&gt;보정 &lt;/span&gt;&lt;span&gt;후 &lt;/span&gt;&lt;span&gt;radiance&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;반영했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플 하나일 때 차이가 명확하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZHMGe/btsNOL7I7IN/mnfTr62lWkMlCy4MUTcGwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZHMGe/btsNOL7I7IN/mnfTr62lWkMlCy4MUTcGwk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;792&quot; data-filename=&quot;250508 noNee + anti + no bloom + SPP 1.PNG&quot; style=&quot;width: 49.512%; margin-right: 10px;&quot; data-widthpercent=&quot;50.09&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZHMGe/btsNOL7I7IN/mnfTr62lWkMlCy4MUTcGwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZHMGe%2FbtsNOL7I7IN%2FmnfTr62lWkMlCy4MUTcGwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPQR59/btsNPbkN0kH/SG7Wia5ePgJdWcJbVK05P0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPQR59/btsNPbkN0kH/SG7Wia5ePgJdWcJbVK05P0/img.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;795&quot; data-is-animation=&quot;false&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 1.PNG&quot; style=&quot;width: 49.3252%;&quot; data-widthpercent=&quot;49.91&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPQR59/btsNPbkN0kH/SG7Wia5ePgJdWcJbVK05P0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPQR59%2FbtsNPbkN0kH%2FSG7Wia5ePgJdWcJbVK05P0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: NEE 추가 전, 오른쪽: NEE 추가 후 (SPP 1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 안티 엘리어싱&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;안티 &lt;/span&gt;&lt;span&gt;앨리어싱은 &lt;/span&gt;&lt;span&gt;복잡하게 &lt;/span&gt;&lt;span&gt;처리하지 &lt;/span&gt;&lt;span&gt;않고,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;픽셀 &lt;/span&gt;&lt;span&gt;중심 &lt;/span&gt;&lt;span&gt;대신 &lt;/span&gt;&lt;span&gt;랜덤한 &lt;/span&gt;&lt;span&gt;서브픽셀 &lt;/span&gt;&lt;span&gt;위치에서 &lt;/span&gt;&lt;span&gt;ray&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;쏘는 &lt;/span&gt;&lt;span&gt;방식&lt;/span&gt;&lt;span&gt;으로 &lt;/span&gt;&lt;span&gt;간단히 &lt;/span&gt;&lt;span&gt;해결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프레임마다 &lt;/span&gt;&lt;span&gt;다른 &lt;/span&gt;&lt;span&gt;위치에서 &lt;/span&gt;&lt;span&gt;샘플링되기 &lt;/span&gt;&lt;span&gt;때문에&lt;/span&gt;&lt;br /&gt;&lt;span&gt;프레임 &lt;/span&gt;&lt;span&gt;누적으로 &lt;/span&gt;&lt;span&gt;자연스럽게 &lt;/span&gt;&lt;span&gt;aliasing&lt;/span&gt;&lt;span&gt;이 &lt;/span&gt;&lt;span&gt;줄어드는 &lt;/span&gt;&lt;span&gt;효과&lt;/span&gt;&lt;span&gt;를 &lt;/span&gt;&lt;span&gt;얻을 &lt;/span&gt;&lt;span&gt;수 &lt;/span&gt;&lt;span&gt;있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUxJJ4/btsNOjp43Ws/gtcA4GF6hn6TwtugiKX8xK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUxJJ4/btsNOjp43Ws/gtcA4GF6hn6TwtugiKX8xK/img.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;792&quot; data-is-animation=&quot;false&quot; data-filename=&quot;250508 모든경로 NEE + no anti + no bloom + SPP 4096.PNG&quot; style=&quot;width: 49.3775%; margin-right: 10px;&quot; data-widthpercent=&quot;49.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUxJJ4/btsNOjp43Ws/gtcA4GF6hn6TwtugiKX8xK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUxJJ4%2FbtsNOjp43Ws%2FgtcA4GF6hn6TwtugiKX8xK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1202&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dowoaB/btsNNh05FMZ/0PasSsgoLrafEOXeNig5mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dowoaB/btsNNh05FMZ/0PasSsgoLrafEOXeNig5mk/img.png&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;792&quot; data-is-animation=&quot;false&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 4096.PNG&quot; style=&quot;width: 49.4597%;&quot; data-widthpercent=&quot;50.04&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dowoaB/btsNNh05FMZ/0PasSsgoLrafEOXeNig5mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdowoaB%2FbtsNNh05FMZ%2F0PasSsgoLrafEOXeNig5mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1204&quot; height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: 안티 엘리어싱 적용 전, 오른쪽: 적용 후 (SPP 4096)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/698tU/btsNMyvJfUJ/V0Vkn3icDzpAkhvbHiK5vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/698tU/btsNMyvJfUJ/V0Vkn3icDzpAkhvbHiK5vk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;200&quot; data-filename=&quot;250508 모든경로 NEE + no anti + no bloom + SPP 4096 확대.PNG&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/698tU/btsNMyvJfUJ/V0Vkn3icDzpAkhvbHiK5vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F698tU%2FbtsNMyvJfUJ%2FV0Vkn3icDzpAkhvbHiK5vk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgKrqU/btsNOhTmpig/d5hskqGCI70hVwGrYNK4j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgKrqU/btsNOhTmpig/d5hskqGCI70hVwGrYNK4j0/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;200&quot; data-filename=&quot;250508 모든경로 NEE + anti + no bloom + SPP 4096.PNG&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgKrqU/btsNOhTmpig/d5hskqGCI70hVwGrYNK4j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgKrqU%2FbtsNOhTmpig%2Fd5hskqGCI70hVwGrYNK4j0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: 안티 엘리어싱 적용 전, 오른쪽: 적용 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 러시안 룰렛&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;번 &lt;/span&gt;&lt;span&gt;bounce &lt;/span&gt;&lt;span&gt;이후부터 &lt;/span&gt;&lt;span&gt;경로를 &lt;/span&gt;&lt;span&gt;무조건 &lt;/span&gt;&lt;span&gt;이어가는 &lt;/span&gt;&lt;span&gt;대신 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;throughput&lt;/span&gt;&lt;span&gt;에 &lt;/span&gt;&lt;span&gt;비례한 &lt;/span&gt;&lt;span&gt;확률로 &lt;/span&gt;&lt;span&gt;생존 &lt;/span&gt;&lt;span&gt;여부를 &lt;/span&gt;&lt;span&gt;결정하는 &lt;/span&gt;&lt;span&gt;러시안 &lt;/span&gt;&lt;span&gt;룰렛을 &lt;/span&gt;&lt;span&gt;적용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;에너지 &lt;/span&gt;&lt;span&gt;보존을 &lt;/span&gt;&lt;span&gt;위해 &lt;/span&gt;&lt;span&gt;살아남을 &lt;/span&gt;&lt;span&gt;경우에는 &lt;/span&gt;&lt;span&gt;기여를 &lt;/span&gt;&lt;span&gt;1/&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;로 &lt;/span&gt;&lt;span&gt;보정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p3rfq/btsNNBZEpiA/KKkqKzXPXlC7SEHdDeXyZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p3rfq/btsNNBZEpiA/KKkqKzXPXlC7SEHdDeXyZk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;136&quot; data-filename=&quot;250508 모든경로 NEE + anti + no 러시안룰렛 + SPP 누적중 프레임타임.PNG&quot; style=&quot;width: 49.2556%; margin-right: 10px;&quot; data-widthpercent=&quot;49.84&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p3rfq/btsNNBZEpiA/KKkqKzXPXlC7SEHdDeXyZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp3rfq%2FbtsNNBZEpiA%2FKKkqKzXPXlC7SEHdDeXyZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;261&quot; height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RceyG/btsNND3T5r8/4UYwE2jiiLCvQJUP2CoEvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RceyG/btsNND3T5r8/4UYwE2jiiLCvQJUP2CoEvK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;132&quot; data-filename=&quot;250508 모든경로 NEE + anti + 러시안룰렛 + SPP 누적중 프레임타임.PNG&quot; style=&quot;width: 49.5816%;&quot; data-widthpercent=&quot;50.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RceyG/btsNND3T5r8/4UYwE2jiiLCvQJUP2CoEvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRceyG%2FbtsNND3T5r8%2F4UYwE2jiiLCvQJUP2CoEvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽: 러시안 룰렛 적용 전, 오른쪽: 적용 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Graphics/VulkanPT</category>
      <author>surkim</author>
      <guid isPermaLink="true">https://surkim.tistory.com/144</guid>
      <comments>https://surkim.tistory.com/144#entry144comment</comments>
      <pubDate>Thu, 8 May 2025 10:57:34 +0900</pubDate>
    </item>
  </channel>
</rss>