← 모든 글

엔지니어링 철학: 리누스 토르발스, 사라지는 특수한 경우

Linux와 git을 만든 리누스 토르발스

핵심 요약

  • 좋은 취향이란 특수한 경우가 사라지는 순간입니다. 자료 구조를 다시 빚으면 – 포인터 대신 포인터를 가리키는 포인터로 – 예외를 처리하던 if가 더 이상 머무를 곳을 잃습니다.
  • “코드를 보여달라”는 슬로건이 아니라 인식론입니다. 설계는 가설일 뿐이며, 논쟁을 매듭짓는 것은 실제로 돌아가는 코드뿐입니다.
  • git은 분산을 자료 구조의 필연적 귀결로 만듭니다. 내용으로 주소가 매겨지는 객체 덕분에 모든 저장소는 동등하며, 그래서 지켜야 할 “유일한 진본”이라는 것이 애초에 존재하지 않습니다.
  • 규모에서의 신뢰는 가정이 아니라 구조로 떠받쳐야 합니다. 토르발스는 이를 두 번 풀었습니다 – 누가 책임지는지를 정하는 메인테이너 트리와, 무엇이 일어났는지를 변조 불가능하게 기록하는 히스토리로 말입니다.

원칙

“때로는 문제를 다른 방식으로 바라보고 다시 작성해서, 특수한 경우가 사라지고 평범한 경우로 바뀌게 만들 수 있습니다. 그게 바로 좋은 코드라는 것을 여러분이 이해했으면 합니다.” – 리누스 토르발스, TED, 20161

토르발스는 TED 무대 위에서 두 개의 C 함수를 나란히 펼쳐 들고 있었습니다. 둘 다 단일 연결 리스트에서 항목 하나를 삭제하는 함수였습니다. 첫 번째는 prev 포인터로 리스트를 훑으며, 삭제할 항목이 머리(head)인지를 검사하고 분기했습니다. 머리는 특수한 경우로, 나머지는 일반적인 경우로 처리한 것입니다. 열 줄에 if 하나. 두 번째 함수는 포인터를 가리키는 포인터 – **indirect – 로 리스트를 훑었기에, 머리는 애초에 특수한 위치가 아니었습니다. 그저 그 포인터를 가리키는 포인터가 처음으로 가리키게 된 대상일 뿐이었습니다. 네 줄에 if 없음.1

줄 수가 적다는 점이 핵심이었던 적은 한 번도 없습니다. 첫 번째 버전의 조건문은 오로지 프로그래머가 리스트의 머리를 나머지 부분과 다른 것으로 모델링했기 때문에 존재했습니다. 더 나은 자료 구조를 고르면 – 포인터 대신 포인터를 가리키는 포인터로 – 그 차이는 증발합니다. 예외란 문제에 본래 내재한 것이 아니라, 문제를 어떻게 표현했는지에서 비롯된 인위적 산물이었습니다. 토르발스가 말하는 취향이란 바로 이 한 수이며, 그것은 취향이 미적 선호가 아니라 기술 시스템이게 만드는 바로 그 신념과 같습니다. 우아한 버전이 이기는 이유는 더 예뻐서가 아니라 더 옳기 때문입니다. 틀릴 수 있는 자리가 더 적게 남아 있으니까요.

그 직관 – 특수한 경우를 없애 예외가 숨을 곳을 빼앗는다 – 은 토르발스가 만든 모든 것을 관통합니다. 또한 그것은 그의 또 다른 유명한 한마디가 선언문이라기보다 지시문처럼 읽히는 이유이기도 합니다. “말은 싸다. 코드를 보여달라.”2

토르발스의 TED 강연에 나온 연결 리스트 삭제의 두 버전: "당연한" 버전은 if로 머리를 특수한 경우로 처리하고, "좋은 취향" 버전은 포인터를 가리키는 포인터를 써서 특수한 경우를 완전히 없앤다

위에서 직접 해보십시오. 가운데 노드를 삭제한 다음, 각 모드에서 머리를 삭제해 보십시오. “당연한 방식”에서는 머리가 if (!prev) 분기를 건드리지만, “좋은 취향”에서는 머리도 그저 또 하나의 링크일 뿐이어서 동일한 한 줄이 그것을 처리합니다.

배경

