Image Based Lighting

2025. 7. 17. 20:21·Computer Graphics

Reflectance function

  • Lo : Out Radiance - 점 p에서 Wo(카메라 방향) 으로 반사하는 Radiance
  • Li : Incident Radiance - 점 p에서 Wi (광원 입사 방향) 으로 입사하는 Radiance
  • fr : BRDF 함수. 점 p에서 Wi 방향으로 입사한 빛이 Wo 방향으로 반사하는 비율.S
  • n dot wi : 램버트 코사인 법칙. 광량은 입사각에 따라 감쇠.

 

중요한 것은 BRDF 함수

  • 이것에 따라서 렌더링 결과물이 달라진다.
  • Physically Based Rendering에서는 미세면이론, 에너지 보존을 고려하여 모델링한다.
  • PBR 계산을 위한 재질 파라미터
    • albedo, metalic, roughness, normal, fresnel (F0)
    • F0 은 normal 방향의 입사에서의 반사율. metalic과 roughness를 사용해 대체하기도함.

 

Global Illumination

출처 :

하지만 현실에서는 간접광이 존재

  • Direct : 광원이 직접 카메라에 반사됨
  • Indirect : 다른 물체에 반사된 빛이 다시 반사하여 카메라에 들어옴.

즉 광원 방향뿐만 아니라 모든 가능한 방향에서의 Wo 를 모아주어야 간접광을 포함한 결과이다.

 

따라서 아까의 Rendering Equation에서 반구에 대한 적분이 추가된다.

이것이 General한 Rendering Equation.

 

Unreal Engine에서 사용하는 Rendering Equation

언리얼 엔진은 이 적분부분을 직접광, 간접광으로 나누어 계산한다.

  • 파란색 부분이 IndirectLighting
  • 빨간색 부분이 DirectLighting. (광원이 여러개여서 Sigma 추가)

직접광은 광원마다 계산하고, 간접광은 따로 구해서 더해준다.

Direct Lighting은 계산 난이도가 낮고, IndirectLighting은 계산 난이도가 높으므로 순서대로 파악해봅시다.

먼저 BRDF 함수 (fr함수)

 

BRDF function

 

BRDF에서 반사된 값을 얻기위해서 Diffuse , Specular 텀을 각각 계산해주어야 한다.

PBR에서는 주로 Diffuse → Lambert, Specular → Cook-torrance 를 사용하고, 언리얼엔진도 이를 사용한다.

여기에 Energy conservation Term을 적용하면, (kd + ks = 1)

입사량보다 반사량이 더 많은 오류를 피할 수 있다.

이제 각 텀을 자세히 분석해보자. 기준은 “Real Shading in Unreal Engine 4” 의 내용으로 작성하였다.

 

Diffuse BRDF

  • Light, View 방향과 Independant하다. c는 재질의 diffuse albedo값이다.
  • 이는 반구방향으로 균일하게 퍼지는 램버시안 표면을 계산한 값이다.

PI로 나눠주는 이유를 자세히 보면,

Albedo라는 값은 입사광을 얼마나 반사시키는지를 0~1 값으로 나타낸 것. 이는 광선으로 입사해서 반구 전체에 퍼뜨린다. (hemispherical-directional reflectance)

albedo = 반사하는 모든 광량 / 입사 광량

BRDF는 반사 광선 하나에 대해 관심이 있으므로 그에 맞게 반구에서 광선으로 줄여주는 작업이 필요한데, 수학적으로 증명하면 이는 pi이다.

자세한 증명은 아래에.

https://sakibsaikia.github.io/graphics/2019/09/10/Deriving-Lambertian-BRDF-From-First-Principles.html

 

Specular : Microfacet Cook-Torrance BRDF

게임업계에서 가장 주류를 이루는 정반사 모델은 미세면 이론 기반 Microfacet Cook-Torrance BRDF 이다.

미세면 이론 (Microfacet Theory)

물체의 표면을 미소표면으로 간주하여 표면이 평평하다고 볼 수 있습니다. 그리고 각 표면의 정보를 통계적으로 정의하여 계산하는 방식입니다.

 

