답변:
수심을 기준으로 조명수에는 기본적으로 두 가지 방법이 있습니다.
Minecraft는 복셀 기반 조명을 사용하며 블록 유형에 따라 밝기를 낮추어 인접한 큐브로 빛을 전파하여 작동합니다. 어두운 바다는이 시스템의 부작용입니다.
물은 햇빛을 차단하고 빛을 블록 당 3 단계 씩 줄입니다 (기본 1 단계 대신).
0 (surface): 15 (direct sunlight)
1: 12
2: 9
3: 6
4: 3
5 and below: 0 (darkness)
출처 : 마인 크래프트 위키-Light
전통적인 조명 모델을 사용하는 게임에서는 광원과 해저 사이에있는 물의 양을 측정하여이 효과를 만들 수 있습니다. 그런 다음이 거리에 따라 빛이 희미 해집니다. 이를위한 몇 가지 방법이 있습니다.
평평한 표면이있는 경우, 수면으로부터이 표면 법선 과이 법선의 내적 및 표면 위치 를 지오메트리 쉐이더로 전달하면 빛이 물로 이동하는 거리를 쉽게 계산할 수 있습니다 .
효과적인 물 거리는
여기서 정점의 위치 는 지표면 아래의 빛 방향과 수면을 향한 수면 법선 사이의 각도입니다.
해 가 질 때 물이 들어올 때 빛이 굴절되기 때문에 50 °보다 약간 작아집니다.
다음은 좋은 설명이 포함 된 블로그 게시물입니다 . 디지털 카메라 : 내부 전반사
자세한 내용이 포함 된 또 다른 게시물 : 디지털 카메라 : Snell의 굴절 법칙
물과 평행 한 표면에 하이트 맵을 사용하는 경우 가됩니다 . 태양이 수면 바로 위에있는 경우 올바른 계수는 1입니다.
포인트 라이트를 사용하면 광원 에 대한 상대 위치를 기준으로 각 정점에 대해 계산해야합니다 .
고정 수위 또는 고정 광 방향으로 방정식의 일부는 일정하므로 성능상의 이유로 셰이더에서 계산해서는 안됩니다.
수면을 광원에서 볼 때 별도의 깊이 맵으로 렌더링하는 경우 해당 깊이 텍스처를 사용하여 표면에 닿기 전에 물에서 빛이 이동하는 거리를 계산할 수 있습니다.
이를 위해 각 정점을 정점 셰이더에서 광원의 뷰 투영으로 투영하고 픽셀 셰이더에서 텍스처 조회를 수행합니다.
표면이 비교적 평평한 경우 더 나은 결과를 얻으려면 굴절 된 광원을 사용해야합니다.
* 광선 POV의 깊이를 다음과 같이 계산하여 가장 가까운 고체 표면 앞에서 물의 양을 결정할 수 있습니다.
결과 텍스처는 이제 라이트 뷰 스페이스에서 라이트 앞의 물의 양을 포함하므로 값을 사용하기 전에 다시 변환해야합니다. 이 방법은 방향 조명 (마이너스 굴절)을 계산하는 데 사용되지만 표면이 매우 불규칙하고 같은 조각에 영향을주는 수역 사이에 많은 양의 공기가있는 경우 주변 조명이 잘못 될 수 있습니다.
장단점은 깊이를 계산하는 동안 하나 이상의 버퍼가 필요하고 더 많은 지오메트리를 그려야하기 때문에 성능이 더 나빠진다는 점을 제외하면 일반 섀도우 매핑의 경우와 같습니다.
레이트 레이싱은 투명 볼륨 렌더링을위한 가장 정확하지만 가장 비싼 솔루션입니다. 이를 수행하는 방법은 두 가지가 있습니다. 1. 해저에서 지표면으로의 추적 2. 광원에서 물로의 추적. 밝기를 계산하려면 바닥의 각 지점마다 여러 개의 광선이 필요합니다.
물을 렌더링 할 때 고려해야 할 사항이 몇 가지 더 있습니다.
관찰자에게 이동하는 동안 물 속의 빛이 다시 산란되므로 단색으로 혼합해야합니다.
옵저버가 잠긴 경우, 깊이 버퍼의 최종 결과에 따라 안개를 렌더링 할 수 있습니다. 안개 색상은 아니지만 밀도는 표면에서 관찰자의 거리에 따라 변해야합니다! (Minecraft는이 부분의 효과 만 사용합니다.)
관찰자가 위에서 물을 보면 수면과 지오메트리 사이의 깊이 차이를 기반으로 안개를 계산해야합니다. 안개 색상은 깊이 차이가 클수록 약간 어두워 지지만 안개가 완전히 불투명 한 지점으로 만 변경되어야합니다.
안개 색상은 각 픽셀의보기 방향에 따라 달라 지므로 두 경우 모두 아래를 내려다볼 때 약간 어둡습니다.
가짜 가성으로 데칼 대신 매끄러운 타일링 3D 텍스처를 사용하는 경우 수직 표면에서 스트레칭을 피할 수 있습니다. 표면 근처에서 산란 된 빛의 강도는 3 차원으로 다양하므로 2D 텍스처를 사용하면 일반적으로 장면 어딘가에서 스트레칭이 생성됩니다. 바닥의 꼭짓점 위치를 다른 좌표계로 투영하여 조명 각도 변경을 모델링 할 수 있습니다.
또 다른 가능성은 빛의 좌표계에서 표면 위치를 기준으로 빛의 밀도를 계산하는 것입니다.
화선은 깊이가 증가함에 따라 확산 광보다 빠르게 사라집니다.
색상이 다르게 흩어져 있으므로 밝은 색상은 깊이가 증가함에 따라 변해야합니다. 또한 예를 들어 해변이 수면과 교차하는 갑작스러운 가장자리를 방지합니다.
굴절 때문에 빛은 평상시보다 훨씬 가파르게 해저에 닿습니다. 스넬의 법칙에 대한 위키 백과의 문서 각도와 벡터에 대한 공식을 가지고있다.
나는 Minecraft의 하늘 조명 효과가 똑바로 있다고 생각합니다. 태양이 어디에 있든 상관없이 그 위에있는 것들에 의해 음영이 나타납니다. 그런 다음 횃불 등의 로컬 조명에 드롭 오프 효과가 적용됩니다. 광원에서 멀어 질수록 큐브의 빛은 줄어 듭니다.
이 방법으로 수행하면 각 물 층이 그 아래 층을 누적 음영 처리하므로 점진적으로 어두워집니다. 나무 단풍은 이와 같은 그늘을 제공하지만 누적되지는 않습니다. 1 개 또는 100 개의 단풍 큐브에 상관없이 나무 아래에서 같은 그늘을 얻습니다.
이것이 사용되는 방법 중 하나의 단서는 뷰어에서 멀어 질 때 물이 더 어두워지지 않는다는 것입니다. 그렇습니다. 안개 효과는 먼 거리에서 시작되지만 물 어두운 효과는 아닙니다.
따라서 조명을 계산하는 기본 공식은 의사 코드에서 다음과 같습니다.
light_on_cube = 1.0
for each cube above target cube, from lowest to highest {
if cube being examined is tree foliage
light_on_cube = 0.5
else if cube being examined is water
light_on_cube = light_on_cube - 0.1
else if cube being examined is solid
light_on_cube = 0
}
이 방법을 사용하면 돌출부 아래에서 피치가 어두워 지므로 돌출부 또는 동굴에서 조명을 계산하는 데 적합하지 않습니다. 그러나 태양 광 블록을 광원으로 취급 할뿐만 아니라 지역 광원 (토치, 화재 등)을 모두 추가 할 수 있습니다. 이런 식으로 할 수 있습니다 ...
여기서 아이디어는 태양이나 토치에 의해 큐브가 켜지면 그 옆에있는 큐브도 어떤 방식 으로든 켜질 것입니다. 그리고 그 조명 큐브에서 멀어 질수록 빛이 줄어 듭니다. 확산 조명을 추정하는 일종의 멍청한 방법이지만 작동한다고 생각합니다 (?).
아마도 나는 그 질문을 오해하고 있지만 왜 깊이에 따라 블록의 색상을 바꿀 수 없습니까?
깊이 d (블록 단위, 0부터 시작)가 있으면 적절한 밝기 방정식은 다음과 같습니다.
L = (1- m ) e - kd + m
암호: L = (1.0 - m) * exp(-k * d) + m;
k 는 어두워지는 속도를 제어합니다 (높을수록 빠름). 합리적인 값은 0.5입니다.
m 은 원하는 최소 밝기입니다.
L 은 0에서 1까지 다양합니다.
사용중인 그래픽 API에서 블록 색상을 변경하는 방법을 모르는 경우 별도의 질문으로 사용하십시오 (사용하는 API 및 셰이더 사용 여부를 지정).
e^-kd
비트 서서히 어떤 값 (깊이)를 통해 0으로 경향 가지 표준 함수 단지 지수 감쇠이다. 곱셈 (1-m)
과 덧셈은 m
붕괴를 스케일링하고 상쇄하여 최소로 끝나지만 m
여전히 시작합니다 1
. en.wikipedia.org/wiki/Exponential_decay