[과제] refraction effect
전공 지식 컴퓨터 그래픽스
문제
유리구(glass sphere) 뒤에 놓인 불투명한 세 개의 구를 화면에 그려야 한다.
이 때 유리구의 굴절률은 3/2 또는 1이고 transparency coefficient는 0.95이다.
단, ray tracing의 depth는 4로 제한한다.
문제의 상황을 그림으로 표현하면 다음과 같다.
코드
// Compute the intensity from ray using recursive ray casting.
// Exclude an intersection with the object E where the ray start from.
vec3
intensity(const Ray& ray, const Light l[], int nLights, int depth, int E = -1)
{
vec3 I(0, 0, 0); // Final intensity
// Find the closest intersection point and the normal
vec3 p, n; // Position and normal in the eye coordinate system
int iObject = findIntersection(ray, p, n, E);
if (iObject != -1) // Hit an object
{
if (ray.currMedium == Medium::AIR)
for (int i = 0; i < nLights; i++)
{
// Shadow ray
vec3 p_shadow, n_shadow; // Not used
vec3 pDistantLight = p + 1.0e10f * l[i].p_eye;
Ray shadowRay(p, pDistantLight);
int jObject = findIntersection(shadowRay, p_shadow, n_shadow, iObject);
if (jObject == -1) // Not shadowed
{
// Phong reflection
vec3 v = glm::normalize(ray.p0 - ray.p1); // Direction to the viewer
vec3 r = glm::normalize(reflect(l[i].p_eye, n)); // Direction of Reflected light
I += phong(n, v, l[i], r, iObject);
}
else
I += ambient(l[i], iObject); // Shadowed
}
// Recursive ray casting
if (depth < DEPTH)
{
// Reflection ray
if (reflection && ray.currMedium!=Medium::GLASS) // No reflection inside the glass sphere
// if (reflection) // Reflection inside the glass sphere
{
vec3 direction_reflection = glm::normalize(reflect(ray.p0 - ray.p1, n));
vec3 pr = p + 1.0E10f * direction_reflection; // Point far away from p along r
Ray recursiveRay_reflection(p, pr);
vec3 I_R_reflection = intensity(recursiveRay_reflection, l, nLights, depth + 1, iObject);
for (int i = 0; i < 3; i++)
I[i] += material[iObject].s[i] * I_R_reflection[i];
}
// Refraction ray
if (iObject == GLASS_SPHERE && translucent)
{
if (refraction)
{
// next medium
Medium nextMedium = ray.currMedium;
if (ray.currMedium == Medium::GLASS) // GLASS -> AIR
nextMedium = Medium::AIR;
else if (ray.currMedium == Medium::AIR) // AIR -> GLASS
nextMedium = Medium::GLASS;
vec3 direction_refraction = glm::normalize(refractedRay(ray.p0 - ray.p1, n, nextMedium));
vec3 pr = p + 1.0E10f * direction_refraction;
Ray recursiveRay_refraction(p + 0.0001f * direction_refraction, pr);
recursiveRay_refraction.currMedium = nextMedium;
vec3 I_R_refraction = intensity(recursiveRay_refraction, l, nLights, depth + 1);
for (int i = 0; i < 3; i++)
I[i] += k_t * I_R_refraction[i];
}
else // without refraction
{
vec3 I_R_translucent = intensity(ray, l, nLights, depth + 1, iObject);
for (int i = 0; i < 3; i++)
I[i] += k_t * I_R_translucent[i];
}
}
}
}
else I = I_back;
return I;
}
결과
굴절률 3/2
굴절률 1
Comments