Jasontreks Blog

DM 보내기

메세지는 텔레그램 챗봇에 의해 익명으로 전달됩니다. 답장을 받으려면 이메일을 입력하세요.
Send

그래픽 디자인 - Interactive 환경 요소

우리 팀은 기획 단계에서 전략적 상호작용을 설계하기 위해 고안된 수풀(Bush)과 연못(Pond)을 디자인하는 작업에 착수하였다.

수풀과 연못의 공통점은 플레이어보다 앞에 있어 직접적인 상호작용을 연출해야 한다는 점이다. 따라서 월드에 배치할때는 z-index가 플레이어보다 작도록 설정한다.

수풀 디자인

수풀은 플레이어와 대포를 충분히 가릴 만큼 크기가 크도록 디자인해야 한다.

우선 아래와 같이 흔한 상록 활엽 관목의 모습을 떠올렸다.

이 모습을 참고해 2D 수풀의 이미지를 생성형 AI의 도움을 받아 제작하였다.

디자인을 이대로 끝내면 밋밋할 거 같아서 몇 가지 꽃잎을 직접 그려 추가하였다.

연못 디자인

연못의 경우 물의 유동성을 표현하면 좋기 때문에 쉐이더에서 사인 함수의 조합으로 파동을 구현하였다.

이전에 그래픽 디자인 - Non-Interactive 환경 요소 포스트에서 다루었던 사인 함수를 이용한 풀의 흔들림 구현과 원리가 같다. 아래 사인 함수를 이용하는 쉐이더 코드에서 확인할 수 있다.

float wave_point(float uv_x, float wave_length, float wave_height, float wave_speed, float wave_offset) {
	return wave_height * (sin(wave_length * uv_x + TIME * wave_speed) + wave_offset);
}

다른 점은 해당 함수의 반환값이 픽셀의 Y좌표라는 점, 텍스처를 변형하는 게 아닌 Y를 기준으로 색상을 채운다는 점이다.

// 각 웨이브의 y값 계산
float wave_bottom = wave_point(uv.x, wave_b_length, wave_b_height, wave_b_speed, wave_b_offset);
float wave_middle = wave_point(uv.x, wave_m_length, wave_m_height, wave_m_speed, wave_m_offset);
float wave_top = wave_point(uv.x, wave_t_length, wave_t_height, wave_t_speed, wave_t_offset);

함수를 세 번 호출하고 진폭, 파장값 등 인자를 각각 다르게 전달함으로써 세 가지 모양의 파동이 조합된 연못 물결을 연출할 수 있다.

float blend_amount = 0.1; // 블렌딩 강도 조절

// 색상 블렌딩
vec4 final_color;

if (uv.y > wave_bottom) {
    float t = smoothstep(wave_bottom, wave_bottom + blend_amount, uv.y);
    final_color = mix(m_color, b_color, t);
}
else if (uv.y > wave_middle) {
    float t = smoothstep(wave_middle, wave_middle + blend_amount, uv.y);
    final_color = mix(t_color, m_color, t);
}
else if (uv.y > wave_top) {
    float t = smoothstep(wave_top, wave_top + blend_amount, uv.y);
    final_color = mix(vec4(0.0), t_color, t);
}
else {
    final_color = vec4(0.0, 0.0, 0.0, 0.0);
}

그리고 세 가지 색상으로 각 파동을 구성해 최종적인 물결 텍스처를 완성한다. smoothstep() 함수는 각 파동의 경계가 명확하지 않고 그라데이션을 적용해 색상이 부드럽게 변화하도록 하여 부자연스러움을 줄인다. blend_amount 값으로 경계가 흐릿한 정도를 조절한다.

Abstract art
blend_amount = 0 (smoothstep 미적용)
Abstract art
blend_amount = 0.1

이제 이 출렁이는 물결 텍스처 위에 웅덩이 지면 텍스처를 입히면 최종적인 연못 오브젝트가 완성된다.

Abstract art

또한 각 물결의 색상을 poisoned 계수에 따라 선형보간하여 청정 상태에서 오염 상태로의 변화를 연출할 수 있다.

// 청정 상태 <-> 독성화 상태 색 보간
vec4 b_color = mix(b_clean_color, b_poisoned_color, poisoned);
vec4 m_color = mix(m_clean_color, m_poisoned_color, poisoned);
vec4 t_color = mix(t_clean_color, t_poisoned_color, poisoned);

게임 속에서 연못이 독탄에 맞아 독성화되는 과정에서 poisoned 계수에 일정 속도로 변화를 줌으로써 해당 연출을 구현하였다.

다음 포스트

대포와 플레이어 애니메이션