리누스 베네딕트 토르발스는 1969년 핀란드 헬싱키에서 스웨덴어를 쓰는 가정에 태어났습니다. 헬싱키 대학교의 컴퓨터 과학과 학생이던 그는 Minix를 사용했습니다. Minix는 네덜란드 교수 앤드루 타넨바움이 교육용 도구로 작성한 작은 Unix 계열 운영체제였습니다. Minix는 배울 점이 많았지만 의도적으로 제한적이었습니다 – 타넨바움은 학생들이 전체를 읽어낼 수 있도록 일부러 단순하게 유지했습니다. 토르발스는 허락된 것보다 더 많은 것을 원했습니다.

1991년 8월 25일, 그는 comp.os.minix Usenet 뉴스그룹에 글을 올렸습니다. “저는 (무료) 운영체제를 만들고 있습니다(그냥 취미예요, gnu처럼 크고 전문적이진 않을 겁니다). 386(486) AT 호환기용입니다.”3 괄호 안에 깔아 둔 그 단서는 소프트웨어 역사상 가장 자주 인용되는 오판입니다.

1991년 8월 25일 comp.os.minix에 올린 토르발스의 최초 발표문 -- "그냥 취미예요, gnu처럼 크고 전문적이진 않을 겁니다"

그 취미는, 어떤 배포 지표로 보아도, 지구상에서 가장 널리 돌아가는 커널이 되었습니다 – 대다수의 웹 서버, 모든 Android 휴대폰, 그리고 클라우드와 슈퍼컴퓨팅 인프라의 압도적 비중을 떠받칩니다.

아키텍처는 처음부터 논쟁거리였습니다. 1992년 초, 타넨바움은 “LINUX는 시대에 뒤떨어졌다(LINUX is obsolete)”라는 제목의 스레드를 열어, 모놀리식 커널은 “1970년대로 거대하게 후퇴한 것”이며 마이크로커널 – 운영체제를 격리된, 메시지를 주고받는 서비스들로 분해하는 방식 – 이 미래라고 주장했습니다.4 토르발스는 마이크로커널이 “이론적·미학적” 관점에서 우월함을 인정한 다음, 그래도 모놀리식 커널을 계속 만들었습니다. 동작했고, 빨랐고, 출시되었기 때문입니다. 이 논쟁은 하나의 기질을 담은 창립 문서로 기억됩니다. 이론은 실제로 돌아가는 시스템 앞에서 진다는 것입니다.

업적

Linux 커널 (1991-): 규모를 감당한 모놀리스

래리 어윙이 그린 Linux 커널 마스코트 Tux

Linux는 모놀리식 커널입니다. 스케줄러, 메모리 관리자, 파일시스템, 디바이스 드라이버가 모두 하나의 특권 주소 공간에서 돌아갑니다. 타넨바움의 비판이 이론적으로 틀린 것은 아니었습니다 – 모놀리식 드라이버의 결함은 마이크로커널이라면 격리할 수 있는 방식으로 시스템 전체를 무너뜨릴 수 있습니다. 토르발스의 답은 경험적이었습니다. 모놀리스는 더 빨랐고, 작성하기 더 단순했으며, 수천 명의 기여자가 저마다 메시지 전달 프로토콜부터 익히지 않고도 수정할 수 있었습니다. 학술적 논쟁에서 진 그 아키텍처가 배포 전쟁에서 이긴 이유는, 기여의 비용을 낮췄기 때문입니다.

오늘날 이 커널은 지금까지 만들어진 협업 엔지니어링 산출물 가운데 가장 큰 축에 듭니다 – 수천만 줄의 코드에, 릴리스마다 수천 명의 기여자가 참여합니다. 그 규모 중 어느 것도 미리 설계된 것이 아닙니다. 병합된 패치 하나하나가 쌓이면서, 토르발스가 직접 고안해야 했던 개발 모델 아래에서 차곡차곡 누적된 것입니다.

메인테이너 모델: 트리로서의 신뢰

