여러 물체가 겹쳐 있을때 뭘 위에 그릴까?
depth buffer 라는 것을 만들어서 depth가 얕은것만 그리면 된다.
https://knowww.eu/nodes/59b8e93cd54a862e9d7e4165
Depth buffer (z-buffer)
Description The depth buffer is used to determine visibility, that is, which primitives in the scene are visible to the camera, and which are occluded by other primitives. This is an example of hidden surface removal. The depth buffer, or z-buffer, is si
knowww.eu
depth buffer (z-buffer)
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);
}
}