각 셀에 색을 지정해보자!
지난번에는 일단 그리드를 그렸지만 빨간 단색으로 채워졌었다.
해당 부분을 조금 변경하여서, 색을 다채롭게 칠해보자.
@fragment
fn fragmentMain() -> @location(0) vec4f {
return vec4f(1, 0, 0, 1);
}
위 코드에서 각 프레그먼트에 반환되는 컬라값으로 #FF0000를 넘기고 있기 때문에 전부 빨간 사각형으로 채워졌었다.
색을 다채롭게 하기 위해서는 생각보다 간단하다고 하는데, @vertex 부분에서 렌더링 중인 셀을 알고있으므로 @fragment 단계에 값을 전달만 하면 된다고 한다.
일단, 최종 코드를 먼저 보면 다음과 같다.
struct VertexOutput {
@builtin(position) position: vec4f,
@location(0) cell: vec2f,
};
@group(0) @binding(0) var<uniform> grid: vec2f;
@vertex
fn vertexMain(@location(0) position: vec2f,
@builtin(instance_index) instance: u32) -> VertexOutput {
let i = f32(instance);
let cell = vec2f(i % grid.x, floor(i / grid.x));
let cellOffset = cell / grid * 2;
let gridPos = (position+1) / grid - 1 + cellOffset;
var output: VertexOutput;
output.position = vec4f(gridPos, 0, 1);
output.cell = cell;
return output;
}
@fragment
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
let c = input.cell / grid;
return vec4f(c, 1-c.x, 1);
}
VertexOutput 이라는 구조체가 추가되었고,
fragment에서 반환값에 각 셀마다 주는 색상값이 셀별로 다르게 연산되어 처리되고 있으며, VertexOutput을 넘겨주고 있다.
일단 해당 결과물은 다음과 같이 렌더링 되어서 추출된다.
중간 과정을 거쳐서, 코드를 조금씩 해석해보자!
먼저, @fragment 부분을 다음과 같이 작성 하였을 때의 결과값을 확인해보자.
@fragment
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
return vec4f(input.cell, 0, 1);
}
위과 같이 작성하게 되면, 아래와 같은 결과물이 나오게 된다.
먼저 return 되는 값만 일부 변경되었는데, 기존에 (r:1,g:0,b:0,a:1) 을 넘겨주다가, r,g 값에 VertexOutput인 2차 배열을 넘겨주고 있다.
@vertex쪽의 코드를 보면, outupt.cell의 값에는 vec2f( i % grid.x, floor(i/grid.x)) 값이 지정되어 넘겨지고 있다.
현재 grid가 32*32로 되어있으므로, (0,0) 부터 (31,31) 까지의 값이 넘어가게 될 것이다.
따라서, 좌측 가장 하단의 셀은 (0, 0, 0, 1) 값이 넘겨지게 되어 검은 색이 출력되게 되고
이외 하단 행은 (1, 0, 0, 1) 값이 넘어가서 빨간색이,
첫번째 열의 경우에는 (0, 1, 0, 1) 이 넘어가면서 초록색이,
나머지 셀의 경우에는 (1~31, 1~31, 0, 1) 이 넘어가면서 노란색이 (1 이상의 값은 1으로 처리된다) 출력되게 된다.
최종 코드로 돌아가서 분석해 보자!
@fragment
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
let c = input.cell / grid;
return vec4f(c, 1-c.x, 1);
}
마지막으로 최종코드를 살펴보면, input.cell을 grid 값으로 나눠주고 있다.
grid 값은 (32,32)로 지정되어있으니,
좌측 최 하단 셀의 생상 코드는 다음과 같다. (0/32, 0/32, 1 - 0, 1)
(0,0,1,1) 이므로, 파란색이 랜더링 되게 된다.
우측으로 가면서, R값이 올라가게 되므로. input.cell 의 값이 만약 (16,0) 이라면
(0.5, 0, 0.5, 1) 의값 으로 보라색이 나오게 되고 점차 빨간색으로 변경된다.
'JAVASCRIPT > vanilla' 카테고리의 다른 글
[javascript] DOM 변화를 관측하여 observer 패턴 사용 (0) | 2023.11.02 |
---|---|
WebGPU(3) - bindGroup (0) | 2023.05.16 |
WebGPU(2) - draw rect (0) | 2023.05.16 |
WebGPU(1) - 개념과 캔버스 초기화 (1) | 2023.05.16 |