Browse Source

渲染出texture

master
ubuntu20 4 years ago
parent
commit
636b3e996f
  1. 5
      Material.cpp
  2. 9
      Material.h
  3. 18
      Scene.cpp
  4. 11
      Sphere.cpp
  5. 1
      Sphere.h
  6. 12
      Texture.cpp
  7. 6
      Texture.h
  8. 1
      Vector3.h
  9. BIN
      earth.bmp

5
Material.cpp

@ -1,16 +1,17 @@
#include "Material.h" #include "Material.h"
#include "Ray.h" #include "Ray.h"
#include "Texture.h"
#include <math.h> #include <math.h>
bool LamberMaterial::Scatter(const Ray & input_ray, const HitPoint & hit_point, Ray & out_ray) bool LamberMaterial::Scatter(const Ray & input_ray, const HitPoint & hit_point, Ray & out_ray)
{ {
Vector3 random_vector = UnitRandomVector3InSphere(); Vector3 random_vector = UnitRandomVector3InSphere();
Vector3 new_direction = hit_point.mNormal + random_vector; Vector3 new_direction = hit_point.mNormal + random_vector;
out_ray.Set(hit_point.mPosition, new_direction, input_ray.mLightAttenuation*mDiffuse);
out_ray.Set(hit_point.mPosition, new_direction, input_ray.mLightAttenuation*mDiffuseTexture->Sample(hit_point.mU, hit_point.mV));
return true; return true;
} }
bool MetalMaterial::Scatter(const Ray & input_ray, const HitPoint & hit_point, Ray & out_ray) bool MetalMaterial::Scatter(const Ray & input_ray, const HitPoint & hit_point, Ray & out_ray)
{ {
Vector3 new_direction = Reflect(input_ray.mDirection, hit_point.mNormal); Vector3 new_direction = Reflect(input_ray.mDirection, hit_point.mNormal);
out_ray.Set(hit_point.mPosition, new_direction, input_ray.mLightAttenuation*mDiffuse);
out_ray.Set(hit_point.mPosition, new_direction, input_ray.mLightAttenuation*mDiffuseTexture->Sample(hit_point.mU, hit_point.mV));
return true; return true;
} }

9
Material.h

@ -1,19 +1,20 @@
#pragma once #pragma once
#include "Vector3.h" #include "Vector3.h"
class Ray; class Ray;
class Texture2D;
class Material { class Material {
public: public:
virtual bool Scatter(const Ray& input_ray, const HitPoint& hit_point, Ray& out_ray) = 0; virtual bool Scatter(const Ray& input_ray, const HitPoint& hit_point, Ray& out_ray) = 0;
}; };
class LamberMaterial : public Material { class LamberMaterial : public Material {
public: public:
Vector3 mDiffuse;
LamberMaterial(const Vector3 diffuse) { mDiffuse = diffuse; }
Texture2D *mDiffuseTexture;
LamberMaterial(Texture2D* diffuse) { mDiffuseTexture = diffuse; }
bool Scatter(const Ray& input_ray, const HitPoint& hit_point, Ray& out_ray); bool Scatter(const Ray& input_ray, const HitPoint& hit_point, Ray& out_ray);
}; };
class MetalMaterial : public Material { class MetalMaterial : public Material {
public: public:
Vector3 mDiffuse;
MetalMaterial(const Vector3 diffuse) { mDiffuse = diffuse; }
Texture2D *mDiffuseTexture;
MetalMaterial(Texture2D* diffuse) { mDiffuseTexture = diffuse; }
bool Scatter(const Ray& input_ray, const HitPoint& hit_point, Ray& out_ray); bool Scatter(const Ray& input_ray, const HitPoint& hit_point, Ray& out_ray);
}; };

18
Scene.cpp