토르발스는 Linux에 들어가는 코드 대부분을 읽지 않습니다. 읽을 수가 없습니다 – 그 양은 한 사람의 능력을 한참 넘어섭니다. 대신 커널은 신뢰의 위계로 다스려집니다. 서브시스템 메인테이너들이 각자의 영역을 책임집니다. 그들은 패치를 검토하고, 자기 트리에 접어 넣은 뒤, 부관(lieutenant)들에게로, 그리고 궁극적으로는 토르발스에게로 풀 리퀘스트를 올려 보냅니다. 토르발스는 자신이 신뢰하는 트리를 병합합니다. 그는 뿌리에 자리한 자비로운 독재자이지만, 그의 진짜 일은 그들이 만들어 내는 모든 줄을 감사하는 것이 아니라 누구를 신뢰할지 가려내는 것입니다.

메인테이너 트리는 하나의 사회적 아키텍처이며, 그것은 현대의 모든 소프트웨어 공급망이 마주하는 바로 그 문제와 정면으로 부딪칩니다. 모든 것을 직접 검증할 수는 없으므로, 신뢰는 가정되는 것이 아니라 구조화되어야 한다는 것입니다. 이것이 저장소가 자기 자신의 신뢰성에 표를 던져서는 안 되는 이유이며, 오픈 소스가 보안 경계가 아닌 이유입니다 – 누군가 들여다보는 책임을 질 때에만 그 많은 눈들이 도움이 됩니다. 그 유명하리만치 직설적인 리뷰가 오가는 메일링 리스트는, 신뢰 트리를 읽을 수 있게 만드는 장치입니다. 결정과 그 근거가 공개되고, 보관되며, 누구에게 귀속되는지가 명확하기 때문입니다.

git (2005): 자료 구조로서의 분산된 신뢰

git log --graph 출력 -- 내용으로 주소가 매겨진 커밋 DAG, 브랜치와 병합, 짧은 SHA 해시가 보이며 특권을 가진 중앙 사본은 없다

수년 동안 커널은 BitKeeper로 개발되었습니다. BitKeeper는 그 제작사가 프로젝트에 무료 사용을 허락한 독점 분산 버전 관리 시스템이었습니다. 2005년, 그 합의가 라이선스 분쟁 속에서 무너졌고, 토르발스는 커널의 작업 흐름을 감당할 수 있는 도구 없이 갑자기 남겨졌습니다.5 그래서 그는 직접 하나를 작성했습니다. git의 첫 커밋은 2005년 4월 7일이었고, 대략 열흘 만에 git은 스스로를 호스팅하며 커널을 관리하고 있었습니다.6

git이 연결 리스트 사례와 동일한 원칙의 표현인 까닭은 그 핵심 자료 구조에 있습니다. git은 차이(diff)를 저장한 뒤 상태를 재구성하지 않습니다. 모든 파일의 모든 버전, 모든 디렉터리 트리, 모든 커밋이 자기 내용의 SHA-1 해시로 이름 붙여진 객체로 저장됩니다 – 내용으로 주소가 매겨지는 저장소(content-addressed store)입니다. 토르발스는 이 해싱이 “보안에 관한 것이었던 적은 한 번도 없다. 그것은 손상을 찾아내기 위한 것이었다”라고 분명히 말합니다.6 신원이 내용입니다. 같은 바이트를 가진 두 파일은 자동으로 같은 객체가 되고, 비트 하나만 뒤집혀도 다른 이름이 만들어져 탐지됩니다. 그리고 “모든 저장소가 같고 동등하기” 때문에, 특권을 가진 중앙 서버가 존재하지 않습니다 – “유일한 진본”이라는 특수한 경우가, “리스트의 머리”라는 특수한 경우가 사라졌던 것과 똑같은 방식으로 사라지는 것입니다.6 분산은 git에 덧붙여진 기능이 아닙니다. 옳은 자료 구조를 고른 데서 비롯된 필연적 귀결입니다.

그 마지막 성질 – 내용으로 주소가 매겨진 커밋들의 변조 불가능한 사슬 – 이야말로 커밋 그래프가 코드를 넘어선 의미를 담을 수 있는 이유이며, 제가 작업 회차를 곧 커밋 메시지로 여기는 이유입니다. 히스토리가 산출물의 부산물이 아니라, 히스토리 자체가 산출물인 것입니다.

방법론

토르발스의 방법론은 증거로 강제되는 실용주의입니다. “말은 싸다. 코드를 보여달라”는, 자기 패치가 무슨 일을 할지 설명하던 누군가에게 커널 메일링 리스트에서 문자 그대로 건넨 답이었습니다.2 설계는 가설이고, 패치는 실험입니다. 코드가 존재하고 돌아가기 전까지 논쟁은 매듭지어지지 않습니다.

