通过使用glm::vec4将使用光线追踪原理显示的"粉色圆形"多彩化,显示更为立体:
glm::vec4 Renderer::PerPixel(glm::vec2 coord)
{
glm::vec3 rayOrigin(0.0f, 0.0f, 2.0f);
glm::vec3 rayDirection(coord.x, coord.y, -1.0f);
float radius = 0.5f;
// rayDirection = glm::normalize(rayDirection);
// (bx^2 + by^2)t^2 + (2(axbx + ayby))t + (ax^2 + ay^2 - r^2) = 0
// where
// a = ray origin
// b = ray direction
// r = radius
// t = hit distance
//float a = coord.x * coord.x + coord.y * coord.y + coord.z * coord.z;
float a = glm::dot(rayDirection, rayDirection);
float b = 2.0f * glm::dot(rayOrigin, rayDirection);
float c = glm::dot(rayOrigin, rayOrigin) - radius * radius;
// Quadratic formula discriminant:
// b^2 - 4ac
float discriminant = b * b - 4.0f * a * c;
if (discriminant < 0.0f)
{
return glm::vec4(0, 0, 0, 1);
}
// (-b +- sqrt(discriminant)) / 2a
float t0 = (-b + glm::sqrt(discriminant)) / (2.0f * a);
float closestT = (-b - glm::sqrt(discriminant)) / (2.0f * a);
//glm::vec3 h0 = rayOrigin + rayDirection * t0;
glm::vec3 hitPoint = rayOrigin + rayDirection * closestT;
glm::vec3 sphereColor(1, 0, 1);
sphereColor = hitPoint;
return glm::vec4(sphereColor, 1.0f); // 0xff000000
}
在人们的视图原理中,眼睛通过接收光线来形成图形视图,当我们旋转物体时,迎光的一面会显得更亮,背光的一面会显得更暗,我们通常会定义一个法线向量(normal vector)来对物体的方向和角度的定义。
修改如下代码,使用glfm图形库进行法线向量的使用:
//glm::vec3 h0 = rayOrigin + rayDirection * t0;
glm::vec3 hitPoint = rayOrigin + rayDirection * closestT;
glm::vec3 normal = glm::normalize(hitPoint);
glm::vec3 sphereColor(1, 0, 1);
sphereColor = normal;
return glm::vec4(sphereColor, 1.0f); // 0xff000000
显示如图:
可以看到亮度变得很高了。因为是正对点光源的。
更改rayOrigin的位置,再运行程序:
glm::vec3 rayOrigin(0.0f, 0.0f, 1.0f);
glm::vec3 rayDirection(coord.x, coord.y, -1.0f);
float radius = 0.5f;
显示如下:
球形看起来大了很多,那么应该是距离摄像机距离更近了,相对看起来就显得更大。
在进行法向量的显示修改
glm::vec3 sphereColor(1, 0, 1);
sphereColor = normal * 0.5f + 0.5f;
return glm::vec4(sphereColor, 1.0f); // 0xff000000
显示如图:
渲染出来的球形对比度降低了,摄像机的蓝光范围更小,光圈更大,上面的天蓝色光和右边的紫光也光圈更大,
更换成一个光源,让光影感更加好一些:
glm::vec3 lightDir = glm::normalize(glm::vec3(-1, -1, -1));
float d = glm::max(glm::dot(normal, -lightDir), 0.0f); // == cos(angle)
glm::vec3 sphereColor(1, 0, 1);
sphereColor *= d;
return glm::vec4(sphereColor, 1.0f); // 0xff000000
显示如下:
这样显示出来的球形有一些写实风格了,虽然还是很假,右上到左下逐渐变暗。
电脑不好,可以看到有右上角显示的渲染速率,只有5,6帧每秒,因为完全使用cpu运行程序,又是使用的vulkan库,对电脑要求很高。