Browse Source

添加多个物体,修复渲染bug

master
ubuntu20 4 years ago
parent
commit
0a3b6e8475
  1. 21
      Object.h
  2. 33
      Scene.cpp
  3. 8
      Sphere.cpp

21
Object.h

@ -1,7 +1,26 @@
#pragma once #pragma once
#include "Vector3.h" #include "Vector3.h"
class Material; class Material;
class Object {
class LinkedList {
public:
LinkedList* mNext;
LinkedList() {
mNext = nullptr;
}
template<typename T>
T* Next() {
return (T*)mNext;
}
void Append(LinkedList* node) {
if (mNext == nullptr) {
mNext = node;
}
else {
mNext->Append(node);
}
}
};
class Object : public LinkedList{
public: public:
Geometry *mGeometry; Geometry *mGeometry;
Material *mMaterial; Material *mMaterial;

33
Scene.cpp

@ -10,16 +10,17 @@
static int sTotalPixelCount = 0; static int sTotalPixelCount = 0;
static int sViewportWidth = 0, sViewportHeight = 0; static int sViewportWidth = 0, sViewportHeight = 0;
static Camera* sCamera = nullptr; static Camera* sCamera = nullptr;
Sphere sphere(Vector3(0.0f, 0.0f, -5.0f), 0.5f);
Sphere sphere(Vector3(0.0f, 0.5f, 0.0f), 0.5f);
static Object* sRootObject = nullptr; static Object* sRootObject = nullptr;
static Material* lambert = nullptr; static Material* lambert = nullptr;
static int sSampleCount = 64; static int sSampleCount = 64;
static int sMaxBounceTime = 30;
void AddObject(Object* object) { void AddObject(Object* object) {
if (sRootObject == nullptr) { if (sRootObject == nullptr) {
sRootObject = object; sRootObject = object;
} }
else { else {
//TODO
sRootObject->Append(object);
} }
} }
void Init(int width, int height) void Init(int width, int height)
@ -28,7 +29,9 @@ void Init(int width, int height)
sViewportWidth = width; sViewportWidth = width;
sViewportHeight = height; sViewportHeight = height;
sCamera = new Camera(45.0f, float(width) / float(height)); sCamera = new Camera(45.0f, float(width) / float(height));
sCamera->LookAt(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 1.0f, 0.0f));
sCamera->LookAt(Vector3(3.0f, 1.0f, 3.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f));
Material* earth_material = new LamberMaterial(Vector3(0.5f, 0.3f, 0.1f));
AddObject(new Object(new Sphere(Vector3(0.0f, -1000.0f, 0.0), 1000.0f), earth_material));
lambert = new LamberMaterial(Vector3(0.1f, 0.4f, 0.7f)); lambert = new LamberMaterial(Vector3(0.1f, 0.4f, 0.7f));
AddObject(new Object(&sphere, lambert)); AddObject(new Object(&sphere, lambert));
} }
@ -50,16 +53,28 @@ Vector3 GetEnviromentColor(const Ray& input_ray) {
return factor * top_color + (1.0f - factor) * bottom_color; return factor * top_color + (1.0f - factor) * bottom_color;
} }
Vector3 GetColor(const Ray& input_ray) {
Vector3 RenderOneSample(const Ray& input_ray, int bounce_time) {
HitPoint hit_point; HitPoint hit_point;
if (sRootObject->HitTest(input_ray, 0.01f, 100.0f, hit_point)) {
float max_distance = 1000.0f;
Object* current_object = sRootObject;
Object* hitted_object = nullptr;
while (current_object != nullptr) {
if (current_object->HitTest(input_ray, 0.01f, max_distance, hit_point)) {
max_distance = hit_point.mDistance;
hitted_object = current_object;
}
current_object = current_object->Next<Object>();
}
if (hitted_object != nullptr) {
if(bounce_time < sMaxBounceTime){
Ray scatter_ray; Ray scatter_ray;
if (hit_point.mMaterial->Scatter(input_ray, hit_point, scatter_ray)) { if (hit_point.mMaterial->Scatter(input_ray, hit_point, scatter_ray)) {
return GetColor(scatter_ray);
return RenderOneSample(scatter_ray, bounce_time + 1);
} }
} }
return GetEnviromentColor(input_ray);
}
return GetEnviromentColor(input_ray) * input_ray.mLightAttenuation;
} }
void RenderOnePixel(int pixel_index) { void RenderOnePixel(int pixel_index) {
@ -73,7 +88,7 @@ void RenderOnePixel(int pixel_index) {
float u = (float(x) + offset_u) / sViewportWidth; float u = (float(x) + offset_u) / sViewportWidth;
float v = (float(y) + offset_v) / sViewportHeight; float v = (float(y) + offset_v) / sViewportHeight;
Ray ray = sCamera->GetRay(u, v); Ray ray = sCamera->GetRay(u, v);
Vector3 current_color = GetColor(ray);
Vector3 current_color = RenderOneSample(ray,0);
color = color + current_color; color = color + current_color;
} }
color /= sSampleCount; color /= sSampleCount;

8
Sphere.cpp

@ -23,17 +23,19 @@ bool Sphere::HitTest(const Ray& input_ray, float min_distance, float max_distanc
bool isHited = false; bool isHited = false;
float distance = -1.0f; float distance = -1.0f;
if (determinant > 0.0f) { if (determinant > 0.0f) {
distance = (-b - sqrtf(determinant))/ 2.0f;
distance = (-b - sqrtf(determinant))/ 2.0f *a;
if (distance > min_distance && distance < max_distance) { if (distance > min_distance && distance < max_distance) {
isHited = true; isHited = true;
} }
distance = (-b + sqrtf(determinant)) / 2.0f;
else {
distance = (-b + sqrtf(determinant)) / 2.0f*a;
if (distance > min_distance && distance < max_distance) { if (distance > min_distance && distance < max_distance) {
isHited = true; isHited = true;
} }
} }
}
else if (determinant == 0.0f) { else if (determinant == 0.0f) {
distance = -b / 2.0f;
distance = -b / (2.0f * a);
if (distance > min_distance && distance < max_distance) { if (distance > min_distance && distance < max_distance) {
isHited = true; isHited = true;
} }

Loading…
Cancel
Save