그 아래에는, 엔지니어링 판단이 실제로 어디에 깃드는지를 가장 정밀하게 짚은 그의 발언이 자리합니다. “나쁜 프로그래머는 코드를 걱정한다. 좋은 프로그래머는 자료 구조와 그 관계를 걱정한다.”7 연결 리스트 사례는 이 문장을 구체로 빚은 것입니다. 자료 구조가 옳으면, 그 위에서 작동하는 코드는 짧고 분기도 적습니다. 구조가 이미 복잡성을 흡수했기 때문입니다. 자료 구조가 틀리면, 특수한 경우로 그 대가를 영원히 치릅니다 – 나쁜 모델을 땜질하느라 존재하는 if 문들로 말입니다. 코드를 걱정하는 것은 증상을 다루는 일입니다. 자료 구조를 걱정하는 것은 치료입니다.

거버넌스 방법론도 기술적 방법론과 짝을 이룹니다. 자비로운 독재자와 부관들로 이루어진 모델은 자아를 한곳에 모으기 위해서라기보다, 병합 결정을 단일한 취향에 책임지게 하면서도 리뷰 노동을 각 서브시스템에 가장 가까운 사람들에게 분산하기 위해 존재합니다. 그리고 그의 코드 리뷰가 보이는 직설성 – 본인도 나중에 인정했듯 때로는 불필요한 가혹함으로까지 넘어갔던 – 은 같은 뿌리에서 나옵니다. 코드는 옳은지 여부로 판단되지, 누가 썼는지나 얼마나 많은 노력을 담았는지로 판단되지 않습니다. 전달 방식은 그렇지 않았을지언정, 기준만큼은 비개인적이었습니다.

영향의 사슬

그를 빚은 사람들

앤드루 타넨바움과 Minix. Minix는 토르발스가 그 위에서 배운 운영체제이자 그가 넘어서려 한 대상이었습니다. 타넨바움은 그에게 공부할 수 있는 읽기 쉬운 Unix 계열 시스템을 주었고, “LINUX는 시대에 뒤떨어졌다” 논쟁을 통해서는 토르발스가 무엇을 중시하는지를 또렷이 드러낼 만큼 날카로운 대척점을 주었습니다. 만족스러운 아키텍처보다 출시되는 시스템을 택하는 가치 말입니다. (형성기의 영향)4

Unix와 GNU 도구들. Linux는 설계 계보상 하나의 Unix입니다 – 프로세스, 파일, 파이프, 그리고 모든 것이 파일이라는 추상화. 그리고 Linux가 쓸모를 가질 수 있었던 것은, 그 위에서 돌아갈 GNU 프로젝트의 컴파일러, 셸, 유틸리티가 이미 존재했기 때문입니다. 토르발스는 커널이 이렇다 할 일을 하기도 전에 bash와 gcc를 포팅했습니다.3 그는 빠져 있던 한 조각 – 커널 – 을 만들었고, 나머지는 이미 있던 조각들이 하게 두었습니다. 필요한 것은 만들고, 잘 돌아가는 것은 재사용한다는 것입니다. (직접적 영향)

그가 빚은 것들

오픈 소스 세계 전체. Linux는 전 지구적으로 분산된, 자원봉사자와 기업이 뒤섞인 협업체가 가장 큰 규모에서 독점 팀들을 엔지니어링으로 능가할 수 있음을 증명했고, 메인테이너 모델은 큰 오픈 프로젝트를 운영하는 본보기가 되었습니다.

그 이후의 모든 분산 버전 관리 시스템. git은 단지 이기기만 한 것이 아니라 – 토대 자체가 되었습니다. GitHub, GitLab, 그리고 현대의 풀 리퀘스트 작업 흐름은 모두 토르발스가 그 열흘 동안 고른, 내용으로 주소가 매겨지는 분산 모델 위에 세워졌습니다. 자료 구조가 자신을 낳은 긴급 상황보다 오래 살아남은 것입니다.

관통하는 줄기

