I am working on a ray tracer, but I am stuck for days on the shadow part. My shadow is acting really weird. Here is an image of the ray tracer:
The black part should be the shadow.
The origin of the ray is always (0.f, -10.f, -500.f), because this is a perspective projection and that is the eye of the camera. When the ray hits a plane, the hit point is always the origin of the ray, but with the sphere it is different. It is different because it is based on the position of the sphere. There is never an intersection between the plane and sphere because the origin is huge difference. I also tried to add shadow on a box, but this doesn't work either. The shadow between two spheres does work!
If someone wants to see the intersection code, let me know.
Thanks for taking the time to help me!
Camera
Camera::Camera(float a_fFov, const Dimension& a_viewDimension, vec3 a_v3Eye, vec3 a_v3Center, vec3 a_v3Up) :
m_fFov(a_fFov),
m_viewDimension(a_viewDimension),
m_v3Eye(a_v3Eye),
m_v3Center(a_v3Center),
m_v3Up(a_v3Up)
{
// Calculate the x, y and z axis
vec3 v3ViewDirection = (m_v3Eye - m_v3Center).normalize();
vec3 v3U = m_v3Up.cross(v3ViewDirection).normalize();
vec3 v3V = v3ViewDirection.cross(v3U);
// Calculate the aspect ratio of the screen
float fAspectRatio = static_cast<float>(m_viewDimension.m_iHeight) /
static_cast<float>(m_viewDimension.m_iWidth);
float fViewPlaneHalfWidth = tanf(m_fFov / 2.f);
float fViewPlaneHalfHeight = fAspectRatio * fViewPlaneHalfWidth;
// The bottom left of the plane
m_v3ViewPlaneBottomLeft = m_v3Center - v3V * fViewPlaneHalfHeight - v3U * fViewPlaneHalfWidth;
// The amount we need to increment to get the direction. The width and height are based on the field of view.
m_v3IncrementX = (v3U * 2.f * fViewPlaneHalfWidth);
m_v3IncrementY = (v3V * 2.f * fViewPlaneHalfHeight);
}
Camera::~Camera()
{
}
const Ray Camera::GetCameraRay(float iPixelX, float iPixelY) const
{
vec3 v3Target = m_v3ViewPlaneBottomLeft + m_v3IncrementX * iPixelX + m_v3IncrementY * iPixelY;
vec3 v3Direction = (v3Target - m_v3Eye).normalize();
return Ray(m_v3Eye, v3Direction);
}
Camera setup
Scene::Scene(const Dimension& a_Dimension) :
m_Camera(1.22173f, a_Dimension, vec3(0.f, -10.f, -500.f), vec3(0.f, 0.f, 0.f), vec3(0.f, 1.f, 0.f))
{
// Setup sky light
Color ambientLightColor(0.2f, 0.1f, 0.1f);
m_AmbientLight = new AmbientLight(0.1f, ambientLightColor);
// Setup shapes
CreateShapes();
// Setup lights
CreateLights();
// Setup buas
m_fBias = 1.f;
}
Scene objects
Sphere* sphere2 = new Sphere();
sphere2->SetRadius(50.f);
sphere2->SetCenter(vec3(0.f, 0.f, 0.f));
sphere2->SetMaterial(matte3);
Plane* plane = new Plane(true);
plane->SetNormal(vec3(0.f, 1.f, 0.f));
plane->SetPoint(vec3(0.f, 0.f, 0.f));
plane->SetMaterial(matte1);
Scene light
PointLight* pointLight1 = new PointLight(1.f, Color(0.1f, 0.5f, 0.7f), vec3(0.f, -200.f, 0.f), 1.f, 0.09f, 0.032f);
Shade function
for (const Light* light : a_Lights) {
vec3 v3LightDirection = (light->m_v3Position - a_Contact.m_v3Hitpoint).normalized();
light->CalcDiffuseLight(a_Contact.m_v3Point, a_Contact.m_v3Normal, m_fKd, lightColor);
Ray lightRay(a_Contact.m_v3Point + a_Contact.m_v3Normal * a_fBias, v3LightDirection);
bool test = a_RayTracer.ShadowTrace(lightRay, a_Shapes);
vec3 normTest = a_Contact.m_v3Normal;
float test2 = normTest.dot(v3LightDirection);
// No shadow
if (!test) {
a_ResultColor += lightColor * !test * test2;
}
else {
a_ResultColor = Color(); // Test code - change color to black.
}
}
Real-Time Ray Tracing is the biggest leap in computer graphics in years, bringing realistic lighting, shadows and effects to games, enhancing image quality, gameplay and immersion.
A major disadvantage of ray tracing is that its computation complexity is about square of object number. More object on the scene, much more time needed for rendering. Some optimal methods are available to enhance efficient of ray tracing.
Shadow UltraCapable of up to 4K resolution with ray-tracing on (that's super fancy lighting and shadows if you didn't know), you'll be the envy of all your console obsessed and PC master race friends. With the Shadow Ultra plan, you'll be able to run the latest games without breaking a computational sweat.
Compared to traditional shadow mapping techniques, ray-traced shadows have realistic penumbras, translucency, self-shadowing, and other benefits, creating contact-hardened, smooth shadows that would otherwise be impossible to render in real-time.
You have several bugs:
Sphere::Collides
, m_fCollisionTime
is not set, when t2>=t1
Sphere::Collides
, if m_fCollisionTime
is negative, then the ray actually doesn't intersect with the sphere (this causes the strange shadow on the top of the ball)With these fixed, you'll get this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With