P
Hallo alle zusammen,
ich sitze schon seit mehreren Wochen an einem Ray-Tracing Projekt.
Die Szene zeigt mehrere Kugeln in einer Cornell-Box.
Die Seiten der Cornell-Boxen passen auch soweit alle bis auf die Backplane.
Diese zeigt keine Reflektionen und nur eine schwarze (Roughness=1) und graue Textur bei (Metallness=1) an. Ich habe inzwischen das Gefühl, dass es an der Normalen liegt, das die negativ ist. Wenn ich diese jedoch nun flippe, dann ist die Plane nicht mehr sichtbar und der Hintergrund wird gerendert.
Zuerst hab ich vermutet, dass es die Intersection Funktion ist. Aber dort finde ich einfach nicht die Ursache für diesen Bug.
Mein Code zur Intersection:
TrianglePBR(
const Vector3& v0,
const Vector3& v1,
const Vector3& v2,
const Vector3& sc,
const float metallic = 0,
float roughness = 0,
float ambientOcclusion = 0)
{
mV0 = v0;
mV1 = v1;
mV2 = v2;
surfaceColor = sc;
mMetallic = metallic;
mRroughness = roughness;
mAmbientOcclusion = ambientOcclusion;
Vector3 v0v1 = mV1 - mV0;
Vector3 v0v2 = mV2 - mV0;
Vector3 N = cross(v0v1, v0v2);
normal = unit_vector(N);
}
bool TrianglePBR::intersect(Ray& ray, float t_min, float t_max, hit_record &rec) const
{
// plane normals
//Vector3 v0v1 = mV1 - mV0;
//Vector3 v0v2 = mV2 - mV0;
Vector3 N = normal;//cross(v0v1, v0v2);
float area2 = N.length();
// Step 1: finding P
float NdotRayDirection = dot(N, ray.direction());
// calculates the absolute value
if (std::fabs(NdotRayDirection) < 1e-8) // near zero
return false; // ray and triangle are parallel, so they do not intersect
// compute component d
float d = dot(N, mV0);
// compute t
rec.t = (dot(N, ray.origin()) + d) / NdotRayDirection;
// check if the triangle is behind the ray
if (rec.t < 0) return false;
rec.p = ray.origin() + rec.t * ray.direction();
// Step 2: inside, outside test
Vector3 C;
// edge0
Vector3 edge0 = mV1 - mV0;
Vector3 vp0 = rec.p - mV0;
C = cross(edge0, vp0);
if (dot(N, C) < 0) return false;
// edge1
Vector3 edge1 = mV2 - mV1;
Vector3 vp1 = rec.p - mV1;
C = cross(edge1, vp1);
if (dot(N, C) < 0) return false;
// edge2
Vector3 edge2 = mV0 - mV2;
Vector3 vp2 = rec.p - mV2;
C = cross(edge2, vp2);
if (dot(N, C) < 0) return false;
rec.normal = N;
/*if (NdotRayDirection < 0)
{
rec.normal = -N;
}
else
{
rec.normal = N;
}*/
return true; // ray hits the triangle
}
Hier nochmal der Code wo ich meine Objekte erstelle:
#ifdef PBR_SHADING
// Physical Based Shading
mWorld.Add(new SpherePBR(Vector3(-R - 0.3, -2.0, -1), 1, Vector3(0.933, 0.31, 1), 0.75, 0.35, 0.3));
mWorld.Add(new SpherePBR(Vector3(R + 0.9, -1.0, -0.5), R, Vector3(0.65, 0.77, 0.97), 0.25, 0.75, 0.3));
//mWorld.AddCube(Vector3(0, 0, 0), 5, 2, 6, Vector3(0.0, 0.0, 1.0), 0.75, 0.0, 0.3);
Plane planeBottom = mWorld.AddPlanePBR(Vector3(0, 0, 0), 5, 6, Vector3(0.0, 0.0, 1.0), 0.75, 0.0, 0.3);
planeBottom.Move(Vector3(0,0, 5.0));
Plane planeRight = mWorld.AddPlanePBR(Vector3(0, 0, 0), 5, 6, Vector3(0.0, 1.0, 0.0), 0.7, 0.0, 0.3);
planeRight.rotateY(90);
planeRight.Move(Vector3(-2.5, 0, -2.5));
Plane planeLeft = mWorld.AddPlanePBR(Vector3(0, 0, 0), 5, 6, Vector3(1.0, 0.0, 0.0), 0.7, 0.0, 0.3);
planeLeft.rotateX(180);
planeLeft.rotateY(90);
planeLeft.Move(Vector3(2.5, 0.0, -2.5));
Plane planeBack = mWorld.AddPlanePBR(Vector3(0, 0, 0), 2.5, 2.5, Vector3(0.0, 0.0, 1.0), 0.7, 0.0, 0.3);
planeBack.rotateX(90);
planeBack.Move(Vector3(0, -6.0, -2.5));
Plane planeTop = mWorld.AddPlanePBR(Vector3(0, 0, 0), 5, 6, Vector3(0.0, 0.0, 1.0), 0.7, 0.0, 0.3);
planeTop.rotateX(180);
planeTop.Move(Vector3(0, 0, 0.0));
#endif
mWorld.Add(new Light(Vector3(1.0, 1.0, 1.0), Vector3(-1, -0.0, -2.0), -2));
Falls ihr euch mein komplettes Projekt anschauen wollt und vll. noch weitere Anregungen geben wollt könnt ihr es in meinen öffentlichen Github Repository finden.
https://github.com/dekorlp/RayTracer
(Zur Info: Das Demoimage aus der Readme.md ist veraltet, da ich damals eine Zeile in der Intersection Methode auskommentiert hatte und die Plane hinter der Kamera war. Diese ist jedoch zwingend notwndig für die Schattenberechnung, welche ich noch implementieren will in Zukunft)
Vielen Dank im Vorraus für eure Hilfe
Mit freundlichen Grüßen
Dennis