존 카맥과 토르발스는 정반대의 전공에서 출발해 같은 자리에 다다릅니다. 카맥은 알고리즘과 하드웨어가 한 톨도 낭비 없이 맞물릴 때까지 문제를 쥐어짭니다. 토르발스는 자료 구조가 특수한 경우를 사라지게 만들 때까지 문제를 다시 빚습니다. 둘 다 성능과 우아함을 같은 성질의 양면으로 다루며, 둘 다 실제로 돌아가는 것을 이론이 뒤엎게 두지 않습니다. 이 시리즈를 관통하는 좋은 취향이란 결코 장식을 뜻하지 않습니다. 그것은 손끝으로 느낄 수 있는 올바름을 뜻합니다. (시리즈 연결 고리)

내가 여기서 얻는 것

연결 리스트의 교훈은 제가 가장 자주 손을 뻗는 교훈입니다. 코드가 “첫 번째 것”이나 “빈 경우” 또는 “관리자 사용자”를 처리하려고 if를 돋아낼 때, 그 분기는 대개 자료 모델이 살짝 틀렸다는 자백입니다. 해법은 좀처럼 더 나은 if가 아닙니다. 더 나은 표현이며, 그러고 나면 그 분기가 막으려던 경우가 더 이상 일어날 수 없기에 분기 자체가 필요 없어집니다. 그것이 가능한 가장 값싼 방어입니다. 존재할 수 없는 예외는 처리할 코드도 필요 없으니까요.

두 번째 교훈은 규모에서의 신뢰에 관한 것이며, 제가 지금 몸담고 일하는 세계 – 한 줄 한 줄 직접 쓰지 않은 일을 조율하는 에이전트 시스템 – 에서 가장 크게 작동하는 교훈입니다. 토르발스는 같은 문제를 두 번 풀었습니다. 사회적으로는 누가 책임지는지를 구조화하는 메인테이너 트리로, 기술적으로는 무엇이 일어났는지를 변조 불가능하게 만드는 git의 내용 주소 기반 히스토리로 말입니다. 토르발스가 모든 커널 패치를 읽을 수 없는 것과 마찬가지로, 여러분도 에이전트가 만들어 내는 모든 것을 읽을 수는 없습니다. 그래서 여러분은 그가 한 그대로 합니다 – 신뢰를 구조로 만들고 히스토리를 검증 가능하게 만드는 것입니다. 이것이 바로 제가 취향을 인프라로, 공급망을 공격 표면으로 다루는 이유입니다. 취미에서 커널을 빚어낸 그 규율은, 코드베이스가 쇠퇴하는 대신 가속하게 만드는 규율과 똑같습니다. 구조를 옳게 잡으면, 특수한 경우들이 더 이상 불어나지 않습니다.

자주 묻는 질문

리누스 토르발스가 말하는 코드의 “좋은 취향”이란 무엇입니까?

2016년 TED 인터뷰에서 토르발스는 연결 리스트에서 항목을 삭제하는 두 가지 구현으로 좋은 취향을 정의했습니다. 그가 취향 없다고 부른 버전은 리스트의 머리를 제거하는 것을 특수한 경우로 처리하려고 if 문을 썼고, 그가 좋은 코드라고 부른 버전은 포인터를 가리키는 포인터를 써서 머리가 더 이상 특수한 경우가 아니게 만들었습니다. 그의 요약은 이렇습니다. “때로는 문제를 다른 방식으로 바라보고 다시 작성해서, 특수한 경우가 사라지고 평범한 경우로 바뀌게 만들 수 있습니다. 그게 바로 좋은 코드입니다.”1

리누스 토르발스는 무엇을 만들었습니까?

토르발스는 Linux 커널을 만들었습니다. 그는 1991년 8월 25일 comp.os.minix 뉴스그룹에서 이를 처음 발표했고, Linux 커널은 오늘날 세계에서 가장 널리 배포된 운영체제 커널입니다. 2005년에는 Linux 프로젝트가 독점 도구 BitKeeper에 대한 접근을 잃은 뒤 분산 버전 관리 시스템 git도 만들었습니다. 그는 지금도 Linux 커널의 수석 메인테이너입니다.35

리누스 토르발스는 왜 git을 만들었고, 얼마나 걸렸습니까?

Linux 프로젝트는 2005년의 라이선스 분쟁으로 무료 접근이 끝나기 전까지 독점 분산 버전 관리 시스템 BitKeeper를 사용했습니다. 토르발스는 그 대체물로 git을 작성했는데, 첫 커밋은 2005년 4월 7일이었고 약 열흘 만에 그 도구로 커널을 관리했습니다 – 다만 그 이전에 여러 달에 걸쳐 설계를 곱씹었다고 그는 밝힙니다.56

