519e4980de
네 가지 작업이 같은 함수들을 겹쳐 고쳐서 한 커밋으로 묶는다. 쪼개려면 hunk 단위로 갈라야 하는데 서로 얽혀 있어 오히려 위험하다. 먼 바다 배경 (backdrop.gd) - 3/4 부감에서 화면 위쪽은 더 먼 곳이다. 거기까지 모래를 깔면 바다가 아니라 사막처럼 보여서, 위쪽 띠를 물로 비웠다. - 먼 물 그라디언트 → 능선 → 먼 실루엣 순으로 깊이를 만든다. - Seabed가 뒷줄일수록 색을 물빛 쪽으로 당겨 공기원근을 준다. - 빛줄기를 알파를 더하는 방향으로 바꿨다. 걷어내는 방향이면 바닥만 밝아지고 물기둥은 텅 빈 채로 남는다. 하루의 빛 (day_cycle.gd) - 실제 시각에 맞춰 새벽/아침/낮/저녁/밤. 이름은 구간으로 끊고 색과 밝기는 계속 보간한다. - 밤에는 물결과 빛줄기가 잦아들고, 스스로 빛나는 것은 어둠을 되밀어 오히려 도드라진다. - godot --path . -- --hour=21 로 특정 시각을 눈으로 확인할 수 있다. 한 화면에 한 층 - 가로 연속 스크롤을 버리고 층 전환으로 바꿨다. 위층(얕은 바다)에서 아래층(열수구)으로 내려간다. 층 선택기·휠·↑↓ 키. - 층은 내부적으로 여전히 옆으로 늘어서 있고 화면이 한 구간만 비춘다. 갈아탈 때만 세로로 미끄러뜨려 깊이가 위아래로 읽히게 했다. - 칸 크기를 가로에서 정하도록 뒤집고 ZONE_COLUMNS를 36으로 올렸다. 층당 칸이 96 -> 216이라 정원과 해금 곡선은 다시 봐야 한다. - 한 화면에 한 층만 보이므로 층 색은 이웃과 섞지 않는다. 감상 모드 (F11) - 창을 화면 전체로. 세로로 남는 공간은 격자가 아니라 물기둥에 준다. 격자를 키우면 타일만 커지고 보이는 열은 오히려 줄어든다. - 창을 화면과 픽셀까지 똑같이 맞추면 Windows가 독점 전체화면으로 승격시켜 size 지정이 먹지 않는다. usable_rect까지만 쓴다. 그 밖에 - 저장 window_state: scroll_x -> layer - 알림이 정보 바와 겹치던 것을 바 아래로 옮겼다 - 난파선 선체 폴리곤이 제 몸을 가로질러 삼각분할이 실패하던 것 수정 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
2.7 KiB
Plaintext
54 lines
2.7 KiB
Plaintext
shader_type canvas_item;
|
|
// 탑다운 바다의 물빛 오버레이. 바닥 위에 덮여서 "물을 통해 내려다본다"는 느낌을 만든다.
|
|
// 구역 하나를 담당하고, 좌우 끝 색을 이웃과 공유해 이음매 없이 이어진다.
|
|
|
|
uniform vec4 tint_left : source_color = vec4(0.27, 0.70, 0.80, 1.0);
|
|
uniform vec4 tint_right : source_color = vec4(0.16, 0.51, 0.57, 1.0);
|
|
// 깊을수록 물이 두꺼워 바닥이 흐려진다.
|
|
uniform float murk_left : hint_range(0.0, 1.0) = 0.20;
|
|
uniform float murk_right : hint_range(0.0, 1.0) = 0.30;
|
|
|
|
// 물결 무늬가 구역 경계에서 끊기지 않도록 스트립 전체에서의 위치를 넘겨받는다.
|
|
uniform float x_offset = 0.0;
|
|
uniform vec2 rect_size = vec2(300.0, 220.0);
|
|
uniform float caustic_strength : hint_range(0.0, 0.4) = 0.13;
|
|
// 수면에서 내려오는 빛의 양. 밤에는 0에 가까워져 물결도 빛줄기도 잦아든다.
|
|
uniform float sun : hint_range(0.0, 1.0) = 1.0;
|
|
// 수면에서 내려오는 빛줄기. 얕은 구역에서만 뚜렷하고 깊어질수록 사라진다.
|
|
uniform float ray_left : hint_range(0.0, 1.0) = 0.7;
|
|
uniform float ray_right : hint_range(0.0, 1.0) = 0.6;
|
|
|
|
void fragment() {
|
|
vec2 px = vec2(x_offset, 0.0) + UV * rect_size;
|
|
vec3 tint = mix(tint_left.rgb, tint_right.rgb, UV.x);
|
|
float murk = mix(murk_left, murk_right, UV.x);
|
|
|
|
// 수면에서 갈라진 빛이 바닥에 드리우는 그물 무늬.
|
|
vec2 p = px / 78.0;
|
|
float c = sin(p.x + TIME * 0.45) * sin(p.y * 1.3 - TIME * 0.31);
|
|
c += sin(p.x * 1.7 - TIME * 0.38) * sin(p.y * 0.8 + TIME * 0.44);
|
|
float caustic = pow(max(c * 0.5 + 0.5, 0.0), 3.0) * sun;
|
|
|
|
// 밝은 물결 자리는 물이 얇아 보이도록 살짝 걷어낸다.
|
|
float alpha = clamp(murk - caustic * caustic_strength * 0.5, 0.0, 1.0);
|
|
vec3 col = tint + caustic * caustic_strength;
|
|
|
|
// 비스듬히 내려오는 빛줄기. 3/4 시점이라 화면 위쪽(먼 곳)에서 가장 밝고
|
|
// 앞으로 올수록 흩어진다. 물속임을 알려주는 가장 강한 신호다.
|
|
float rs = mix(ray_left, ray_right, UV.x) * sun;
|
|
if (rs > 0.001) {
|
|
// 거의 세로로 서되 살짝 기운다. y 계수를 크게 잡으면 화면이 높을 때
|
|
// 무늬가 가로로 누워버려 빛줄기로 안 보인다.
|
|
float g = px.x * 0.010 + px.y * 0.0035;
|
|
float r = (sin(g + TIME * 0.09) * 0.5 + 0.5)
|
|
* (sin(g * 2.3 - TIME * 0.06) * 0.5 + 0.5);
|
|
float rays = pow(r, 2.6) * rs * smoothstep(1.0, 0.02, UV.y);
|
|
// 빛줄기는 물을 걷어내는 게 아니라 물 속에 떠 있는 밝은 기둥이다.
|
|
// 알파를 낮추면 바닥만 밝아지고 물기둥은 텅 빈 채로 남는다.
|
|
col += rays * 0.38;
|
|
alpha = clamp(alpha + rays * 0.20, 0.0, 1.0);
|
|
}
|
|
|
|
COLOR = vec4(col, alpha);
|
|
}
|