출처 zhihu (https://zhuanlan.zhihu.com/p/53086060)

각 미세면의 법선 벡터를 m이라고하면, m=h인 벡터의 비율만큼만 시선v에 기여합니다.

하지만 실제 환경에서 모든 h벡터를 가지는 표면이 반사에 기여하지는 않습니다.

 

출처 zhihu (https://zhuanlan.zhihu.com/p/53086060)

 

l 방향에 가려진 그림자, v방향에 가려진 차폐에 의해서 차단됩니다. 실제로 이러한 두 표면은 BRDF에 기여하지 않습니다. 미세면 이론에서는 차폐,그림자 된 빛은 정반사 항에서 사라집니다.

3번째 그림을 보면 다중 표면 반사로인해 표시되지만 일반적으로 미세면 표현에서는 이를 반영하진 않습니다.

 

 

BRDF로 표현

이러한 가정(국소적으로 광학적으로 평평한 표면)을 사용하여 Microfacet Cook-Torrance BRDF라고 하는 Specular BRDF 용어를 분석해봅시다.

D(h): Normal Distribution Function. 미세 영역 정규 분포의 확률, 즉 올바른 방향의 법선이 집중된 확률을 설명하는 정규 분포 함수입니다. 즉, l에서 v로 빛을 반사하는 올바른 방향을 갖는 표면 영역에 대한 표면 점의 농도입니다.

출처 zhihu (https://zhuanlan.zhihu.com/p/53086060)

l,v 가 정의되었을 때, m = h 인 벡터의 비율이 얼마일까를 표현합니다.

G(l,v,h): Geometric Attenuation Function. 마이크로평면의 자체 그림자,마스킹 비율. 즉 m = h인데 차폐, 그림자지지 않은 표면 점의 백분율을 설명하는 형상 함수입니다.

F(l,h): Fresnel Function. 프레넬 현상을 표현합니다. 큰 각도로 입사한 광선이 더 큰 specular값을 갖는 현상을 표현합니다.

G, F 텀 보다는 D가 결과에 더 많이 기여합니다.

각 텀을 살펴봅시다.

 

D - Normal Distribution Function

  • Beckmann[1963]
  • Blinn-Phong[1977]
  • GGX [2007] / Trowbridge-Reitz[1975]
  • Generalized-Trowbridge-Reitz(GTR) [2012]
  • Anisotropic Beckmann[2012]
  • Anisotropic GGX [2015]

UE4에서는 NDF 함수로 Disney에서 채택한 GGX/TrowBridge-Reitz 라는 함수를 사용합니다. Blinn-Phong에서 약간의 추가비용으로 사용할 수 있고, 뚜렷하고 자연스러운 긴 “꼬리” 효과를 제공합니다.

 

Unreal source code

// GGX / Trowbridge-Reitz
// [Walter et al. 2007, "Microfacet models for refraction through rough surfaces"]
float D_GGX( float a2, float NoH )
{
	float d = ( NoH * a2 - NoH ) * NoH + 1;	// 2 mad
	return a2 / ( PI*d*d );					// 4 mul, 1 rcp
}

 

G - Specular Geometric Attenuation

  • Smith [1967]
  • Cook-Torrance [1982]
  • Neumann [1999]
  • Kelemen [2001]
  • Implicit [2013]

에서 네 가지 형태로 확장했는데요.

  • 분리 가능한 마스킹 및 섀도잉
  • 높이 상관 마스킹 및 섀도잉
  • 방향 상관 마스킹 및 섀도잉
  • 높이 방향 상관 마스킹 및 섀도잉

“분리 가능한 마스킹/섀도잉 함수”로 정의된 모델들은 다음과 같고

(G함수를 빛의 방향, 시야 방향으로 독립적으로 나눠 계산하는 모델)

  • Smith-GGX
  • Smith-Beckmann
  • Smith-Schlick
  • Schlick-Beckmann
  • Schlick-GGX

UE4는 Schlick-GGX를 사용하며 ****수식은 다음과 같습니다.

 

UE5에서는 두 텀이 독립적이지 않은 “높이 방향 상관 마스킹 및 섀도잉” 으로 변경된 것 같네요.

// Appoximation of joint Smith term for GGX
// [Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"]
float Vis_SmithJointApprox( float a2, float NoV, float NoL )
{
	float a = sqrt(a2);
	float Vis_SmithV = NoL * ( NoV * ( 1 - a ) + a );
	float Vis_SmithL = NoV * ( NoL * ( 1 - a ) + a );
	return 0.5 * rcp( Vis_SmithV + Vis_SmithL );
}

 

Schlick와 Smith는 비슷하다고 합니다.

 

 

F - Fresnel

  • Cook-Torrance [1982]
  • Schlick [1994]
  • Gotanta [2014]

Fresnel 항은 일반적으로 비용이 낮고 정확도가 충분한 Schlick 프레넬 근사를 사용한다고 합니다.

 

UE4에서는 pow연산을 완화하기위해 자체적인 근사식으로 개량해서 사용했고, (Spherical Gaussian approximation)

 

F(v, h) = F0 + (1 − F0) 2 ^(−5.55473(v·h)−6.98316)(v·h)

 

UE5에서는 다른 F함수로 수정된 것으로 보임.

Unreal GBuffer 의 Specular = F0이고 다음과 같이 유도됨.

 

half DielectricSpecularToF0(half Specular)
{
	return 0.08f * Specular;
}

half3 ComputeF0(half Specular, half3 BaseColor, half Metallic)
{
	return lerp(DielectricSpecularToF0(Specular).xxx, BaseColor, Metallic.xxx);
}

GBuffer.SpecularColor = ComputeF0(Specular, BaseColor, Metallic);

 

// [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"]
float3 F_Schlick( float3 SpecularColor, float VoH )
{
	float Fc = Pow5( 1 - VoH );					// 1 sub, 3 mul
	//return Fc + (1 - Fc) * SpecularColor;		// 1 add, 3 mad
	
	// Anything less than 2% is physically impossible and is instead considered to be shadowing
	return saturate( 50.0 * SpecularColor.g ) * Fc + (1 - Fc) * SpecularColor;
}

float3 F_Schlick(float3 F0, float3 F90, float VoH)
{
	float Fc = Pow5(1 - VoH);
	return F90 * Fc + (1 - Fc) * F0;
}

 

자 여기까지 왔다면 빨간색 항(직접광)을 구할 수 있습니다.

모든 광원에 대해서 Diffuse, Specular를 구할 수 있습니다.

Direct Lighting With CookTorrance 결과물

출처 : 직접 구현

 

그 다음은 파란색 Indirect Lighting 항을 구해봅시다.

 

Image Based Lighting

해당 텀을 구하기위해서 Image Based Lighting (IBL) 이라는 기법을 사용합니다.

IBL 은 특정 점으로 입사하는 모든 광량을 계산하는 기법인데요. 이 입사 광량을 계산할 때 sphere에 매핑된 Cubemap Texture을 이용하는 방식입니다.

이 Cubemap Texture가 (실시간이 아닌) 미리 계산되거나 처리되었으면, Pre-Filtered, Pre-Computed 같은 말이 붙습니다.

이 매핑된 Sphere를 probe라고 하며, 어느 정도 커버하냐에 따라

  • Distant light probe
  • Local light probe

로 분류됩니다.

Distant light probe는 Environment mapping을 생각하면 됩니다. 무한히 멀리에서 오는 ray를 표현하는 것이며, 때문에 어느 지점에서 샘플링하던 결과가 같습니다.

반면 Local light probe은 한정된 거리(볼륨) 내에서의 샘플링을 위한 것이며 샘플링할 때 위치에 대한 변위도 추가해주어야 합니다.

 

IBL 분석

Distant light probe인 Environment mapping을 구현하며 IBL 동작을 분석해봅시다.

Integral을 단순화 시키기위해 먼저 Importance Sampling 기법을 사용합니다.

Importance Sampling

Integral을 그냥 Summation으로 바꾸는 것은 문제가 있습니다.

  • Sample이 매우 많이 필요하며 이는 런타임에 부적합
  • Sample이 적으면 Noise 발생

출처 : 직접 구현

Importance Sampling의 기본 아이디어

⇒ 확률 밀도 함수를 정의해서 낮은 확률로 걸린 샘플에 높은 Weight를 주자.

왜 ? 확률이 낮으면 Uniform Sampling을 했을 때보다 걸린 샘플이 적을거고,

높으면 Uniform Sampling을 했을 때보다 걸린 샘플이 많을테니까

그 Weight가 바로 그 (1/샘플이 걸릴 확률).

 

이 Importance Sampling을 적용해도 해당 계산은 굉장히 복잡해서 실시간으로 구하기 힘듭니다.

만해 1024개의 ray를 계산한다고 가정하면, 우리가 계산하는 픽셀마다 1024의

 

을 구해야하며, 이는 굉장히 비싼 연산입니다.

이 연산은 리얼타임 렌더링에 부적합하며, 여러가지 단순화를 진행합니다.

 

계산 단순화

먼저 view dependency 없애기 입니다.

미세면 모델과 half-angle parameterization에서 view-angle은 굉장히 중요한 요소입니다.

frostbite- pbr paper (https://seblagarde.wordpress.com/wp-content/uploads/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf)

 

누워있는 각도에서 anisotropy를 높이기 때문에 이를 무시하면 아래와 같은 artifact가 발생합니다.

frostbite- pbr paper (https://seblagarde.wordpress.com/wp-content/uploads/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf)

 

그러나 이는 trade-off 로 감수할만한 부분입니다.

또한 parameter 단순화를 위해 roughness와 F0만 사용합니다.

마지막으로, importance sampling을 사용하여 샘플링 converge 속도를 높입니다.

 

pr함수는 BRDF함수의 확률밀도함수이며, li 는 pr함수로 샘플링된 라이트입니다.

Split Sum Approximation

[SIGRAPH2013 Karis] 에서는 이를 단순화 하기위해 Split Sum Approximation을 제안합니다. 이는 Sigma 혹은 integral 에서 분리할 수 없는 곱 연산을 근사화하여 분리하는 기법입니다.

이는 수학적으로는 오류가 있지만, trade-off로 감당가능한 수준입니다.

 

Image Based Lighting

앞의 세 가지 가정과 함께 다시 수식으로 ..

  • Importance Sampling
  • Split Sum Approximation
  • View Dependency 제거

BRDF함수의 PDF는 다음과 같이 정의되며, 원래 L(v) 함수를 근사화해보면,,,

다음과 같이 두 가지 term으로 나누어집니다.

[SIGRAPH2013 Karis]에서 소개한 Schlick Fresnel term을 사용한다면,

DFG term은 다음과 같이 계산됩니다.

LD term은 incident lighting이 바뀐다면 런타임에 계속 다시구해줘야합니다.

이는 LD 계산이 빠르고, noise에 대해 robust해야함을 의미합니다.

Importance sampling은 convergence를 도와주지만, 역시도 꽤나 샘플이 필요한데요,

Pre-filtered importance sampling [Kriv`anek KC08] 은 pre-filtered value를 사용해 비교적 적은 샘플 수로도 convergence를 유도하는 방식입니다.

 

대조가 심한 환경에서 roughness가 큰 경우에는 노이즈가 보일 수 있는데요,

이를 없애기위해서 sample pattern에 rotating/jittering을 추가하면 줄일 수 있습니다.

고스팅이 증가한다고 하지만 노이즈보다는 보기 좋다고 하네요. (+ TAA와 함께 사용하면 더 효과적일 듯 합니다.)

frostbite- pbr paper (https://seblagarde.wordpress.com/wp-content/uploads/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf)

 

Specular 구현 결과

출처 : 직접 구현

 

출처 : 직접 구현

Sharp aliasiing 발생.

이는 specular가 중첩되면서 발생

 

Filtered Importance Sampling

GPU Gem 3에서 소개된 내용

아이디어 : 샘플된 PDF가 작다면 (샘플이 낮은 확률을 뚫고 샘플되었다면), 다른 샘플은 비슷한 각도에서 샘플링되진 않을거다.

⇒ PDF가 낮을수록 넓은 범위의 illumination을 샘플링하자

== 낮은 Mipmap을 샘플링하자.

 

반대로 샘플된 PDF가 높으면, 다른 비슷한 각도에서도 샘플링되기 때문에 여러 샘플링이 적절히 평균내줄 것이다.

⇒ 높은 Mipmap을 샘플링하자.

출처 : https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling

 

이를 수학적으로 표현해보면

내가 샘플링할 solid angle 크기를 sample과 pdf 로 비례 관계를 구해보면,

출처 : https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling

pdf와 반비례, 샘플수와 반비례

기준이 될 solid angle 크기를 구해보면,

Miplevel 0 의 enviroment map 에서 픽셀 한개정도의 solid angle을 다음과 같이 정의.

d(u) : distortion. 추후 다시 언급

출처 : https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling

(내 샘플링 solid angle) / (one pixel solid angle)을 기준으로 mip level을 정한다.

출처 : https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling

앞 부분은 미리 계산 가능해서 최적화를 위해 빼둔 것이고, 뒤만 런타임에 구해주면 된다.

mipmap이 2배수로 증가하기 때문에 log2텀이 나온 것.

 

Distortion

Sphere → Cubemap으로 변환할 때의 distortion 수치를 적용해줍니다.

Mipmap 사용

이 정보를 pre-filtered map에 저장할 때, roughness가 높을수록 high frequency 맵 (넓은 범위에 필터링된 맵) 을 사용해야합니다. 이를 빠르게 구하기 위해서 (roughness * miplevels) 값의 miplevel에 해당 roughness로 필터링된 맵을 저장합니다.

그럼 런타임에는 roughness * miplevels 값으로 prefilter map을 샘플링하면 LD 텀을 빠르게 구할 수 있습니다.

 

 

출처 : https://bruop.github.io/ibl/

 

Filtered Importance Sampling 결과물

출처 : 직접 구현

 

(좌 before , 우 after)

 

Lambertian Diffuse Component

diffuse part는 다음과 같이 표현가능합니다.

환경맵에서는 해당 식이 material 속성이나 view direction과 독립적이라서 모든 N에 대해서 계산해서 cube map에 저장해두었다가 실시간에 특정 N에 대해서 Lookup할 수 있습니다. 이를 irradiance map이라고 하며 hemisphere에 대해 간단한 uniform sampling으로 구현할 수 있습니다.

 

#define TWO_PI 6.2831853071795864769252867665590
#define HALF_PI 1.5707963267948966192313216916398

#define THREADS 8

SAMPLERCUBE(s_source, 0);
IMAGE2D_ARRAY_WR(s_target, rgba16f, 1);

NUM_THREADS(THREADS, THREADS, 6)
void main()
{
    const float imgSize = 64.0;
    ivec3 globalId = gl_GlobalInvocationID.xyz;

    vec3 N = normalize(toWorldCoords(globalId, imgSize));

    vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
    const vec3 right = normalize(cross(up, N));
    up = cross(N, right);

    vec3 color = vec3_splat(0.0);
    uint sampleCount = 0u;
    float deltaPhi = TWO_PI / 360.0;
    float deltaTheta = HALF_PI / 90.0;
    for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) {
        for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) {
            // Spherical to World Space in two steps...
            vec3 tempVec = cos(phi) * right + sin(phi) * up;
            vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
            color += textureCubeLod(s_source, sampleVector, 0).rgb * cos(theta) * sin(theta);
            sampleCount++;
        }
    }
    imageStore(s_target, globalId, vec4(PI * color / float(sampleCount), 1.0));
}

 

런타임에 다음과 같이 구해주면 됩니다.

 
float3 SingleScatteringIBL(float3 F0, float2 EnvBRDF, float3 diffuseColor, float3 radiance, float3 irradiance)
{
    float3 specularDFG = (F0 * EnvBRDF.x + EnvBRDF.yyy);
    
    float3 color = (specularDFG * radiance) + (diffuseColor * irradiance);
    return color;
}

float NoV = saturate(dot(N, V));
float4 EnvBRDF = EnvBRDFTexture.Sample(linearClampSampler, float2(NoV, roughness));
const float3 irradiance = IrradianceTexture.Sample(pointWrapSampler, worldSpaceNormal).rgb;
uint PrefilterMipLevel = min(roughness * EnvMipCount, EnvMipCount-1);
float3 radiance = PrefilterEnvmap.SampleLevel(pointClampSampler, WorldSpaceL, PrefilterMipLevel).rgb;

color = SingleScatteringIBL(F0, EnvBRDF.xy, diffuseColor, radiance, irradiance);
...

 

 

Single Scattering 최종 결과

  • Light : Image Based Lighting Only
  • Tonemaping (ACEs) 적용
  • Gamma Correction 적용

출처 : 직접 구현

 

출처 : 직접 구현

 

 

여기까지 구현한 모델을 Single Scattering 모델이라고 하는데요. (Single Scattering인 이유는 다음에 제시될 Multiple-Scattering Model 과 비교하면 알 수 있습니다.)

이 모델의 단점은 에너지보존법칙을 따르지 않는다는 점입니다.

결과물을 보았을 때 roughness가 증가할수록 Conductor 모델에서 급격하게 어두워지는 현상을 볼 수 있는데요

 

출처 : 직접 구현

 

에너지보존을 증명하는 방법 중에는 모든 방향에서 들어오는 Light를 1로 설정한 뒤에 색이 1인 물체를 렌더링해보는 것 입니다. (이를 white furnace test라고 부릅니다.)

 

출처 : 직접 구현

그러면 conductor의 경우에는 roughness가 증가할수록 어두워지는, 즉 에너지를 잃는 현상이 생기고, dielectric 의 경우에는 표면에서 에너지가 남는 현상을 볼 수 있습니다.

 

Eric Heitz는 Multiple-Scattering Microfacet BSDFs with the Smith Model [2015] 에서 이 원인을 mutiple-scattering에 의한 light가 계산되지 않았기 때문이라는 것을 증명했고, 이를 보완한 Multiple-Scattering BSDF 모델을 제안했습니다.

 

다음 챕터

Multiple-Scattering BSDF 기반의 IBL

 

소스 코드

https://github.com/Jooh34/CubiEngine

Reference

https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf

https://pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models

https://graphicscompendium.com/gamedev/15-pbr

https://zhuanlan.zhihu.com/p/53086060

  • 디즈니 PBR

https://github.com/QianMo/PBR-White-Paper/blob/master/content/part 3/README.md

  • frostbite pbr

https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf

  • SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice

https://blog.selfshadow.com/publications/s2013-shading-course/

  • IBL by Chetan Jags

https://chetanjags.wordpress.com/2015/08/26/image-based-lighting/

  • Real-time Shading with Filtered Importance Sampling

https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling

  • GPU-Based Importance Sampling 

https://cgg.mff.cuni.cz/~jaroslav/papers/2008-egsr-fis/2008-egsr-fis-final-embedded.pdf

  • Multiple-Scattering Microfacet BSDFs with the Smith Model https://eheitzresearch.wordpress.com/240-2/

'Computer Graphics' 카테고리의 다른 글

Multi-Scattering BRDF  (4) 2025.07.19
Two Pass Occlusion Culling  (0) 2025.07.01
'Computer Graphics' 카테고리의 다른 글
  • Multi-Scattering BRDF
  • Two Pass Occlusion Culling
jooh3444
jooh3444
게임엔진 / 그래픽스 개발 블로그
  • jooh3444
    Jooh 개발 블로그
    jooh3444
  • 전체
    오늘
    어제
    • Dev blog (18)
      • OpenGL (7)
        • CS-248 셰이더 프로그래밍 (7)
      • 언리얼 엔진 (7)
      • 기타 (1)
      • Computer Graphics (3)
  • 블로그 메뉴

    • 홈
    • About
    • github
  • 인기 글

  • 태그

    Virtual Shadow Map
    Enviroment Lighting
    Computer Graphics
    Shadow map
    범프 매핑
    그래픽스
    Shader
    OpenGL
    Nanite
    twopass occlusion culling
    셰이더
    multi-scattering brdf
    Shader Programming
    셰이더 프로그래밍
    Unreal Engine 5
    Blueprint load by path
    bDontLoadBlueprintOutsideEditor
    UE5 bugfix
    UE5
    Unreal Engine
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
jooh3444
Image Based Lighting
상단으로

티스토리툴바