“말은 싸다. 코드를 보여달라”는 무슨 뜻입니까?

토르발스는 2000년 8월 25일 Linux 커널 메일링 리스트에, 어떤 코드가 무슨 일을 할지에 관한 논의에 대한 직접적인 답으로 이 문장을 올렸습니다.2 이 말은 그의 실용주의를 담고 있습니다. 어떤 접근에 대한 설명은 가설일 뿐이며, 실제로 돌리고 시험할 수 있는, 동작하는 코드가 존재하기 전까지 논쟁은 매듭지어지지 않는다는 것입니다. (참고: 관련 표현인 “충분히 많은 눈이 있으면 모든 버그는 얕다”는 토르발스 본인의 발언이 아니라, 에릭 레이먼드가 정식화한 리누스의 법칙입니다.8)

출처


  1. Linus Torvalds, “The mind behind Linux,” 크리스 앤더슨과의 TED 인터뷰, 2016 (좋은 취향 / 연결 리스트 구간, 약 14:10). TED 트랜스크립트가 클라이언트 측에서 렌더링되기 때문에, 해당 인용문과 포인터를 가리키는 포인터 기법은 강연의 정확한 표현과 타임스탬프를 그대로 재현한 mkirchner/linked-list-good-taste의 주석 달린 소스 해설로 온전히 뒷받침됩니다. 

  2. Linus Torvalds, “Talk is cheap. Show me the code,” Linux Kernel Mailing List에 보낸 메시지, 2000년 8월 25일. 이 문장은 Wikiquote: Linus Torvalds에 정확한 날짜와 출처로 정리되어 있으며, lkml.org/lkml/2000/8/25/132의 LKML 스레드에 보관되어 있습니다. 

  3. Linus Torvalds, “What would you like to see most in minix?” comp.os.minix Usenet 뉴스그룹, 1991년 8월 25일. “그냥 취미예요, gnu처럼 크고 전문적이진 않을 겁니다”라는 발표문입니다. 배경: Tom’s Hardware, “Linux is 34 years old today.” 

  4. “Tanenbaum-Torvalds debate,” Wikipedia. 1992년 “LINUX is obsolete” 스레드, “1970년대로 거대하게 후퇴한 것”, 마이크로커널 대 모놀리식 커널, 토르발스의 “이론적·미학적” 인정. 

  5. “A Git Origin Story,” Linux Journal. 2005년 BitKeeper 라이선스 붕괴와 git의 탄생, 2005년 4월 7일의 첫 커밋. 

  6. “Git turns 20: A Q&A with Linus Torvalds,” The GitHub Blog, 2025. “모든 저장소가 같고 동등하다”, “SHA-1 해시는 보안에 관한 것이었던 적이 한 번도 없다. 그것은 손상을 찾아내기 위한 것이었다”, 약 10일의 타임라인. 

  7. Linus Torvalds, “Bad programmers worry about the code. Good programmers worry about data structures and their relationships,” Linux Kernel Mailing List, 2006년 6월 27일. 

  8. Eric S. Raymond, “The Cathedral and the Bazaar,” 1997. 레이먼드는 “충분히 많은 눈이 있으면 모든 버그는 얕다”라는 리누스의 법칙을 자신의 정식화로 만들어 이름 붙였으며, 그 표현 자체가 아니라 그 바탕에 있는 개발 모델에 대해 토르발스의 공로를 인정했습니다. 

관련 게시물

엔지니어링 철학: 마크 셔틀워스(Mark Shuttleworth)

마크 셔틀워스는 단 하나의 생각 위에 Ubuntu를 세웠습니다 -- 인간을 위한 Linux, 모두를 위한 자유 소프트웨어 -- 그리고 그 뿌리에는 우분투(ubuntu), 즉 타인을 향한 인간애가 있었고, 정해진 시계…

16 분 소요

엔지니어링 철학: Thompson과 Ritchie, 하나를 제대로 하라

Thompson과 Ritchie는 하나의 보편적 인터페이스, 즉 텍스트 스트림과 파이프로 엮인 작고 날카로운 도구들로 Unix와 C를 만들었습니다. 기능보다 단순함입니다.

12 분 소요

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

11 분 소요