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++)
{
double radius = 0.15;
double scale = randomizeValue(radius, 0.5, 1.0);
Vector3 dir = Vector3::randomInSphere(1.0 - radius);
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);
}
}

View file

@ -69,11 +69,26 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
for (const auto &leaf: model->getFoliageItems())
{
Disk sized_leaf(leaf.getPoint(), leaf.getNormal(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius());
if (sized_leaf.checkRayIntersection(subray, &near) == 1)
Sphere leafcap(leaf.getPoint(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius());
// 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());
distance = ray.getCursor(near);
if (capnear.sub(leaf.getPoint()).normalize().dotProduct(leaf.getNormal()) < 0.5)
{
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)
{
@ -89,8 +104,8 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
nearest = distance;
hit = true;
location = near;
normal = sized_leaf.getNormal();
location = capnear;
normal = capnormal;
if (normal.dotProduct(location.sub(segment.getStart())) > 0.0)
{
@ -109,9 +124,9 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
if (hit)
{
SurfaceMaterial material(result);
material.reflection = 0.003;
material.shininess = 3.0;
material.hardness = 0.3;
material.reflection = 0.001;
material.shininess = 2.0;
material.hardness = 0.1;
material.validate();
return VegetationResult(location, normal, material);
}