vegetation: Now using sphere cap for leaves, to avoid flat effect

This commit is contained in:
Michaël Lemaire 2015-11-04 01:08:48 +01:00
parent f68bba75bb
commit 1e12b8ac9c
2 changed files with 26 additions and 10 deletions

View file

@ -158,9 +158,10 @@ void VegetationModelDefinition::randomize()
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
double radius = 0.15; double radius = 0.15;
double scale = randomizeValue(radius, 0.5, 1.0);
Vector3 dir = Vector3::randomInSphere(1.0 - radius); Vector3 dir = Vector3::randomInSphere(1.0 - radius);
Vector3 normal = dir.add(Vector3::randomInSphere(0.4)).add(Vector3(0.0, 0.3, 0.0)).normalize(); Vector3 normal = dir.add(Vector3::randomInSphere(0.4)).add(Vector3(0.0, 0.3, 0.0)).normalize();
Disk leaf(dir, normal, randomizeValue(radius, 0.8, 1.0)); Disk leaf(dir, normal, scale);
foliage_items.push_back(leaf); foliage_items.push_back(leaf);
} }
} }

View file

@ -69,11 +69,26 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
for (const auto &leaf: model->getFoliageItems()) for (const auto &leaf: model->getFoliageItems())
{ {
Disk sized_leaf(leaf.getPoint(), leaf.getNormal(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius()); Sphere leafcap(leaf.getPoint(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius());
if (sized_leaf.checkRayIntersection(subray, &near) == 1) // TODO Add cap intersection to Sphere class
Vector3 capnear, capfar;
if (leafcap.checkRayIntersection(subray, &capnear, &capfar) == 2)
{ {
near = near.scale(foliage.getRadius()).add(foliage.getCenter()); if (capnear.sub(leaf.getPoint()).normalize().dotProduct(leaf.getNormal()) < 0.5)
distance = ray.getCursor(near); {
if (capfar.sub(leaf.getPoint()).normalize().dotProduct(leaf.getNormal()) < 0.5)
{
continue;
}
else
{
capnear = capfar;
}
}
Vector3 capnormal = capnear.sub(leaf.getPoint()).normalize();
capnear = capnear.scale(foliage.getRadius()).add(foliage.getCenter());
distance = ray.getCursor(capnear);
if (distance >= 0.0 and distance <= maximal) if (distance >= 0.0 and distance <= maximal)
{ {
@ -89,8 +104,8 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
nearest = distance; nearest = distance;
hit = true; hit = true;
location = near; location = capnear;
normal = sized_leaf.getNormal(); normal = capnormal;
if (normal.dotProduct(location.sub(segment.getStart())) > 0.0) if (normal.dotProduct(location.sub(segment.getStart())) > 0.0)
{ {
@ -109,9 +124,9 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
if (hit) if (hit)
{ {
SurfaceMaterial material(result); SurfaceMaterial material(result);
material.reflection = 0.003; material.reflection = 0.001;
material.shininess = 3.0; material.shininess = 2.0;
material.hardness = 0.3; material.hardness = 0.1;
material.validate(); material.validate();
return VegetationResult(location, normal, material); return VegetationResult(location, normal, material);
} }