Skip to content

Commit

Permalink
add texture on sphere and importance sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
evan69 committed May 26, 2016
1 parent 169f007 commit 94dad78
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 15 deletions.
1 change: 1 addition & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
2016.5.24 ��������Ӱ���ֲھ��淴��
2016.5.26 ����������࣬�޸��ֲھ��淴���bug
2016.5.26 ����ƽ���������ͼ
2016.5.26 �������������ͼ��������Ҫ�Բ���
1 change: 1 addition & 0 deletions all.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace HYF
#define GRIDSIZE 8
#define GRIDSHFT 3
#define MAXLIGHTS 10
#define SAMPLES 128

#define PI 3.141592653589793238462f

Expand Down
9 changes: 9 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "all.h"

using namespace cv;
using std::string;

Mat colorim(600,800,CV_8UC3);

Expand All @@ -15,6 +16,14 @@ int main()
imshow("test",colorim);
time_t end = clock();
printf("time : %llf second\n",(double)(end - start) / CLOCKS_PER_SEC);
#ifdef OUTPUT
string name = "output_";
char* htime = new char[100];
gcvt((double)(end - start) / CLOCKS_PER_SEC,6,htime);
name += string(htime);
name += string("s.png");
imwrite(name.c_str(),colorim);
#endif
waitKey(0);
return 0;
}
1 change: 0 additions & 1 deletion plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class PlanePrim : public Primitive
PlanePrim( vector3& p_Normal, double p_D ) : m_Plane( plane( p_Normal, p_D ) )
{
//x_Dir = vector3( m_Plane.N.y, m_Plane.N.z, -m_Plane.N.x );

x_Dir = m_Plane.N.Cross(vector3(0,1,0));
y_Dir = x_Dir.Cross( m_Plane.N );
NORMALIZE(x_Dir);
Expand Down
60 changes: 50 additions & 10 deletions raytracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ int Engine::FindNearest( Ray& p_Ray, double& p_Dist, Primitive*& p_Prim )
return retval;
}

