遍历三角形-对每个三角形逐像素遍历-直线和三角形求交判断点是不是在三角形内-着色
代码如下:
void rasterize(Image& image, const Scene& scene, const Camera& camera) {
const int w = image.width();
const int h = image.height();
DepthBuffer depthBudder(w.h, INFINITY);
for (unsigened int t = 0; t < scene.triangleArray.size(); i++) //遍历场景中的三角形数组
{
const Triangle& T = scene.triangleArray[t];
const int x0 = 0;
const int x1 = w;
const int y0 = 0;
const int y1 = h;
//遍历像素
for (int y = y0; y < y1; y++)
{
for (int x = x0; x < x1; x++)
{
const Ray& R = computeEyeRay(x, y, w, h, camera); //计算穿过像素(x,y)中心的射线
Radiance3 L_o;
float distance = depthBuffer.get(x, y);//获得当前像素的深度
if (sampleRayTriangle(scene, x, y, R, T, L_o, distance)) //一根光线对一个三角形进行求交和着色
{
image.set(x, y, L_O);
depthBuffer.set(x, y, distance);
}
}
}
}
}
bool sampleRayTriangle(const Scene& scene, int x, int y, const Ray& R, const Triangle& T, Radiance3& radiance, float& distance)
{
float weight[3];
const float d = intersect(R, T, weight);//光线三角形求交
if (d >= distacne) {
return false;
}
distance = d;
const Point3& p = R.origin() + R.direction() * d;
const Vector3& n = (T.normal(0) * weight[0] +
T.normal(1) * weight[1] +
T.normal(2) * weight[2]).direction();
const Vector3& w_o = -R.direction();
shade(scene, T, P, n, w_o, radiance);
return true;
}
float intersect(const Ray& R, const Triangle& T, float weight[3]) { //求交
const Vector3& e1 = T.vertex(1) - T.vertex(0); //V0到V1的边向量
const Vector3& e2 = T.Vertex(2) - T.vertex(0); //V0到V2的边向量
const Vector3& q = R.direction().cross(e2); //向量q垂直于e2和光线
const float a = e1.dot(q);
const Vector3& s = R.origin() - T.vertex(0); //光线起始点到V0的位移向量
const Vector3& r = s.cross(e1); //s和e1的叉积
weight[1] = s.dot(q) / a;
weight[2] = R.direction().dot(r) / a;
weight[0] = 1.0f - (weight[1] + weight[2]);
const float dist = e2.dot(r) / a;
static const float epsilon = le - 7f;
static const float epsilon2 = le - 10;
if ((a <= epsilon) || (weight[0] < -epsilon2) || (weight[1] < -epsilon2) || (weight < -epsilon2) || (dist <= 0.0f))
{
return INFINITY;
}
else
{
return dist;
}
}
void shade(const Scene& scene, const Triangle& T, const Point3& P, const Vector3& n, const Vector3& w_o, Radiance3* L_o) { //着色
L_0 = Color3(0.0f, 0.0f, 0.0f);
for (unsigned int i = 0; i < scene.lightArray.size(); ++i) {
const Light& light = scene.lightArray[i];
const Vector3& offset = light.position - P;
const float distanceToLight = offset.length();
const Vector3& w_i = offset / distanceToLight;
if (visible(P, w_i, distanceToLight, scene)) {
const Radiance3& L_i = light.power / (4 * PI * square(distanceToLight));
L_o += L_i * T.bsdf().evaluateFiniteScatteringDensity(w_i, w_o) * max(0.0, dot(w_i, n));
}
}
}