commit
05ffa6048e
@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
.vscode/
|
@ -0,0 +1,8 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
project(ray)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "-g -Wall")
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
add_executable(ray main.cpp )
|
@ -0,0 +1,121 @@
|
|||||||
|
Creative Commons Legal Code
|
||||||
|
|
||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||||
|
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||||
|
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||||
|
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||||
|
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||||
|
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||||
|
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||||
|
HEREUNDER.
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||||
|
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for
|
||||||
|
the purpose of contributing to a commons of creative, cultural and
|
||||||
|
scientific works ("Commons") that the public can reliably and without fear
|
||||||
|
of later claims of infringement build upon, modify, incorporate in other
|
||||||
|
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||||
|
and for any purposes, including without limitation commercial purposes.
|
||||||
|
These owners may contribute to the Commons to promote the ideal of a free
|
||||||
|
culture and the further production of creative, cultural and scientific
|
||||||
|
works, or to gain reputation or greater distribution for their Work in
|
||||||
|
part through the use and efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any
|
||||||
|
expectation of additional consideration or compensation, the person
|
||||||
|
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||||
|
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||||
|
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||||
|
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||||
|
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not
|
||||||
|
limited to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display,
|
||||||
|
communicate, and translate a Work;
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or
|
||||||
|
likeness depicted in a Work;
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||||
|
in a Work;
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation
|
||||||
|
thereof, including any amended or successor version of such
|
||||||
|
directive); and
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the
|
||||||
|
world based on applicable law or treaty, and any national
|
||||||
|
implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||||
|
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||||
|
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||||
|
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||||
|
of action, whether now known or unknown (including existing as well as
|
||||||
|
future claims and causes of action), in the Work (i) in all territories
|
||||||
|
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||||
|
treaty (including future time extensions), (iii) in any current or future
|
||||||
|
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||||
|
including without limitation commercial, advertising or promotional
|
||||||
|
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||||
|
member of the public at large and to the detriment of Affirmer's heirs and
|
||||||
|
successors, fully intending that such Waiver shall not be subject to
|
||||||
|
revocation, rescission, cancellation, termination, or any other legal or
|
||||||
|
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||||
|
as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||||
|
be judged legally invalid or ineffective under applicable law, then the
|
||||||
|
Waiver shall be preserved to the maximum extent permitted taking into
|
||||||
|
account Affirmer's express Statement of Purpose. In addition, to the
|
||||||
|
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||||
|
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||||
|
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||||
|
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||||
|
maximum duration provided by applicable law or treaty (including future
|
||||||
|
time extensions), (iii) in any current or future medium and for any number
|
||||||
|
of copies, and (iv) for any purpose whatsoever, including without
|
||||||
|
limitation commercial, advertising or promotional purposes (the
|
||||||
|
"License"). The License shall be deemed effective as of the date CC0 was
|
||||||
|
applied by Affirmer to the Work. Should any part of the License for any
|
||||||
|
reason be judged legally invalid or ineffective under applicable law, such
|
||||||
|
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||||
|
of the License, and in such case Affirmer hereby affirms that he or she
|
||||||
|
will not (i) exercise any of his or her remaining Copyright and Related
|
||||||
|
Rights in the Work or (ii) assert any associated claims and causes of
|
||||||
|
action with respect to the Work, in either case contrary to Affirmer's
|
||||||
|
express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or
|
||||||
|
warranties of any kind concerning the Work, express, implied,
|
||||||
|
statutory or otherwise, including without limitation warranties of
|
||||||
|
title, merchantability, fitness for a particular purpose, non
|
||||||
|
infringement, or the absence of latent or other defects, accuracy, or
|
||||||
|
the present or absence of errors, whether or not discoverable, all to
|
||||||
|
the greatest extent permissible under applicable law.
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without
|
||||||
|
limitation any person's Copyright and Related Rights in the Work.
|
||||||
|
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||||
|
consents, permissions or other rights required for any use of the
|
||||||
|
Work.
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to
|
||||||
|
this CC0 or use of the Work.
|
@ -0,0 +1,101 @@
|
|||||||
|
#ifndef GEOH
|
||||||
|
#define GEOH
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "ray.h"
|
||||||
|
using namespace std;
|
||||||
|
struct hit_record {
|
||||||
|
float t;
|
||||||
|
vec3 p;
|
||||||
|
vec3 nv;
|
||||||
|
vec3 kd;
|
||||||
|
float wr;
|
||||||
|
float wt;
|
||||||
|
};
|
||||||
|
|
||||||
|
class hitable { //geometry parent class
|
||||||
|
public:
|
||||||
|
virtual bool hit(const ray &r, float tmin, float tmax, hit_record *rec) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class sphere : public hitable {
|
||||||
|
public:
|
||||||
|
sphere() {}
|
||||||
|
sphere(vec3 c, float r, vec3 _kd = vec3(1.0, 1.0, 1.0), float w_ri = 0.0f, float w_ti = 0.0f) : center(c), radius(r), kd(_kd), w_r(w_ri), w_t(w_ti){};
|
||||||
|
bool hit(const ray &r, float tmin, float tmax, hit_record *rec) const;
|
||||||
|
vec3 center;
|
||||||
|
float radius;
|
||||||
|
vec3 kd;
|
||||||
|
float w_r; //reflected
|
||||||
|
float w_t; //transmitted
|
||||||
|
};
|
||||||
|
|
||||||
|
bool sphere::hit(const ray &r, float tmin, float tmax, hit_record *rec) const {
|
||||||
|
float a, b, c, t;
|
||||||
|
a = dot(r.D, r.D);
|
||||||
|
b = 2 * (dot(r.D, (r.O - this->center)));
|
||||||
|
c = dot(r.O - this->center, r.O - this->center) - this->radius * this->radius;
|
||||||
|
if (((b * b) - (4 * a * c)) > 0) {
|
||||||
|
if ((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin && (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) {
|
||||||
|
t = min((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)), (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)));
|
||||||
|
} else if ((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) {
|
||||||
|
t = (((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a));
|
||||||
|
} else if ((((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) {
|
||||||
|
t = (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (t > tmax || t < tmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (rec->t > t) {
|
||||||
|
rec->t = t;
|
||||||
|
rec->p = r.point_at_parameter(t);
|
||||||
|
rec->nv = unit_vector(r.point_at_parameter(t) - this->center);
|
||||||
|
rec->kd = this->kd;
|
||||||
|
rec->wr = this->w_r;
|
||||||
|
rec->wt = this->w_t;
|
||||||
|
//cout << t << " " << rec->p << " " << rec->nv << endl;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 reflect(const vec3 &d, const vec3 &nv) {
|
||||||
|
return d - (2 * dot(d, nv) * nv);
|
||||||
|
|
||||||
|
return vec3(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
float clamp(T bot, T top, T targ) {
|
||||||
|
if (targ > top) {
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
if (targ < bot) {
|
||||||
|
return bot;
|
||||||
|
}
|
||||||
|
return targ;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 refract(const vec3 &i, const vec3 &n, float eta) {
|
||||||
|
vec3 I = unit_vector(i);
|
||||||
|
vec3 N = unit_vector(n);
|
||||||
|
//cout << I << " " << N << " " << dot(N, I) << endl;
|
||||||
|
eta = 1 / eta;
|
||||||
|
if (dot(N, I) > 0) {
|
||||||
|
N = -1 * N;
|
||||||
|
eta = 1 / eta;
|
||||||
|
}
|
||||||
|
float k = 1.0f - eta * eta * (1.0 - dot(N, I) * dot(N, I));
|
||||||
|
//cout << k << endl;
|
||||||
|
if (k < 0.0) {
|
||||||
|
return i - (2 * dot(i, n) * n);
|
||||||
|
}
|
||||||
|
|
||||||
|
//cout << eta * I - (eta * dot(N, I) + sqrt(k)) * N << endl;
|
||||||
|
return eta * I - (eta * dot(N, I) + sqrt(k)) * N;
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,195 @@
|
|||||||
|
#include <cfloat>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "geo.h"
|
||||||
|
#include "ray.h"
|
||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
float MAX(float a, float b) { return (a > b) ? a : b; }
|
||||||
|
using namespace std;
|
||||||
|
int max_step = 5;
|
||||||
|
|
||||||
|
vec3 shading(vec3 &lightsource, vec3 &intensity, hit_record ht, vec3 kd, const vector<sphere> &list) {
|
||||||
|
/*
|
||||||
|
define L, N by yourself
|
||||||
|
*/
|
||||||
|
vec3 L = lightsource - ht.p;
|
||||||
|
vec3 N = ht.nv;
|
||||||
|
ray shadowRay(ht.p, L);
|
||||||
|
|
||||||
|
int intersect = -1;
|
||||||
|
hit_record rec;
|
||||||
|
float closest = FLT_MAX;
|
||||||
|
/*
|
||||||
|
To-do:
|
||||||
|
To find whether the shadowRay hit other object,
|
||||||
|
you should run the function "hit" of all the hitable you created
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
if (list[i].hit(shadowRay, 0.001, 10000, &rec)) {
|
||||||
|
intersect += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intersect == -1) {
|
||||||
|
return kd * intensity * MAX(0, dot(N, unit_vector(L)));
|
||||||
|
} else {
|
||||||
|
return vec3(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 skybox(const ray &r) {
|
||||||
|
vec3 uni_direction = unit_vector(r.direction());
|
||||||
|
float t = 0.5 * (uni_direction.y() + 1);
|
||||||
|
return (1.0 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 trace(const ray &r, const vector<sphere> &list, int depth) {
|
||||||
|
if (r.direction() == vec3(0, 0, 0)) {
|
||||||
|
return vec3(0, 0, 0);
|
||||||
|
}
|
||||||
|
//cout << r.direction() << endl;
|
||||||
|
if (depth >= max_step)
|
||||||
|
return skybox(r); //or return vec3(0,0,0);
|
||||||
|
|
||||||
|
int intersect = -1;
|
||||||
|
vec3 lightsource = vec3(-10, 10, 0);
|
||||||
|
vec3 intensity = vec3(1, 1, 1);
|
||||||
|
hit_record rec;
|
||||||
|
rec.t = 10000;
|
||||||
|
rec.p = vec3(0, 0, 0);
|
||||||
|
rec.nv = vec3(0, 0, 0);
|
||||||
|
float closest = FLT_MAX;
|
||||||
|
/*
|
||||||
|
To-do:
|
||||||
|
To find the nearest object from the origin of the ray,
|
||||||
|
you should run the function "hit" of all the hitable you created
|
||||||
|
*/
|
||||||
|
//cout << "Hit" << endl;
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
if (list[i].hit(r, 0.0001, 1000, &rec)) {
|
||||||
|
//cout << intersect << endl;
|
||||||
|
intersect += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intersect != -1) {
|
||||||
|
/*
|
||||||
|
To-do:
|
||||||
|
1.compute the local color by shading function
|
||||||
|
2.compute the relected color by
|
||||||
|
2.1 compute the reflected direction
|
||||||
|
2.2 define a reflected ray by rec.p and the direction in 2.1
|
||||||
|
2.3 run trace(reflected_ray,list,depth+1);
|
||||||
|
3.compute the transmitted color by
|
||||||
|
3.1 compute the transmitted direction by Snell's law
|
||||||
|
3.2 define a transmitted ray by rec.p and the direction in 3.1
|
||||||
|
3.3 run trace( transmitted_ray, list, depth+1 );
|
||||||
|
4.return the color by the parameter w_r, w_t and the 3 color you computed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//1.
|
||||||
|
vec3 L = unit_vector(lightsource - rec.p);
|
||||||
|
vec3 colour = (dot(rec.nv, L) >= 0 ? dot(rec.nv, L) : 0) * rec.kd;
|
||||||
|
|
||||||
|
//cout << rec.kd << " " << rec.wr << endl;
|
||||||
|
|
||||||
|
//return colour;
|
||||||
|
|
||||||
|
vec3 shadow = shading(lightsource, intensity, rec, rec.kd, list);
|
||||||
|
colour = 0.2 * colour + 0.8 * shadow;
|
||||||
|
|
||||||
|
if (depth >= 5) {
|
||||||
|
//return 0.5 * vec3(rec.nv.x() + 1, rec.nv.y() + 1, rec.nv.z() + 1);
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
if (rec.wr <= 0 && rec.wt <= 0) {
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vec3 reflection = vec3(0, 0, 0);
|
||||||
|
if ((dot(r.direction(), rec.nv) / r.direction().length() * rec.nv.length()) < 0) {
|
||||||
|
if (rec.wr > 0) {
|
||||||
|
//cout << "reflection " << depth << endl;
|
||||||
|
reflection = trace(ray(rec.p, reflect(r.direction(), rec.nv)), list, (depth + 1));
|
||||||
|
}
|
||||||
|
if (rec.wt <= 0) {
|
||||||
|
//cout << "reflection " << depth << endl;
|
||||||
|
colour = reflection * rec.wr + colour * max(0.0f, (1 - rec.wr));
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
//cout << "refraction " << depth << endl;
|
||||||
|
vec3 refraction = trace(ray(rec.p, refract(r.direction(), rec.nv, 1.5)), list, (depth + 1));
|
||||||
|
colour = reflection * rec.wr + refraction * rec.wt + colour * max(0.0f, (1 - rec.wr - rec.wt));
|
||||||
|
} else {
|
||||||
|
//cout << "refraction " << depth << endl;
|
||||||
|
vec3 refraction = trace(ray(rec.p, refract(r.direction(), rec.nv, 1.5)), list, (depth + 1));
|
||||||
|
//cout << "refraction out" << endl;
|
||||||
|
colour = refraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
//cout << L << endl;
|
||||||
|
//cout << colour << endl;
|
||||||
|
//return vec3(0, 0, 0);
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return skybox(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int width = 3840;
|
||||||
|
int height = 1920;
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
//camera and projection plane
|
||||||
|
vec3 lower_left_corner(-2, -1, -1);
|
||||||
|
vec3 origin(0, 0, 0);
|
||||||
|
vec3 horizontal(4, 0, 0);
|
||||||
|
vec3 vertical(0, 2, 0);
|
||||||
|
|
||||||
|
vec3 colorlist[8] = {vec3(0.8, 0.3, 0.3), vec3(0.3, 0.8, 0.3), vec3(0.3, 0.3, 0.8),
|
||||||
|
vec3(0.8, 0.8, 0.3), vec3(0.3, 0.8, 0.8), vec3(0.8, 0.3, 0.8),
|
||||||
|
vec3(0.8, 0.8, 0.8), vec3(0.3, 0.3, 0.3)};
|
||||||
|
|
||||||
|
//test scene with spheres
|
||||||
|
vector<sphere> hitable_list;
|
||||||
|
hitable_list.push_back(sphere(vec3(0, -100.5, -2), 100, vec3(1.0f, 1.0f, 1.0f), 0.0f, 0.0f)); //ground
|
||||||
|
hitable_list.push_back(sphere(vec3(0, 0, -2), 0.5, vec3(1.0f, 1.0f, 1.0f), 0.0f, 0.9f));
|
||||||
|
hitable_list.push_back(sphere(vec3(1, 0, -1.75), 0.5, vec3(1.0f, 1.0f, 1.0f), 0.5f, 0.0f));
|
||||||
|
hitable_list.push_back(sphere(vec3(-1, 0, -2.25), 0.5, vec3(1.0f, 0.7f, 0.3f), 0.0f, 0.0f));
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
float xr = ((float)rand() / (float)(RAND_MAX)) * 6.0f - 3.0f;
|
||||||
|
float zr = ((float)rand() / (float)(RAND_MAX)) * 3.0f - 1.5f;
|
||||||
|
int cindex = rand() % 8;
|
||||||
|
float rand_reflec = ((float)rand() / (float)(RAND_MAX));
|
||||||
|
//float rand_refrac = ((float)rand() / (float)(RAND_MAX));
|
||||||
|
hitable_list.push_back(sphere(vec3(xr, -0.4, zr - 2), 0.1, colorlist[cindex], rand_reflec, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
fstream file;
|
||||||
|
file.open("ray.ppm", ios::out);
|
||||||
|
file << "P3\n"
|
||||||
|
<< width << " " << height << "\n255\n";
|
||||||
|
for (int j = height - 1; j >= 0; j--) {
|
||||||
|
cout << j << endl;
|
||||||
|
for (int i = 0; i < width; i++) {
|
||||||
|
//cout << j << " " << i << endl;
|
||||||
|
float u = float(i) / float(width);
|
||||||
|
float v = float(j) / float(height);
|
||||||
|
ray r(origin, lower_left_corner + u * horizontal + v * vertical);
|
||||||
|
vec3 c = trace(r, hitable_list, 0);
|
||||||
|
|
||||||
|
file << min(255, (int)(c.r() * 255)) << " "
|
||||||
|
<< min(255, (int)(c.g() * 255)) << " "
|
||||||
|
<< min(255, (int)(c.b() * 255)) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef RAYH
|
||||||
|
#define RAYH
|
||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
class ray {
|
||||||
|
public:
|
||||||
|
ray() {}
|
||||||
|
ray(const vec3& a, const vec3& b) {
|
||||||
|
O = a;
|
||||||
|
D = b;
|
||||||
|
}
|
||||||
|
vec3 origin() const { return O; }
|
||||||
|
vec3 direction() const { return D; }
|
||||||
|
inline vec3 point_at_parameter(float t) const {
|
||||||
|
return vec3(D * t + O);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 O; //center(origin) point
|
||||||
|
vec3 D; //direction vector
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,98 @@
|
|||||||
|
//=================================================================================================
|
||||||
|
// Written in 2016 by Peter Shirley <ptrshrl@gmail.com>
|
||||||
|
//
|
||||||
|
// To the extent possible under law, the author(s) have dedicated all copyright and related and
|
||||||
|
// neighboring rights to this software to the public domain worldwide. This software is distributed
|
||||||
|
// without any warranty.
|
||||||
|
//
|
||||||
|
// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along
|
||||||
|
// with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
#ifndef VEC3H
|
||||||
|
#define VEC3H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class vec3 {
|
||||||
|
public:
|
||||||
|
vec3() {}
|
||||||
|
vec3(float e0, float e1, float e2) {
|
||||||
|
e[0] = e0;
|
||||||
|
e[1] = e1;
|
||||||
|
e[2] = e2;
|
||||||
|
}
|
||||||
|
vec3(const vec3 &v2){
|
||||||
|
this->e[0] = v2.e[0];
|
||||||
|
this->e[1] = v2.e[1];
|
||||||
|
this->e[2] = v2.e[2];
|
||||||
|
}
|
||||||
|
float x() const { return e[0]; }
|
||||||
|
float y() const { return e[1]; }
|
||||||
|
float z() const { return e[2]; }
|
||||||
|
float r() const { return e[0]; }
|
||||||
|
float g() const { return e[1]; }
|
||||||
|
float b() const { return e[2]; }
|
||||||
|
|
||||||
|
inline vec3 operator+(const vec3 &v2) const { return vec3(x() + v2.x(), y() + v2.y(), z() + v2.z()); }
|
||||||
|
inline void operator+=(const vec3 &v2) { e[0] = x() + v2.x(), e[1] = y() + v2.y(), e[2] = z() + v2.z(); }
|
||||||
|
inline vec3 operator-(const vec3 &v2) const { return vec3(x() - v2.x(), y() - v2.y(), z() - v2.z()); }
|
||||||
|
inline void operator-=(const vec3 &v2) { e[0] = x() - v2.x(), e[1] = y() - v2.y(), e[2] = z() - v2.z(); }
|
||||||
|
|
||||||
|
inline vec3 operator*(const float t) const { return vec3(x() * t, y() * t, z() * t); }
|
||||||
|
inline void operator*=(const float t) { e[0] = x() * t, e[1] = y() * t, e[2] = z() * t; }
|
||||||
|
inline vec3 operator/(const float t) const { return vec3(x() / t, y() / t, z() / t); }
|
||||||
|
inline void operator/=(const float t) { e[0] = x() / t, e[1] = y() / t, e[2] = z() / t; }
|
||||||
|
|
||||||
|
inline bool operator==(const vec3 &v2) const {
|
||||||
|
if(this->x() == v2.x() && this->y() == v2.y() && this->z() == v2.z()) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float length() const { return sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]); }
|
||||||
|
inline float squared_length() const { return e[0] * e[0] + e[1] * e[1] + e[2] * e[2]; }
|
||||||
|
inline void make_unit_vector() {
|
||||||
|
float len = length();
|
||||||
|
e[0] = e[0] / len;
|
||||||
|
e[1] = e[1] / len;
|
||||||
|
e[2] = e[2] / len;
|
||||||
|
}
|
||||||
|
|
||||||
|
float e[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline vec3 operator*(const float t, const vec3 &v) {
|
||||||
|
return vec3(v.x() * t, v.y() * t, v.z() * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
for color calculation
|
||||||
|
*/
|
||||||
|
inline vec3 operator*(const vec3 &v1, const vec3 &v2) {
|
||||||
|
return vec3(v1.e[0] * v2.e[0], v1.e[1] * v2.e[1], v1.e[2] * v2.e[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &os, const vec3 &t) {
|
||||||
|
os << "( " << t.x() << " , " << t.y() << " , " << t.z() << " )";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float dot(const vec3 &v1, const vec3 &v2) {
|
||||||
|
return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline vec3 cross(const vec3 &v1, const vec3 &v2) {
|
||||||
|
return vec3(v1.y() * v2.z() - v1.z() * v2.y(),
|
||||||
|
v1.x() * v2.z() - v1.z() * v2.x(),
|
||||||
|
v1.x() * v2.y() - v1.y() * v2.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline vec3 unit_vector(vec3 v) {
|
||||||
|
return v / v.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in new issue