2013-12-01 18:24:53 +00:00
|
|
|
#include "SkyRasterizer.h"
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-12-01 18:24:53 +00:00
|
|
|
#include "Vector3.h"
|
|
|
|
#include "Color.h"
|
|
|
|
#include "SoftwareRenderer.h"
|
|
|
|
#include "AtmosphereRenderer.h"
|
2013-12-08 19:54:34 +00:00
|
|
|
#include "AtmosphereResult.h"
|
2013-12-01 18:24:53 +00:00
|
|
|
#include "CloudsRenderer.h"
|
2014-06-12 15:45:59 +00:00
|
|
|
#include "Rasterizer.h"
|
2014-08-18 10:17:16 +00:00
|
|
|
#include "CanvasFragment.h"
|
2015-08-23 18:22:37 +00:00
|
|
|
#include "RenderProgress.h"
|
2015-09-29 20:31:25 +00:00
|
|
|
#include "GodRaysSampler.h"
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-12-01 18:24:53 +00:00
|
|
|
#define SPHERE_SIZE 20000.0
|
|
|
|
|
2015-08-23 18:22:37 +00:00
|
|
|
SkyRasterizer::SkyRasterizer(SoftwareRenderer* renderer, RenderProgress *progress, int client_id):
|
|
|
|
Rasterizer(renderer, progress, client_id, Color(0.9, 0.9, 1.0))
|
2013-12-01 18:24:53 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-08-23 18:22:37 +00:00
|
|
|
int SkyRasterizer::prepareRasterization()
|
|
|
|
{
|
|
|
|
return res_i * res_j;
|
|
|
|
}
|
|
|
|
|
2014-06-12 15:45:59 +00:00
|
|
|
void SkyRasterizer::rasterizeToCanvas(CanvasPortion* canvas)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
double step_i, step_j;
|
|
|
|
double current_i, current_j;
|
|
|
|
Vector3 vertex1, vertex2, vertex3, vertex4;
|
|
|
|
Vector3 camera_location, direction;
|
|
|
|
|
|
|
|
step_i = M_PI * 2.0 / (double)res_i;
|
|
|
|
step_j = M_PI / (double)res_j;
|
|
|
|
|
|
|
|
camera_location = renderer->getCameraLocation(VECTOR_ZERO);
|
|
|
|
|
|
|
|
for (j = 0; j < res_j; j++)
|
|
|
|
{
|
2014-08-19 09:44:54 +00:00
|
|
|
if (interrupted)
|
2014-06-12 15:45:59 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
current_j = (double)(j - res_j / 2) * step_j;
|
|
|
|
|
|
|
|
for (i = 0; i < res_i; i++)
|
|
|
|
{
|
|
|
|
current_i = (double)i * step_i;
|
|
|
|
|
|
|
|
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
|
|
|
|
direction.y = SPHERE_SIZE * sin(current_j);
|
|
|
|
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
|
|
|
|
vertex1 = camera_location.add(direction);
|
|
|
|
|
|
|
|
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
|
|
|
|
direction.y = SPHERE_SIZE * sin(current_j);
|
|
|
|
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
|
|
|
|
vertex2 = camera_location.add(direction);
|
|
|
|
|
|
|
|
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
|
|
|
|
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
|
|
|
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
|
|
|
|
vertex3 = camera_location.add(direction);
|
|
|
|
|
|
|
|
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
|
|
|
|
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
|
|
|
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
|
|
|
|
vertex4 = camera_location.add(direction);
|
|
|
|
|
2015-09-29 20:31:25 +00:00
|
|
|
// TODO Triangles at poles
|
2014-06-12 15:45:59 +00:00
|
|
|
pushQuad(canvas, vertex1, vertex4, vertex3, vertex2);
|
|
|
|
}
|
2015-08-23 18:22:37 +00:00
|
|
|
progress->add(res_i);
|
2014-06-12 15:45:59 +00:00
|
|
|
}
|
|
|
|
}
|
2014-08-18 10:17:16 +00:00
|
|
|
|
2015-10-15 22:51:46 +00:00
|
|
|
Color SkyRasterizer::shadeFragment(const CanvasFragment &fragment, const CanvasFragment *) const
|
2014-08-18 10:17:16 +00:00
|
|
|
{
|
|
|
|
Vector3 location = fragment.getLocation();
|
|
|
|
Vector3 camera_location, direction;
|
|
|
|
Color result;
|
|
|
|
|
|
|
|
camera_location = renderer->getCameraLocation(location);
|
|
|
|
direction = location.sub(camera_location);
|
|
|
|
|
2015-09-29 20:31:25 +00:00
|
|
|
// TODO Don't compute sky color if it's fully covered by clouds
|
2014-08-18 10:17:16 +00:00
|
|
|
result = renderer->getAtmosphereRenderer()->getSkyColor(direction.normalize()).final;
|
|
|
|
result = renderer->getCloudsRenderer()->getColor(camera_location, camera_location.add(direction.scale(10.0)), result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2015-09-10 17:33:52 +00:00
|
|
|
|
|
|
|
void SkyRasterizer::setQuality(int res_i, int res_j)
|
|
|
|
{
|
|
|
|
this->res_i = res_i;
|
|
|
|
this->res_j = res_j;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkyRasterizer::setQuality(double factor)
|
|
|
|
{
|
|
|
|
setQuality(20.0 * (1.0 + factor * 10.0), 10.0 * (1.0 + factor * 10.0));
|
|
|
|
}
|