double Engine::calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir)
double Engine::calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir,double p_Sample,double p_SampleRange)
{

//vector3 delta = vector3();
Expand Down Expand Up @@ -244,12 +244,30 @@ double Engine::calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir)
{
//printf("box\n");
shade = 0.0;
int max_X = 10,max_Z = 10;
//int max_X = 10,max_Z = 10;
Box* light = (Box*)p_Light;
vector3 P = light->getPos();
vector3 size = light->getSize();
p_Dir = P + 0.5 * size - p_pi;
NORMALIZE(p_Dir);
int n = (int)floor(sqrt(p_Sample + 0.5));
for(int i = 0;i < n;++i)
for(int j = 0;j < n;++j)
{
vector3 d = vector3(size.x / n,0.0,size.z / n);
//printf("%llf,%llf,%llf\n",d.x,d.y,d.z);
vector3 pos = P + vector3(d.x * (i + (double)rand() / RAND_MAX),0.0,d.z * (j + (double)rand() / RAND_MAX));
//monte carlo
vector3 dir = pos - p_pi;
double dist = LENGTH(dir);
NORMALIZE(dir);
if (FindNearest( Ray( p_pi + dir * EPS, dir), dist, prim ))
if (prim == p_Light)
//shade += (1.0 / (max_X * max_Z));
//shade += p_SampleRange;
shade += 1.0 / (n * n);
}
/*
for(int i = 0;i < max_X;++i)
for(int j = 0;j < max_Z;++j)
{
Expand All @@ -264,6 +282,7 @@ double Engine::calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir)
if (prim == p_Light)
shade += (1.0 / (max_X * max_Z));
}
*/
/*
shade = 0;
Box* b = (Box*)p_Light;
Expand All @@ -284,7 +303,8 @@ double Engine::calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir)
return shade;
}

Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Refr_Rate, double& p_Dist )
#define IMPORTANCE_SAMPLING
Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Refr_Rate, double& p_Dist ,double p_Sample,double p_SampleRange)
{
if (p_Depth > TRACEDEPTH) return 0;
// trace primary ray
Expand Down Expand Up @@ -357,7 +377,8 @@ Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Re
}
*/
vector3 L;
shade = calShade(light,pi,L);
//shade = calShade(light,pi,L);
shade = calShade(light,pi,L,p_Sample,p_SampleRange);
// calculate diffuse shading
//vector3 L = ((Sphere*)light)->getCentre() - pi;
//NORMALIZE( L );
Expand Down Expand Up @@ -400,7 +421,7 @@ Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Re
float drefl = prim->getMaterial()->getDiffRefl();
vector3 N = prim->getNormal( pi );
vector3 R = p_Ray.getDirection() - 2.0 * DOT( p_Ray.getDirection(), N ) * N;
if ((drefl > 0) && (p_Depth < 2))//粗糙镜面反射
if ((drefl > 0) && (p_Depth < 3))//粗糙镜面反射
{
vector3 component1 = vector3( R.z, 0.0, -R.x );
vector3 component2 = R.Cross( component1 );
Expand All @@ -424,7 +445,11 @@ Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Re
NORMALIZE( newR );
double dist;
Color rcol( 0, 0, 0 );
Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist );
#ifdef IMPORTANCE_SAMPLING
Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample * 0.25,p_SampleRange * 4.0);
#else
Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample,p_SampleRange);
#endif
//p_Col += refl * rcol * prim->getMaterial()->getColor() * (1.0 / (double)num);
p_Col += refl * rcol * prim->getColor(pi) * (1.0 / (double)num);
}
Expand All @@ -433,7 +458,14 @@ Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Re
{
Color rcol( 0, 0, 0 );
double dist;
Runtracer( Ray( pi + R * EPS, R ), rcol, p_Depth + 1, p_Refr_Rate, dist );
#ifdef IMPORTANCE_SAMPLING
//Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample * 0.25,p_SampleRange * 4.0);
Runtracer( Ray( pi + R * EPS, R ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample * 0.25,p_SampleRange * 4.0);
#else
//Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample,p_SampleRange);
Runtracer( Ray( pi + R * EPS, R ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample,p_SampleRange);
#endif
//Runtracer( Ray( pi + R * EPS, R ), rcol, p_Depth + 1, p_Refr_Rate, dist );
//p_Col += refl * rcol * prim->getMaterial()->getColor();
p_Col += refl * rcol * prim->getColor(pi);
}
Expand Down Expand Up @@ -461,7 +493,14 @@ Primitive* Engine::Runtracer( Ray& p_Ray, Color& p_Col, int p_Depth, double p_Re
double sinr = sqrt(sinr2);
double cosr = sqrt(cosr2);
vector3 T = (V * (1/n)) + (cosi / n - sqrt( cosr2 )) * N;
Runtracer(Ray(pi + T * EPS , T),rcol,p_Depth + 1, tmp_Refr_rate,dist);
#ifdef IMPORTANCE_SAMPLING
//Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample * 0.25,p_SampleRange * 4.0);
Runtracer(Ray(pi + T * EPS , T),rcol,p_Depth + 1, tmp_Refr_rate,dist,p_Sample * 0.25,p_SampleRange * 4.0);
#else
//Runtracer( Ray( pi + newR * EPS, newR ), rcol, p_Depth + 1, p_Refr_Rate, dist ,p_Sample,p_SampleRange);
Runtracer(Ray(pi + T * EPS , T),rcol,p_Depth + 1, tmp_Refr_rate,dist,p_Sample,p_SampleRange);
#endif
//Runtracer(Ray(pi + T * EPS , T),rcol,p_Depth + 1, tmp_Refr_rate,dist);
//Color absorbance = prim->getMaterial()->getColor() * 0.15 * -dist;
Color absorbance = prim->getColor(pi) * 0.15 * -dist;
Color transparency = Color( exp( absorbance.r ), exp( absorbance.g ), exp( absorbance.b ) );
Expand Down Expand Up @@ -494,7 +533,8 @@ bool Engine::HYF_render(cv::Mat& colorim)
vector3 dir = c.getDir(x,y);
Ray r( c.getEye(), dir );
double dist;
Primitive* prim = Runtracer( r, col, 1, 1.0, dist );
//Primitive* prim = Runtracer( r, col, 1, 1.0, dist );
Primitive* prim = Runtracer( r, col, 1, 1.0, dist ,SAMPLES,(1.0 / SAMPLES));
}
int red = (int)(col.r * 256 / 9);
int green = (int)(col.g * 256 / 9);
Expand All @@ -507,7 +547,7 @@ bool Engine::HYF_render(cv::Mat& colorim)
vector3 dir = c.getDir(x,y);
Ray r( c.getEye(), dir );
double dist;
Primitive* prim = Runtracer( r, col, 1, 1.0, dist );
Primitive* prim = Runtracer( r, col, 1, 1.0, dist ,SAMPLES,(1.0 / SAMPLES));
int red = (int)(col.r * 256);
int green = (int)(col.g * 256);
int blue = (int)(col.b * 256);
Expand Down
4 changes: 2 additions & 2 deletions raytracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ class Engine
~Engine();
void setTarget();
inline Scene* getScene() { return m_Scene; }
Primitive* Runtracer( Ray& p_Ray, Color& p_Acc, int p_Depth, double p_RIndex, double& p_Dist );
Primitive* Runtracer( Ray& p_Ray, Color& p_Acc, int p_Depth, double p_RIndex, double& p_Dist ,double p_Sample,double p_SampleRange);
bool HYF_render(cv::Mat&);
double calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir);
double calShade(Primitive* p_Light, vector3 p_pi, vector3& p_Dir,double p_Sample,double p_SampleRange);
int FindNearest(Ray& p_Ray, double& p_Dist, Primitive*& p_Prim);
protected:
Scene* m_Scene;
Expand Down
23 changes: 21 additions & 2 deletions scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,40 @@ void Scene::init()
// big sphere
m_Primitive[1] = new Sphere( vector3( 2, 0.8f, 3 ), 2.5f );
m_Primitive[1]->setName( "big sphere" );
/*
m_Primitive[1]->getMaterial()->setReflection( 0.2f );
m_Primitive[1]->getMaterial()->setRefraction( 0.8f );
m_Primitive[1]->getMaterial()->setRefr_Rate( 1.3f );
m_Primitive[1]->getMaterial()->setDiffuse( 0.1f );
m_Primitive[1]->getMaterial()->setSpecular( 0.9f );
m_Primitive[1]->getMaterial()->setColor( Color( 0.7f, 0.7f, 1.0 ) );
*/
m_Primitive[1]->getMaterial()->setReflection( 0.1f );
m_Primitive[1]->getMaterial()->setRefraction( 0.0f );
m_Primitive[1]->getMaterial()->setRefr_Rate( 1.3f );
m_Primitive[1]->getMaterial()->setDiffuse( 0.8f );
m_Primitive[1]->getMaterial()->setSpecular( 0.2f );
m_Primitive[1]->getMaterial()->setColor( Color( 0.7f, 0.7f, 1.0 ) );
m_Primitive[1]->getMaterial()->setTexure(new Texture("textures/marble.tga"));
// small sphere

m_Primitive[2] = new Sphere( vector3( -5.5f, -0.5, 7 ), 2 );
m_Primitive[2]->setName( "small sphere" );
/*
m_Primitive[2]->getMaterial()->setReflection( 0.5 );
m_Primitive[2]->getMaterial()->setRefraction( 0.0 );
m_Primitive[2]->getMaterial()->setRefr_Rate( 1.3 );
m_Primitive[2]->getMaterial()->setDiffuse( 0.1 );
m_Primitive[2]->getMaterial()->setSpecular( 0.9 );
m_Primitive[2]->getMaterial()->setColor( Color( 0.7, 0.7, 1.0 ) );
*/
m_Primitive[2]->getMaterial()->setReflection( 0.1f );
m_Primitive[2]->getMaterial()->setRefraction( 0.0f );
m_Primitive[2]->getMaterial()->setRefr_Rate( 1.3f );
m_Primitive[2]->getMaterial()->setDiffuse( 0.8f );
m_Primitive[2]->getMaterial()->setSpecular( 0.2f );
m_Primitive[2]->getMaterial()->setColor( Color( 0.7f, 0.7f, 1.0 ) );
m_Primitive[2]->getMaterial()->setTexure(new Texture("textures/marble.tga"));
// light source 1
m_Primitive[3] = new Sphere( vector3( 0, 5, 5 ), 0.1 );
m_Primitive[3]->Light( true );
Expand All @@ -64,8 +83,8 @@ void Scene::init()
m_Primitive[6]->getMaterial()->setSpecular( 0 );
m_Primitive[6]->getMaterial()->setDiffuse( 0.6 );
m_Primitive[6]->getMaterial()->setColor( Color( 0.5, 0.3, 0.5 ) );
m_Primitive[6]->getMaterial()->setTexure(new Texture( "textures/marble.tga" ));
m_Primitive[6]->getMaterial()->setTexRatio(2.0);
m_Primitive[6]->getMaterial()->setTexure(new Texture( "textures/wood.tga" ));
m_Primitive[6]->getMaterial()->setTexRatio(5.0);
// ceiling plane
m_Primitive[7] = new PlanePrim( vector3( 0, -1, 0 ), 7.4f );
m_Primitive[7]->setName( "back plane" );
Expand Down
17 changes: 17 additions & 0 deletions sphere.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
namespace HYF
{

Color Sphere::getColor(vector3& p_Pos)
{
if(m_Material.getTexure() == NULL)
{
return m_Material.getColor();
}
vector3 r_Pos = p_Pos - m_Centre;
double s = acos(r_Pos.z / m_Radius) / PI;
double t = acos(r_Pos.x / (m_Radius * sin(PI * s))) / PI;
if(r_Pos.y < 0) t += 0.5;
s /= (0.5 * m_Radius);
t /= (0.5 * m_Radius);
s = s - floor(s);
t = t - floor(s);
return m_Material.getTexure()->getUVColor(s,t);
}

int Sphere::Intersect( Ray& p_Ray, double& p_Dist )
{
vector3 v = p_Ray.getOrigin() - m_Centre;
Expand Down
1 change: 1 addition & 0 deletions sphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Sphere : public Primitive
vector3& getCentre() { return m_Centre; }
double getRadius() { return m_Radius; }
double getSqRadius() { return m_SqRadius; }
Color getColor(vector3& p_Pos);
int Intersect( Ray& p_Ray, double& p_Dist );
bool H_IntersectBox(BoundingBox&);
inline vector3 getNormal( vector3& p_Pos ) { return (p_Pos - m_Centre) * m_RRadius; }
Expand Down

0 comments on commit 94dad78

Please sign in to comment.