0.簡介
之前就顧着一直寫來着,中途出現了一些小問題,這裏簡單總結一下。
1.盒體繪製
這裏後來我繪製了一個箱子,結果出現了神奇的問題,找了很久發現,是在計算箱子最近平面的時候找到平面就返回了,沒有判斷最小距離。所以做了新的補丁。
Ray Triangles::intersect(Ray ray)
{
//一束光線只能在同一時間打在這個物體的一個位置上
float min = FLT_MAX;
Ray ret;
for (int i = 0; i < triangles.size(); i++)
{
//光線打在物體上,返回的是光線到物體的信息
Ray r = triangles[i].intersect(ray);
if (r.polygon != nullptr && r.distance < min)
{
min = r.distance;
ret = r;
//return r;
}
}
if (ret.polygon != nullptr)
return ret;
return Ray(ray.direction, ray.position, ray.intensity, ray.color, nullptr);
}
盒子繪製還有一個問題,就是面顯示錯誤,這是頂點信息輸入錯誤導致的,其實上一篇博客中的圖片就能看出來,只不過箱子透明,不明顯。
修改後如下
Triangle tr0 = Triangle(vec5(vec3(-5, 5, 5), vec2(0, 1)), vec5(vec3(-5, -5, 5), vec2(0, 0)), vec5(vec3(5, -5, 5), vec2(1, 0)), &m3);
Triangle tr1 = Triangle(vec5(vec3(5, -5, 5), vec2(1, 0)), vec5(vec3(5, 5, 5), vec2(1, 1)), vec5(vec3(-5, 5, 5), vec2(0, 1)), &m3);
Triangle tr2 = Triangle(vec5(vec3(-5, -5, 5), vec2(1, 0)), vec5(vec3(-5, 5, 5), vec2(1, 1)), vec5(vec3(-5, -5, -5), vec2(0, 0)), &m3);
Triangle tr3 = Triangle(vec5(vec3(-5, -5, -5), vec2(0, 0)), vec5(vec3(-5, 5, 5), vec2(1, 1)), vec5(vec3(-5, 5, -5), vec2(0, 1)), &m3);
Triangle tr4 = Triangle(vec5(vec3(5, 5, 5), vec2(0, 1)), vec5(vec3(5, -5, 5), vec2(0, 0)), vec5(vec3(5, -5, -5), vec2(1, 0)), &m3);
Triangle tr5 = Triangle(vec5(vec3(5, 5, 5), vec2(0, 1)), vec5(vec3(5, -5, -5), vec2(1, 0)), vec5(vec3(5, 5, -5), vec2(1, 1)), &m3);
Triangle tr6 = Triangle(vec5(vec3(5, 5, -5), vec2(0, 1)), vec5(vec3(5, -5, -5), vec2(0, 0)), vec5(vec3(-5, 5, -5), vec2(1, 1)), &m3);
Triangle tr7 = Triangle(vec5(vec3(-5, 5, -5), vec2(1, 1)), vec5(vec3(5, -5, -5), vec2(0, 0)), vec5(vec3(-5, -5, -5), vec2(1, 0)), &m3);
Triangle tr8 = Triangle(vec5(vec3(5, 5, 5), vec2(1, 1)), vec5(vec3(5, 5, -5), vec2(1, 0)), vec5(vec3(-5, 5, 5), vec2(0, 1)), &m3);
Triangle tr9 = Triangle(vec5(vec3(-5, 5, 5), vec2(0, 1)), vec5(vec3(5, 5, -5), vec2(1, 0)), vec5(vec3(-5, 5, -5), vec2(0, 0)), &m3);
Triangle tr10 = Triangle(vec5(vec3(5, -5, 5), vec2(0, 0)), vec5(vec3(-5, -5, 5), vec2(1, 0)), vec5(vec3(5, -5, -5), vec2(0, 1)), &m3);
Triangle tr11 = Triangle(vec5(vec3(-5, -5, 5), vec2(1, 0)), vec5(vec3(-5, -5, -5), vec2(1, 1)), vec5(vec3(5, -5, -5), vec2(0, 1)), &m3);
然後箱子旋轉的時候,出現了紋理扭曲,觀察了一下現象,發現是變換矩陣乘法用法不對。
做了如下修改
void Triangle::move()
{
wA = A.position*transforms + position;
wB = B.position*transforms + position;
wC = C.position*transforms + position;
//更新法向量
normal = normalize(cross(wA.position - wB.position, wB.position - wC.position));
//更新平面參數
normal_distance = dot(normal, wA.position);
}
2.添加
爲了能更方便看各個角度,添加了新的類,專門根據角度生成旋轉矩陣的。旋轉原理是歐拉角。
class EulerAngle
{
public:
EulerAngle();
mat3 operator()(vec3 angle);
~EulerAngle();
};
mat3 EulerAngle::operator()(vec3 angle)
{
vec3 radian(angle.x*3.141592654/180, angle.y * 3.141592654 / 180, angle.z * 3.141592654 / 180);
return mat3(vec3(1, 0, 0), vec3(0, cos(radian.x), -sin(radian.x)), vec3(0, sin(radian.x), cos(radian.x))) *
mat3(vec3(cos(radian.y), 0, sin(radian.y)), vec3(0, 1, 0), vec3(-sin(radian.y), 0, cos(radian.y))) *
mat3(vec3(cos(radian.z), -sin(radian.z), 0), vec3(sin(radian.z), cos(radian.z), 0), vec3(0, 0, 1));
}
這就可以看到旋轉效果了。
還有一處就是時間計算
cout << (end - start)/ CLOCKS_PER_SEC << "s" << endl;
3.效果
牆面和地面都換成了高清紋理,牆面我不想用這個,但是紋理太大沒下載完,暫時用這個吧。