@ -6,6 +6,7 @@
#include "Object.h" #include "Object.h"
#include "Vector3.h" #include "Vector3.h"
#include "Sphere.h" #include "Sphere.h"
#include "Texture.h"
#pragma comment(lib, "winmm.lib") #pragma comment(lib, "winmm.lib")
static int sTotalPixelCount = 0; static int sTotalPixelCount = 0;
static int sViewportWidth = 0, sViewportHeight = 0; static int sViewportWidth = 0, sViewportHeight = 0;
@ -13,8 +14,8 @@ static Camera* sCamera = nullptr;
Sphere sphere(Vector3(0.0f, 0.5f, 0.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 = 6;
static int sMaxBounceTime = 30;
static int sSampleCount = 256;
static int sMaxBounceTime = 2;
void AddObject(Object* object) { void AddObject(Object* object) {
if (sRootObject == nullptr) { if (sRootObject == nullptr) {
sRootObject = object; sRootObject = object;
@ -30,11 +31,18 @@ void Init(int width, int height)
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(3.0f, 1.0f, 3.0f), Vector3(0.0f, 0.0f, 0.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));
Material* metal_material = new MetalMaterial(Vector3(0.9f,0.9f,0.9f));
Texture2D* solid_color1 = new TextureSolidColor(Vector3(0.1f, 0.4f, 0.7f));
Texture2D* solid_color2 = new TextureSolidColor(Vector3(0.5f, 0.3f, 0.1f));
Texture2D* solid_color3 = new TextureSolidColor(Vector3(0.9f, 0.9f, 0.9f));
Material* earth_material = new LamberMaterial(solid_color2);
Material* metal_material = new MetalMaterial(solid_color3);
AddObject(new Object(new Sphere(Vector3(0.0f, -1000.0f, 0.0), 1000.0f), earth_material)); AddObject(new Object(new Sphere(Vector3(0.0f, -1000.0f, 0.0), 1000.0f), earth_material));
AddObject(new Object(new Sphere(Vector3(-1.0f, 0.5f, 0.3), 0.5f), metal_material)); AddObject(new Object(new Sphere(Vector3(-1.0f, 0.5f, 0.3), 0.5f), metal_material));
lambert = new LamberMaterial(Vector3(0.1f, 0.4f, 0.7f));
TextureRGB* rgb = new TextureRGB();
rgb->Set("earth.bmp");
lambert = new LamberMaterial(rgb);
AddObject(new Object(&sphere, lambert)); AddObject(new Object(&sphere, lambert));
} }

11
Sphere.cpp

@ -47,7 +47,18 @@ bool Sphere::HitTest(const Ray& input_ray, float min_distance, float max_distanc
normal.Normalize(); normal.Normalize();
hit_point.mDistance = distance; hit_point.mDistance = distance;
hit_point.mNormal = normal; hit_point.mNormal = normal;
CalculateTexcoord(hit_point.mPosition, hit_point.mU, hit_point.mV);
} }
return isHited; return isHited;
} }
#define PI 3.1415926f
void Sphere::CalculateTexcoord(const Vector3& pos_on_sphere, float& u, float& v) {
float a = atan2f(pos_on_sphere.z, pos_on_sphere.x);
float b = asinf(pos_on_sphere.y);
a = a + PI;
u = a / (2.0f * PI);
b = b + PI / 2.0f;
v = b / PI;
}

1
Sphere.h

@ -7,4 +7,5 @@ public:
Sphere(const Vector3& origin, float radius); Sphere(const Vector3& origin, float radius);
void set(const Vector3& origin, float radius); void set(const Vector3& origin, float radius);
bool HitTest(const Ray& input_ray, float min_distance, float max_distance, HitPoint& hit_point); bool HitTest(const Ray& input_ray, float min_distance, float max_distance, HitPoint& hit_point);
void CalculateTexcoord(const Vector3& pos_on_sphere, float &u, float &v);
}; };

12
Texture.cpp

@ -26,7 +26,7 @@ void TextureRGB::Set(const char * image_path)
Vector3 TextureRGB::Sample(float u, float v) Vector3 TextureRGB::Sample(float u, float v)
{ {
int x = int(u * mWidth); int x = int(u * mWidth);
int y = int(u * mHeight);
int y = int(v * mHeight);
x = x < 0 ? 0 : x; x = x < 0 ? 0 : x;
y = y < 0 ? 0 : y; y = y < 0 ? 0 : y;
x = x > (mWidth - 1) ? (mWidth - 1) : x; x = x > (mWidth - 1) ? (mWidth - 1) : x;
@ -37,3 +37,13 @@ Vector3 TextureRGB::Sample(float u, float v)
float b = float(mRGBPixel[pixel_data_start_index + 2]) / 255.0f; float b = float(mRGBPixel[pixel_data_start_index + 2]) / 255.0f;
return Vector3(r, g, b); return Vector3(r, g, b);
} }
TextureSolidColor::TextureSolidColor(const Vector3 & color)
{
mSolidColor = color;
}
Vector3 TextureSolidColor::Sample(float u, float v)
{
return mSolidColor;
}

6
Texture.h

@ -4,6 +4,12 @@ class Texture2D {
public: public:
virtual Vector3 Sample(float u, float v) = 0; virtual Vector3 Sample(float u, float v) = 0;
}; };
class TextureSolidColor : public Texture2D {
public:
Vector3 mSolidColor;
TextureSolidColor(const Vector3& color);
Vector3 Sample(float u, float v);
};
class TextureRGB : public Texture2D { class TextureRGB : public Texture2D {
public: public:
unsigned char* mImageFileContent; unsigned char* mImageFileContent;

1
Vector3.h

@ -43,6 +43,7 @@ class Material;
struct HitPoint { struct HitPoint {
Vector3 mPosition; Vector3 mPosition;
Vector3 mNormal; Vector3 mNormal;
float mU, mV;
float mDistance; float mDistance;
Material* mMaterial; Material* mMaterial;
}; };

BIN
earth.bmp

Loading…
Cancel
Save