ich ein ray tracer:Probleme mit Lambert'sches Schattierung und Schatten (Raytracing)
gemacht habe und ich habe den Blinn-Phong-Algorithmus wurde die Umsetzung, aber ich habe zu einigen Fragen kommen, wenn in bestimmten Situationen (otherwise it works quite well) Rendering
wenn eine Kugel in der Luft schweben, ist Lambert'sches Schattierung nicht richtig funktioniert (scheint geschieht nur, wenn die Kugel über der Lichtquellenposition ist) - Screenshot
Bei der Lichtquelle unterhalb sphere - Screenshot
als ein Schatten auf eine Kugel geworfen wird (kann auch im 1. Beispiel zu sehen) - Screenshot
Wenn es mehr als 1-Ebene in der Szene (nur wenn Schatten sind auf) - Screenshot
ich gehe davon aus es etwas falsch mit meinem Schatten und Lambert'sches Shading-Algorithmen ist, aber ich bin nicht sicher, was könnte jemand helfen?
-Code (es gibt keine externen Bibliotheken, nur kompilieren):
Color finalColor;
Color ambient;
Color diffuse;
FPType lambertian;
FPType phong;
Color specular;
bool shadowed = false;
// Ambient
if(AMBIENT_ON)
{
ambient = closestObjectMaterial.GetColor() * AMBIENT_LIGHT * closestObjectMaterial.GetAmbient();
finalColor += ambient;
}
// Shadows, Diffuse, Specular
for(const auto &lightSource : lightSources)
{
Vector lightDir = (lightSource->GetPosition() - point); // Calculate the directional vector towards the lightSource
FPType distance = lightDir.Magnitude();
lightDir = lightDir.Normalize();
lambertian = closestObjectNormal.Dot(lightDir);
// Shadows
if(SHADOWS_ON && lambertian > 0)
{
Ray shadowRay(point, lightDir); // Cast a ray from the first intersection to the light
std::vector<FPType> secondaryIntersections;
for(const auto &sceneObject : sceneObjects)
{
secondaryIntersections.push_back(sceneObject->GetIntersection(shadowRay));
}
for(const auto &secondaryIntersection : secondaryIntersections)
{
if(secondaryIntersection > TOLERANCE) // If shadow ray intersects with some object along the way
{
shadowed = true;
finalColor *= closestObjectMaterial.GetDiffuse() * AMBIENT_LIGHT;
break;
}
}
}
// Diffuse
if(DIFFUSE_ON && shadowed == false)
{
diffuse = closestObjectMaterial.GetColor().Average(lightSource->GetColor()) * closestObjectMaterial.GetDiffuse() * lightSource->GetIntensity() * std::fmax(lambertian, 0)/distance;
finalColor += diffuse;
}
if(shadowed == false && SPECULAR_ON)
{
// Specular
if(closestObjectMaterial.GetSpecular() > 0 && closestObjectMaterial.GetSpecular() <= 1)
{
Vector V = -sceneDirection;
// Blinn-Phong
Vector H = (lightDir + V).Normalize();
FPType NdotH = closestObjectNormal.Dot(H);
phong = pow(NdotH, 300);
specular = lightSource->GetColor() * std::fmax(0, phong) * lightSource->GetIntensity()/distance; // closestObjectMaterial.GetSpecular(); add or no?
finalColor += specular;
}
}
}
FPType Sphere::GetIntersection(Ray ray)
{
Vector length = center - ray.GetOrigin(); // Length of the vector between the center and the ray origin (hypotenuse)
FPType tca = length.Dot(ray.GetDirection()); // opposide side
if(tca < 0) // No intersection registered
return -1;
if(tca > 0) // Intersection registered
{
FPType a = sqrt(length.Dot(length) - tca*tca); // Adjacent side (a = sqrt(c²-b²))
if(a > radius || a < 0)
return -1;
FPType thc = sqrt(radius*radius - a*a); // the line between 2 intersection points/2
FPType primaryIntersection;
primaryIntersection = tca - thc;
if(primaryIntersection > 0)
return primaryIntersection;
else
{
FPType secondaryIntersection = thc + tca;
return secondaryIntersection;
}
}
return -1;
}
Kann 'GetIntersection' eine negative Zahl zurückgeben? – 1201ProgramAlarm
Hinzugefügt GetIntersection Code für Kugeln –