Home 14. Reflection And Refraction
Post
Cancel

14. Reflection And Refraction

Sampler State

텍스처 import 설정에는 샘플링 정보가 존재하는데,

이중 몇 가지 옵션에 대해 Override, 재 정의할 수 있는 기능이 존재합니다.

Untitled

Point, Linear, Trilinear

Clamp,Repleat,Mirror,MirrorOnce

  • “Point”, “Linear” 또는 “Trilinear”(필수)는 텍스처 필터링 모드를 설정합니다.
  • “Clamp”, “Repeat”, “Mirror” 또는 “MirrorOnce”(필수)는 텍스처 랩 모드를 설정합니다.
    • 랩 모드는 축(UVW)에 지정할 수 있습니다. 예를 들어, “ClampU_RepeatV”
  • “Compare”(선택)는 뎁스 비교용 샘플러를 설정합니다. HLSL SamplerComparisonState 타입과 SampleCmp/SampleCmpLevelZero 함수를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//sampler state는 3.5 이상에서 동작합니다.
#pragma target 3.5 

////////////////////////////////////
///            정의              ///
////////////////////////////////////

TEXTURE2D(_BaseMap);

SAMPLER(sampler_BaseMap);
//이는 다음과 같습니다
SamplerState sampler_BaseMap; // "sampler" + "_MainTex"

//혹은 다음과 같이 하드코딩해서 특정 samplerState를 만들어둘 수 있습니다.
SamplerState point_linear_sampler;
SamplerState _SamplerState_Point_Repeat_sampler;
SamplerState _pointRepeat;     //카멜/파스칼 가능
SamplerState _pointrepeat;     //풀 소문자 가능
SamplerState _pointKorearepeat;//사이에 다른글자 OK
SamplerState repeatKoreapoint; //순서 바껴도 OK

////////////////////////////////////
///            사용              ///
////////////////////////////////////

//기본적으론 다음과 같이 사용하지만,
half4 color = tex2D(_MainTex, uv);

//이런식으로 특정 샘플러를 적용해서 사용할 수 있습니다.
half4 color = _BaseMap.Sample(sampler_BaseMap, IN.uv);

//혹은 다음과 같이요
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);

Untitled

Global Texture

Untitled

Untitled

해당 설정을 켜줘야합니다.

그렇다면

Untitled

이 게임화면에서 저 CameraOpaqueTextrue는 무엇일까요?

Untitled

이 _CameraOpaqueTexture는

Opaque + Skybox만 렌더링한 상황에서의 카메라 렌더텍스처입니다.

Untitled

Refraction

골자는 다음과 같습니다.

UV를 스크린스페이스로 구성해서, 해당 좌표에 존재하는 기존 그려진 정보를 들고와서 렌더링.

대신 오브젝트의 노멀방향으로 특정수치만큼 늘린 값을 가져와, 굴절효과를 줍니다.

정말 코어만 가져간다면,

화면좌표의 색상= (화면좌표 + 오브젝트의 화면공간에서의 노말방향)의 색상

입니다

두가지 쉐이더그래프를 통해 알아봅시다.

Untitled

노말을 가져옵니다.

하지만 이건 뭔가 사등분되어 정규화 후 보간한 것 같은 느낌입니다.

구체니까 fresnel, 즉 View와 Normal의 내적값을 가져옵니다.

Untitled

해당 위치의 scree color, colorOpaqueTexture를 가져와 칠합니다.

굴절?

이때 굴절률이 중요한데,

중학교때 배웠던 교과서를 잘 살펴봅시다.

스넬 굴절법칙에 따라

굴절률 = sinθ1sinθ2\frac{sin \theta_1}{sin\theta_2} 라고 할 때,

물의 굴절률은 1.333… 입니다.

입사각이 45도면 굴절각은 32.1도라는 소리죠.

비례식을 구합니다

nisin(θi)=nxsin(θx)n_i \cdot sin(\theta_i) = n_x \cdot sin(\theta_x)

여기서 기존값, ni=1,nxn_i=1, n_x =1.33

이라 가정하고 sin(θi)1.33=sin(θx)\frac{sin(\theta_i)}{1.33} = sin(\theta_x)

라고 나옵니다.

Untitled

즉 식은

y = sin1(sin(θ)1.333 )y\ =\ \sin^{-1}\left(\frac{\sin\left(\theta \right)}{1.333}\ \right)

입니다.

따라서,

T=n1n2(P+cos(θ1)N)Ncos(θ2)T = \frac{n_1}{n_2}(P+cos(\theta_1)N) - Ncos(\theta_2)

이므로,

삼각함수의

cos2+sin2=1,cos(t)=1sin2(t)cos^2+sin^2 = 1,\\ \therefore cos(t) = \sqrt{1-sin^2(t)}

의 공식을 사용하여

T=n1n2(P+cos(θ1)N)N1sin2(θ2)T = \frac{n_1}{n_2}(P+cos(\theta_1)N) - N\sqrt{1-sin^2(\theta_2)}

이 됩니다.

sin(θ2)=n1n2sin(θ1)sin(\theta_2) = \frac{n1}{n2}sin(\theta_1)

이므로

이걸다시 재정리하면

T=n1n2(P+cos(θ1)N)N1(n1n2)2sin2(θ1)T = \frac{n_1}{n_2}(P+cos(\theta_1)N)-N\sqrt{1-(\frac{n1}{n2})^2sin^2(\theta_1)}

어렵습니다.

여기서 cos은 dot이라는걸 알고있으니 또 정리하면

T=n1n2(P+(NP)N)N1(n1n2)2(1cos2(θ1))T = \frac{n_1}{n_2}(P+ (N\cdot P)N)- N\sqrt{1-(\frac{n1}{n2})^2(1-cos^2(\theta_1))}

식이 너무 복잡하니

n=n1n2,c=1n2(1cos2(θ1))n=\frac{n1}{n2},\quad c = \sqrt{1-n^2\cdot(1-cos^2(\theta_1))}

이라 가정하면

T=n(P+(NP)N)Nc,T=nP+(n(NP)c)NT = n(P+(N\cdot P)N)-Nc,\\ T = nP +(n(N\cdot P)-c)N

입니다.

1
2
3
4
5
6
7
8
vector3 refract(vector3 p,vector3 n, float n)
{
	float NoP = dot(n,p);
	float NoP2 = NoP * NoP;
	float n2 = n*n;

	return n * p + (n * NoP - sqrt(1 - (n2 * (1 - NoP2))))*n;
}

어때요 엄청 간단하죠?

자 이제 저런 수학식 없이 refraction을 짜봅시다.

간단한 refraction 구현

뷰좌표계에서 처리를 해봅시다.

노멀위치로 이동한지점의 픽셀을 가져오면 됩니다.

외곽에서 심해야하니 프레넬을 살짝 첨가하고요.

이해하기 쉽도록 그래프로 표현하면 다음과 같습니다.

Untitled

결과물

refract_1.gif

사실 이렇게 구성된 부분엔 문제가 있습니다.

Untitled

찌글거림, 정확한 좌표계를 따르지 않기 때문입니다.

Untitled

방향행렬을 구해 뒤집어줍니다

Untitled

Untitled

refract_2.gif

으아 졸작한다고 바빠서 뭐 아무것도 못했네요

This post is licensed under CC BY 4.0 by the author.
Contents