add glass like material
This commit is contained in:
parent
96e389d6b2
commit
f38e7d8081
11
src/main.cu
11
src/main.cu
@ -95,10 +95,11 @@ __global__ void render(vec3 *fb,
|
||||
|
||||
__global__ void create_world(hitable **d_list, int d_list_size, hitable **d_world, camera **d_camera) {
|
||||
if (threadIdx.x == 0 && blockIdx.y == 0) {
|
||||
d_list[0] = new sphere(vec3( 0, 0 , -1), 0.5, new lambertian(vec3(0.8, 0.3, 0.3)));
|
||||
d_list[1] = new sphere(vec3( 0, -100.5, -1), 100, new lambertian(vec3(0.8, 0.8, 0.0)));
|
||||
d_list[2] = new sphere(vec3( 1, 0 , -1), 0.5, new metal(vec3(0.8, 0.6, 0.2), 1.0));
|
||||
d_list[3] = new sphere(vec3(-1, 0 , -1), 0.5, new metal(vec3(0.8, 0.8, 0.8), 0.3));
|
||||
d_list[0] = new sphere(vec3( 0, 0 , -1), 0.5, new lambertian(vec3(0.1, 0.2, 0.5)));
|
||||
d_list[1] = new sphere(vec3( 0, -100.5, -1), 100, new lambertian(vec3(0.8, 0.8, 0.0)));
|
||||
d_list[2] = new sphere(vec3( 1, 0 , -1), 0.5, new metal(vec3(0.8, 0.6, 0.2), 0.0));
|
||||
d_list[3] = new sphere(vec3(-1, 0 , -1), 0.5, new dielectric(1.5));
|
||||
d_list[4] = new sphere(vec3(-1, 0 , -1), -0.45, new dielectric(1.5));
|
||||
*d_world = new hitable_list(d_list, d_list_size);
|
||||
*d_camera = new camera();
|
||||
}
|
||||
@ -137,7 +138,7 @@ int main() {
|
||||
|
||||
// populate world
|
||||
hitable **d_list;
|
||||
int d_list_size = 4;
|
||||
int d_list_size = 5;
|
||||
checkCudaErrors(cudaMalloc((void **)&d_list, d_list_size*sizeof(hitable *)));
|
||||
hitable **d_world;
|
||||
checkCudaErrors(cudaMalloc((void **)&d_world, sizeof(hitable *)));
|
||||
|
@ -21,6 +21,24 @@ __device__ vec3 reflect(const vec3& v, const vec3& n) {
|
||||
return v - 2.0f*dot(v,n)*n;
|
||||
}
|
||||
|
||||
__device__ float schlick(float cosine, float ref_idx) {
|
||||
float r0 = (1.0 - ref_idx) / (1.0f+ref_idx);
|
||||
r0 = r0*r0;
|
||||
return r0 + (1.0f - r0)*pow((1.0f - cosine), 5.0f);
|
||||
}
|
||||
|
||||
__device__ bool refract(const vec3& v, const vec3& n, float ni_over_nt, vec3& refracted) {
|
||||
vec3 uv = unit_vector(v);
|
||||
float dt = dot(uv, n);
|
||||
float discriminant = 1.0f - ni_over_nt*ni_over_nt*(1-dt*dt);
|
||||
if (discriminant > 0) {
|
||||
refracted = ni_over_nt*(uv - n*dt) - n*sqrt(discriminant);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class material {
|
||||
public:
|
||||
__device__ virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered, curandState *local_rand_state) const = 0;
|
||||
@ -58,3 +76,43 @@ public:
|
||||
vec3 albedo;
|
||||
float fuzz;
|
||||
};
|
||||
|
||||
class dielectric : public material {
|
||||
public:
|
||||
__device__ dielectric(float ri) : ref_idx(ri) {}
|
||||
__device__ virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered, curandState *local_rand_state) const {
|
||||
vec3 outward_normal;
|
||||
vec3 reflected = reflect(r_in.direction(), rec.normal);
|
||||
float ni_over_nt;
|
||||
attenuation = vec3(1.0, 1.0, 1.0);
|
||||
vec3 refracted;
|
||||
float reflect_prob;
|
||||
float cosine;
|
||||
if (dot(r_in.direction(), rec.normal) > 0.0f) {
|
||||
outward_normal = -rec.normal;
|
||||
ni_over_nt = ref_idx;
|
||||
cosine = dot(r_in.direction(), rec.normal) / r_in.direction().length();
|
||||
cosine = sqrt(1.0f - ref_idx*ref_idx*(1-cosine*cosine));
|
||||
} else {
|
||||
outward_normal = rec.normal;
|
||||
ni_over_nt = 1 / ref_idx;
|
||||
cosine = -dot(r_in.direction(), rec.normal) / r_in.direction().length();
|
||||
}
|
||||
|
||||
if (refract(r_in.direction(), outward_normal, ni_over_nt, refracted)) {
|
||||
reflect_prob = schlick(cosine, ref_idx);
|
||||
} else {
|
||||
reflect_prob = 1.0;
|
||||
}
|
||||
|
||||
if (curand_uniform(local_rand_state) < reflect_prob) {
|
||||
scattered = ray(rec.p, reflected);
|
||||
} else {
|
||||
scattered = ray(rec.p, refracted);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float ref_idx;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user