재료 배열 ingredient가 주어짐
[1, 2, 3, 1] 순서가 연속으로 등장하면 햄버거 1개 완성
햄버거를 만들면 해당 4개의 재료는 제거
최종적으로 만들 수 있는 햄버거 개수 구하기
❌ 1차 시도: 인덱스 기반 + erase 방식
초기 코드
int answer = 0;
vector<int> checks ={1,2,3,1};
for(int i=0; i<ingredient.size(); i++){
bool ham = false;
for(int j=0; j<4; j++){
if(checks[j] == ingredient[i+j]){
cout<<ingredient[i+j]<<endl;
ham = true;
}
else{
ham = false;
}
}
if(ham==true){
answer+=1;
ingredient.erase(ingredient.begin()+i,ingredient.begin()+i+4);
i=0;
}
}
🚨 문제점 분석 (디버깅 포인트)
1️⃣ 범위 초과 접근 (Out of Bounds)
ingredient[i + j]
i가 끝부분에 가까우면 i+3이 벡터 범위를 벗어남
런타임 에러 위험 ⚠️
2️⃣ ham 논리 오류
if (checks[j] == ingredient[i+j]) ham = true;
else ham = false;
중간에 틀려도 루프가 계속 돌면서 ham 값이 덮어씌워짐
“4개 모두 일치”가 아니라 “마지막 비교 결과”만 남는 구조
3️⃣ erase 이후 인덱스 처리 문제
erase 하면 벡터가 당겨짐
i=0으로 리셋은 가능하지만 비효율적
겹치는 패턴 처리도 애매해짐
✅ 최소 수정으로 고친 버전
int answer = 0;
vector<int> checks = {1,2,3,1};
for (int i = 0; i + 3 < ingredient.size(); i++) {
bool ham = true;
for (int j = 0; j < 4; j++) {
if (checks[j] != ingredient[i + j]) {
ham = false;
break;
}
}
if (ham) {
answer++;
ingredient.erase(ingredient.begin() + i, ingredient.begin() + i + 4);
i = max(i - 4, -1); // 겹침 패턴 재검사
}
}
✨ 배운 점
연속 패턴 비교는 시작부터 true → 하나라도 틀리면 break
erase 이후엔 이전 위치 재검사 필요
🚀 정석 풀이: 스택(벡터) 기반 접근
핵심 아이디어
재료를 하나씩 쌓는다
마지막 4개만 확인
맞으면 pop 4번 → 햄버거 +1
구현 코드
int answer = 0;
vector<int> st;
for (int x : ingredient) {
st.push_back(x);
if (st.size() >= 4) {
int n = st.size();
if (st[n-4]==1 && st[n-3]==2 && st[n-2]==3 && st[n-1]==1) {
answer++;
st.pop_back();
st.pop_back();
st.pop_back();
st.pop_back();
}
}
}
👍 장점
erase 없음 → O(N) 시간
인덱스 꼬일 위험 없음
구현도 직관적
🤔 std::stack은 왜 비추천인가?
stack으로도 가능은 함
top만 접근 가능
4개 pop → 검사 → 아니면 다시 push (복구 필요)
단점
코드 복잡
실수 여지 많음
이 문제엔 vector를 스택처럼 쓰는 게 훨씬 낫다
📝 오늘의 핵심 정리
연속 패턴 제거 문제 → 스택 사고방식
erase 반복은 성능·안정성 모두 불리
std::stack은 “진짜 스택 성질”이 필요할 때만 사용
알고리즘 문제에서는 vector가 최고의 스택
무엇을 만들기 위해, 어떤 노드를 쓰는가
머티리얼을 공부하면서 가장 크게 느낀 점은 이것이었다.
“노드를 안다고 머티리얼을 만드는 게 아니다.
구현하고 싶은 효과가 먼저다.”
그래서 이번 TIL은
‘이 노드는 언제 쓰는가?’를 기준으로 정리했다.
무엇을 구현할 때?
벽, 캐릭터 피부, 나무, 소품 등
사람이 직접 보는 색이 중요한 경우
색공간이 중요한 이유
여러 DCC 툴과 엔진은 각각 다른 색공간(Color Space)을 사용한다.
같은 RGB 값이라도 어떤 색공간에서 해석되느냐에 따라 실제 보이는 색은 달라진다.
Linear
프로그램 내부에서 정확한 수치 계산을 위해 사용하는 색공간
sRGB
사람의 눈에 맞게 명도를 보정한 색공간
우리가 보는 대부분의 이미지가 여기에 해당
언리얼 엔진에서도 텍스처마다
sRGB ON / OFF를 명확히 구분해서 사용한다.
실무 기준 정리
Base Color → sRGB ON
Normal / Mask / AO → sRGB OFF
작업 기준
Base Color는 연산 없이 그대로 사용
색 조절이 필요할 경우
Multiply + Vector Parameter로 제어
느낀 점
색이 이상하면 노드보다 sRGB 체크부터
라이팅 문제인 줄 알았는데
알고 보면 색공간 문제였던 경우가 많았다
언리얼 엔진은 최종 화면 출력 단계(Scene View)에서
ACES 색공간을 사용한다.
톤매핑이란?
쉐이더 연산 결과로 나온 HDR(32bit) 색을
모니터에 출력 가능한 LDR(8bit) 범위로 압축하는 과정
ACES란?
Academy Color Encoding System
미국 영상 업계 표준 색공간
장점
영상 업계 표준
OCIO 프로파일 적용 가능
단점
채도가 변할 수 있음
DCC 툴마다 작업 색공간이 다르기 때문에
실무에서는 색공간을 맞추는 것이 중요한 워크플로우 단계다.
무엇을 구현할 때?
벽돌, 바위, 갑옷, 기계 표면 등
표면 굴곡이 중요하지만 메시를 늘릴 수 없을 때
개념
하이폴리곤 모델의 디테일을
로우폴리곤 메시 위에 ‘빛 반응’으로 속이는 기법
픽셀 단위로 노멀 방향을 조정하여 입체감을 표현
필수 설정
sRGB OFF
Compression: Normalmap
Texture Sample → Normal 핀
왜 하이폴을 그대로 안 쓰나?
폴리곤 수 증가 → 연산 비용 증가
리깅, 버텍스 작업 시 생산성 저하
Displacement는 경우에 따라 대안이 될 수 있음
느낀 점
“형태를 속인다”는 표현이 가장 정확
노멀맵이 잘못되면 라이팅이 전부 망가진다
무엇을 구현할 때?
나뭇잎 흔들림
풀 움직임
깃발, 천
간단한 외곽선 효과
기본 구성 예시
Time → Sine → Multiply(Strength)
→ VertexNormalWS → World Position Offset
값 기준
강도: 0.1 ~ 1.0
속도: Time * 0.5 ~ 2.0
느낀 점
애니메이션 없이도 “움직이는 것처럼” 보이게 만들 수 있다
충돌은 변하지 않는다는 점을 모르고 쓰면 문제 생김
무엇을 구현할 때?
벽 틈
장식물 접합부
캐릭터 장비 사이 음영
사용 방식
AO Texture → Ambient Occlusion 핀
기본값 유지
필요 시 Multiply (0.7 ~ 1.0)
느낀 점
AO는 라이팅을 보조하는 역할
과하면 오히려 가짜 느낌이 난다
UE5 + Lumen 환경에선
AO 영향이 줄어들 수 있다는 점도 인지 필요
언제 쓰는가?
같은 재질인데 색이나 거칠기만 다른 경우
런타임에서 값 변경이 필요한 경우
Scalar Parameter
Roughness
Metallic
Emissive 강도
예시:
Scalar Parameter → Roughness
Roughness 느낌
0.1 금속
0.6 플라스틱
0.9 고무
Vector Parameter
색상 틴트
발광 색
팀 컬러
Vector Parameter → Multiply(BaseColor)
Material Instance
머티리얼 복제 없이 변형
드로우콜 감소
작업 속도 향상
느낀 점
인스턴스 없이 머티리얼 만드는 건 실무에서 거의 불가능
언제 쓰는가?
Mask 연산 후
Multiply / Add 결과가 1을 넘을 때
Multiply → Saturate → Output
느낀 점
하드웨어 비용 거의 없음
습관처럼 써도 되는 안전장치
언제 쓰는가?
RMA 텍스처
마스크 패킹
예시:
R → Roughness
G → Metallic
B → AO
느낀 점
실무에서 패킹 안 하면 용량·성능 모두 손해
언제 쓰는가?
마스크 강조
발광 경계 조절
Mask → Power(2 ~ 4)
느낀 점
값 조금만 올려도 결과 변화 큼
과하면 인위적으로 보임
언제 쓰는가?
복잡한 수식
반복 계산
특수 쉐이딩 로직
느낀 점
가능하면 쓰지 말자
노드로 가능한 건 노드가 가장 안전하다
머티리얼 작업에서 가장 중요한 건 항상 이것이다.
지금 무엇을 만들고 싶은가?
색을 표현하고 싶은가?
디테일을 살리고 싶은가?
움직이게 하고 싶은가?
재사용하고 싶은가?
이 질문이 정해지면
👉 사용할 노드도 자연스럽게 정해진다.