여러 물체가 겹쳐 있을때 뭘 위에 그릴까?
depth buffer 라는 것을 만들어서 depth가 얕은것만 그리면 된다.
https://knowww.eu/nodes/59b8e93cd54a862e9d7e4165
void Rasterization::DrawIndexedTriangle(const size_t &startIndex,
vector<vec4> &pixels) {
const size_t i0 = this->indexBuffer[startIndex];
const size_t i1 = this->indexBuffer[startIndex + 1];
const size_t i2 = this->indexBuffer[startIndex + 2];
const auto v0 = ProjectWorldToRaster(this->vertexBuffer[i0]);
const auto v1 = ProjectWorldToRaster(this->vertexBuffer[i1]);
const auto v2 = ProjectWorldToRaster(this->vertexBuffer[i2]);
const auto &c0 = this->colorBuffer[i0];
const auto &c1 = this->colorBuffer[i1];
const auto &c2 = this->colorBuffer[i2];
const auto xMin = size_t(glm::clamp(
glm::floor(std::min({v0.x, v1.x, v2.x})), 0.0f, float(width - 1)));
const auto yMin = size_t(glm::clamp(
glm::floor(std::min({v0.y, v1.y, v2.y})), 0.0f, float(height - 1)));
const auto xMax = size_t(glm::clamp(glm::ceil(std::max({v0.x, v1.x, v2.x})),
0.0f, float(width - 1)));
const auto yMax = size_t(glm::clamp(glm::ceil(std::max({v0.y, v1.y, v2.y})),
0.0f, float(height - 1)));
for (size_t j = yMin; j <= yMax; j++) {
for (size_t i = xMin; i <= xMax; i++) {
const vec2 point = vec2(float(i), float(j));
const float alpha0 = EdgeFunction(v1, v2, point);
const float alpha1 = EdgeFunction(v2, v0, point);
const float alpha2 = EdgeFunction(v0, v1, point);
if (alpha0 >= 0.0f && alpha1 >= 0.0f && alpha2 >= 0.0f) {
const float area = alpha0 + alpha1 + alpha2;
const vec3 color =
(alpha0 * c0 + alpha1 * c1 + alpha2 * c2) / area;
// 정투영(orthographic projection)에서만 정확합니다.
// 뒤에서 Perspective Correct Interpolation으로 보정
//TODO: Bary-centric coordinates를 이용해서 z 좌표 찾기
//const float depth = ...;
const float z0 = this->vertexBuffer[i0].z;
const float z1 = this->vertexBuffer[i1].z;
const float z2 = this->vertexBuffer[i2].z;
const float depth =
(alpha0 * z0 + alpha1 * z1 + alpha2 * z2) / area;
//TODO: 조건 추가
if (depth < depthBuffer[i + width * j]) {
//TODO: 깊이 버퍼 업데이트
pixels[i + width * j] = vec4(color, 1.0f);
depthBuffer[i + width * j] = depth;
}
}
}
}
}
void Rasterization::Render(vector<vec4> &pixels) {
// 깊이 버퍼 초기화
this->depthBuffer.resize(pixels.size());
//TODO: 깊이 버퍼의 값도 초기화해줘야 합니다.
// std::fill() 사용
//this->depthBuffer.
std::fill(this->depthBuffer.begin(), this->depthBuffer.end(), 1.0f);
// 뒷쪽의 원을 나중에 그리기
this->vertexBuffer.resize(circle1.vertexBuffer.size());
for (size_t i = 0; i < circle1.vertexBuffer.size(); i++) {
this->vertexBuffer[i] = circle1.vertexBuffer[i] + center1;
}
this->indexBuffer = circle1.indexBuffer;
this->colorBuffer = circle1.colorBuffer;
// 현재 버퍼로 삼각형 하나씩 그리기 (아래 for루프는 여러번 사용됨)
for (size_t i = 0; i < this->indexBuffer.size(); i += 3) {
DrawIndexedTriangle(i, pixels);
}
this->vertexBuffer.resize(circle2.vertexBuffer.size());
for (size_t i = 0; i < circle2.vertexBuffer.size(); i++) {
this->vertexBuffer[i] = circle2.vertexBuffer[i] + center2;
}
this->indexBuffer = circle2.indexBuffer;
this->colorBuffer = circle2.colorBuffer;
for (size_t i = 0; i < this->indexBuffer.size(); i += 3) {
DrawIndexedTriangle(i, pixels);
}
this->vertexBuffer.resize(circle3.vertexBuffer.size());
for (size_t i = 0; i < circle3.vertexBuffer.size(); i++) {
this->vertexBuffer[i] = circle3.vertexBuffer[i] + center3;
}
this->indexBuffer = circle3.indexBuffer;
this->colorBuffer = circle3.colorBuffer;
for (size_t i = 0; i < this->indexBuffer.size(); i += 3) {
DrawIndexedTriangle(i, pixels);
}
}