Skip to content

Commit 5d30516

Browse files
authored
Merge pull request #6859 from ienground/patch-2
[p5.js KO] Create webgl_contribution_guide.md
2 parents 7c786e4 + 5638183 commit 5d30516

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# WebGL 기여 안내
2+
3+
여러분이 이 페이지를 읽고 있다면, 아마도 WebGL 모드에서의 작업에 도움을 주고 싶으신 것이겠죠? 여러분의 기여에 다시 한 번 감사의 말씀을 드립니다. 이 페이지에서는 WebGL 기여가 어떻게 구성되었는지를 설명하고, 변경사항을 만들기 위한 몇 가지 팁을 제공합니다.
4+
5+
## 참고 자료
6+
7+
- p5.js의 WebGL 모드가 기반으로 하고 있는 WebGL 모드가 2D 모드와 어떻게 다른지 이해하려면 [p5.js WebGL 모드 아키텍쳐](webgl_mode_architecture.md)를 읽어보세요. 셰이더, 선 등에 대한 몇 가지 구현 세부 사항에 대한 가치 있는 자료가 됩니다.
8+
- 문제 생성, 코드베이스(codebase, 원천 코드 모음) 설정, 변경 사항 테스트에 대한 정보가 필요하다면 [기여자 가이드라인](https://p5js.org/contributor-docs/#/./contributor_guidelines)을 읽어보세요.
9+
- 브라우저의 WebGL API에 대해 조금 알아두면 도움이 될 수 있는데,
10+
- [WebGL fundamentals](https://webglfundamentals.org/)에서 많은 핵심 렌더링 개념에 대해 검토할 수 있습니다.
11+
- [The Book of Shaders](https://thebookofshaders.com/)에 WebGL 셰이더에서 사용되는 많은 기술들이 설명되어 있습니다.
12+
13+
## 계획
14+
15+
[깃허브(GitHub) 프로젝트](https://github.com/orgs/processing/projects/5)에 게시된 이슈(issue)를 정리하고 다음과 같은 몇 가지 유형으로 나누었습니다.
16+
17+
- **시스템 차원 변경사항 (System-level changes)** 란 코드에 광범위한 영향을 미치는 장기적 목표입니다. 이것은 실행에 옮기기 전 수많은 논의와 계획을 필요로 합니다.
18+
- **아직 해결책이 없는 버그 (Bugs with no solution yet)** 란 원인을 줄이기 위한 약간의 디버깅이 필요한 버그 신고입니다. 아직 해결될 준비가 되어 있지 않으며, 원인이 발견되면 이를 고치기 위한 최고의 해결책을 논의할 수 있게 됩니다.
19+
- **해결책이 있지만 PR이 없는 버그 (Bugs with solutions but no PR)** 는 어떻게 해결할 지 결정되었으며 누구나 자유롭게 코드를 작성할 수 있습니다.
20+
- **경미한 개선 (Minor enhancements)** 이란 현재의 아키텍쳐 내에서 확실한 위치를 가지는 새로운 기능에 대한 이슈이며, 어떻게 맞출 것인지에 대한 논의를 하지 않아도 됩니다. 일단 이러한 기능이 가치가 있다고 동의하면, 이를 위한 코드를 자유롭게 작성할 수 있습니다.
21+
- **2D 기능 (2D features)** 이란 p5.js에는 있지만 WebGL 모드에는 없는 기능입니다. 이 기능은 2D 모드의 동작과 일치하는 결과물이 구현될 것으로 예상됩니다. 최적의 구현에 대해 논의할 필요가 있지만, 이에 대한 사용자 요구 사항은 명확합니다.
22+
- **모든 환경에서 작동하지 않는 기능 (Features that don't work in all contexts )** 이란 WebGL 모드에 존재하지만 WebGL 모드를 사용할 수 있는 모든 방식으로 작동하지는 않는 기능입니다. 예를 들어, 일부 p5.js의 메소드는 2D 좌표계와 3D 좌표계에서 모두 작동하지만, 다른 메소드는 3D 좌표계에서 사용하면 중단될 수도 있습니다. 보통은 자유롭게 이 기능에 대한 작업을 시작할 수 있습니다.
23+
- **기능 요청 (Feature requests)** 이란 다른 모든 코드 변경 요청을 말합니다. 이 요청이 WebGL 모드의 지침에 맞는 것인지 확인하기 위해서는 약간의 논의가 필요합니다.
24+
- **문서화 (Documentation)** 이슈는 코드 변경이 필요하지 않지만, 대신 p5.js의 동작을 위해 더 잘 문서화하는 것이 필요한 이슈입니다.
25+
26+
## 코드를 어디에 넣어야 하나요?
27+
28+
WebGL과 관련된 모든 것은 `src/webgl` 하위 디렉토리에 있습니다. 해당 디렉토리 내에서, 최상위 p5.js 기능은 조명을 설정하는 명령어는 `lighting.js`로, 재질을 설정하는 명령어는 `materials.js`로 주제 영역에 따라 여러 파일로 나뉘었습니다.
29+
30+
사용자 지향 클래스를 구현할 때, 일반적으로 클래스당 한 파일로 만드려고 노력하고 있습니다. 이러한 파일들은 때때로 다른 몇 개의 내부 보조 기능(utility) 클래스를 가질 수 있습니다. 예를 들어, `p5.Framebuffer.js``p5.Framebuffer` 클래스를 포함하고, 추가로 다른 메인 클래스의 몇 가지 프레임버퍼 관련 하위 클래스로 구성됩니다. 이 파일에는 추가적인 프레임버퍼 관련 하위 클래스도 들어갈 수 있습니다.
31+
32+
`p5.RendererGL`은 많은 동작을 처리하는 대형 클래스입니다. 이 때문에 하나의 대형 클래스 파일이 있는 것이 아닌, 어떤 주제 영역인지에 따라 여러 개의 파일로 나누었습니다. `p5.RendererGL`을 분할한 파일과, 각 파일에 무엇이 있는지는 다음과 같습니다.
33+
34+
35+
#### `p5.RendererGL.js`
36+
37+
초기화 및 핵심 기능
38+
39+
40+
#### `p5.RendererGL.Immediate.js`
41+
42+
**즉시 모드 (immediate mode)** 드로잉(`beginShape()``endShape()`와 같은, 보관 및 재사용되지 않을 모양)과 관련된 기능
43+
44+
45+
#### `p5.RendererGL.Retained.js`
46+
47+
**보류 모드 (retained mode)** 드로잉(`sphere()`와 같은, 재사용을 위해 저장된 모양)과 관련된 기능
48+
49+
#### `material.js`
50+
51+
혼합 모드 관리
52+
53+
#### `3d_primitives.js`
54+
55+
`triangle()`과 같이 도형을 그리는 사용자 지향 함수. 이 함수들은 도형의 기하학적 구조를 정의합니다. 그런 다음 도형의 렌더링은 `p5.RendererGL.Retained.js` 또는 `p5.RendererGL.Immediate.js`에서 발생하며, 형상 입력을 일반 모양으로 취급합니다.
56+
57+
#### `Text.js`
58+
59+
글자 렌더링을 위한 기능 및 보조 기능 클래스
60+
61+
62+
## WebGL 변경사항 테스트
63+
64+
### 일관성 테스트
65+
66+
p5.js의 함수를 사용할 수 있는 방법은 여러 가지가 있습니다. 모든 것을 수동으로 확인하는 것은 어려우므로, 가능한 곳에 단위 테스트(unit test)를 추가합니다. 그래야 새로운 변경점이 생겨도 단위 테스트를 통과한다면 아무 문제가 발생되지 않았다고 더 확신할 수 있기 때문입니다.
67+
68+
새 테스트를 추가할 때, 기능이 2D 모드에서도 작동하는 경우 일관성을 확인하는 최고의 방법 중 하나는 픽셀 결과물이 두 모드에서 동일한지를 확인하는 것입니다. 다음은 단위 테스트의 예시 중 하나입니다.
69+
70+
71+
```js
72+
test('coplanar strokes match 2D', function() {
73+
const getColors = function(mode) {
74+
myp5.createCanvas(20, 20, mode);
75+
myp5.pixelDensity(1);
76+
myp5.background(255);
77+
myp5.strokeCap(myp5.SQUARE);
78+
myp5.strokeJoin(myp5.MITER);
79+
if (mode === myp5.WEBGL) {
80+
myp5.translate(-myp5.width/2, -myp5.height/2);
81+
}
82+
myp5.stroke('black');
83+
myp5.strokeWeight(4);
84+
myp5.fill('red');
85+
myp5.rect(10, 10, 15, 15);
86+
myp5.fill('blue');
87+
myp5.rect(0, 0, 15, 15);
88+
myp5.loadPixels();
89+
return [...myp5.pixels];
90+
};
91+
assert.deepEqual(getColors(myp5.P2D), getColors(myp5.WEBGL));
92+
});
93+
```
94+
95+
2D 모드에서 안티앨리어싱(계단 현상 방지 기술, antialiasing)을 끌 수 없고, WebGL 모드에서 안티앨리어싱은 종종 약간 다르기 때문에 항상 이 코드가 작동하지는 않습니다. 하지만 x축 및 y축 상의 직선에 대해서는 작동합니다.
96+
97+
만약 어떤 기능이 WebGL 전용이라면 2D 모드와 픽셀 결과물을 비교하기보다는 몇 가지 픽셀을 확인해서 그 색상이 예상한 색상인지 확인하는 경우가 많습니다. 언젠가는 이를 몇 가지 픽셀이 아닌 예상 결과물의 전체 이미지 스냅샷을 비교하는 보다 강력한 시스템으로 전환할 수도 있겠지만, 현재로서는 픽셀 색상을 확인하는 예시가 있습니다.
98+
99+
```js
100+
test('color interpolation', function() {
101+
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);
102+
// upper color: (200, 0, 0, 255);
103+
// lower color: (0, 0, 200, 255);
104+
// expected center color: (100, 0, 100, 255);
105+
myp5.beginShape();
106+
myp5.fill(200, 0, 0);
107+
myp5.vertex(-128, -128);
108+
myp5.fill(200, 0, 0);
109+
myp5.vertex(128, -128);
110+
myp5.fill(0, 0, 200);
111+
myp5.vertex(128, 128);
112+
myp5.fill(0, 0, 200);
113+
myp5.vertex(-128, 128);
114+
myp5.endShape(myp5.CLOSE);
115+
assert.equal(renderer._useVertexColor, true);
116+
assert.deepEqual(myp5.get(128, 128), [100, 0, 100, 255]);
117+
});
118+
```
119+
120+
121+
### 성능 테스트
122+
123+
p5.js가 가장 걱정하는 부분은 아니지만, 변경점이 성능을 크게 저하하지 않도록 노력하고 있습니다. 보통 변경사항이 적용된 것과 변경사항이 적용되지 않은 것, 두 개의 테스트 스케치를 생성해서 이루어지고 있습니다. 그런 다음 두 프레임 속도를 비교합니다.
124+
125+
성능 측정에 대한 몇 가지 조언을 드리자면,
126+
127+
- 스케치 상단에서 `p5.disableFriendlyErrors = true`로 친절한 오류를 비활성화해 보세요. (또는 친절한 오류 메시지가 들어 있지 않은 `p5.min.js`를 테스트해보세요)
128+
- 안정적인 프레임 속도를 명확하게 파악하기 위해 평균 프레임 속도를 표시해 보세요.
129+
130+
```js
131+
let frameRateP;
132+
let avgFrameRates = [];
133+
let frameRateSum = 0;
134+
const numSamples = 30;
135+
function setup() {
136+
// ...
137+
frameRateP = createP();
138+
frameRateP.position(0, 0);
139+
}
140+
function draw() {
141+
// ...
142+
const rate = frameRate() / numSamples;
143+
avgFrameRates.push(rate);
144+
frameRateSum += rate;
145+
if (avgFrameRates.length > numSamples) {
146+
frameRateSum -= avgFrameRates.shift();
147+
}
148+
149+
frameRateP.html(round(frameRateSum) + ' avg fps');
150+
}
151+
```
152+
153+
렌더링 파이프라인의 여러 부분에 스트레스를 주기 때문에 테스트를 해야 하는 다음과 같은 경우가 있습니다.
154+
155+
- 몇 가지의 매우 복잡한 모양 (예: 대용량의 3D 모델이나 긴 곡선)
156+
- 많은 수의 단순한 모양 (예: for 반복문에서 여러 번 호출되는 `line()`)

0 commit comments

Comments
 (0)