【发布时间】:2018-12-18 21:58:10
【问题描述】:
我正在研究光线追踪器,但是 我被困在阴影部分好几天了。 我的影子表现得很奇怪。这是光线追踪器的图像:
黑色部分应该是阴影。
光线的原点始终是 (0.f, -10.f, -500.f),因为这是透视投影,也就是相机的眼睛。当射线撞击平面时,撞击点始终是射线的原点,但对于球体则不同。它是不同的,因为它基于球体的位置。平面和球体之间永远不会有交集,因为原点是巨大的差异。 我也尝试在盒子上添加阴影,但这也不起作用。两个球体之间的阴影确实有效!
如果有人想看路口代码,请告诉我。
感谢您抽出宝贵时间帮助我!
相机
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);
}
相机设置
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;
}
场景对象
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);
场景灯光
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);
阴影功能
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.
}
}
【问题讨论】:
-
其实是在CalcDiffuseLight函数中作为引用传递的,不过我改了,大家就清楚了。这绝对是错误的..对不起!我会编辑它。 @geza
-
@geza 我添加了一张较旧的图片,两个球体上的阴影工作,除了盒子上。
-
在那张照片上,阴影不是黑色的。但是在您的第一张照片上,您有黑色像素(我想您没有将环境颜色更改为黑色)。您在某处没有一些浮点问题吗?南,inf?如果没有完整的源代码,很难说出问题所在。顺便说一句,将来,对您的图片应用一些伽玛校正,以获得更逼真的外观;)
-
黑色只是为了表明它是否是阴影。它只是将颜色硬编码为 0。我没有看到任何浮点问题。有没有可以显示完整源代码的程序? @geza
-
我肯定会研究 gamma,但现在我想从基础开始。我还需要补充:反射、菲涅耳、空间分区等等。
标签: c++ shader intersection trace