Refactored clouds rendering quality factor
This commit is contained in:
parent
6a8fc7b102
commit
cd7eb2f669
11 changed files with 84 additions and 17 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
#include "FloatNode.h"
|
#include "FloatNode.h"
|
||||||
|
#include "SkyRasterizer.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ static void testGroundShadowQuality()
|
||||||
renderer.setQuality(0.2);
|
renderer.setQuality(0.2);
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
// TODO keep same rasterization across renders, or keep rasterization quality low
|
// TODO keep same rasterization across renders
|
||||||
renderer.getTerrainRenderer()->setQuality((double)i / 5.0);
|
renderer.getTerrainRenderer()->setQuality((double)i / 5.0);
|
||||||
startTestRender(&renderer, "ground_shadow_quality", i);
|
startTestRender(&renderer, "ground_shadow_quality", i);
|
||||||
}
|
}
|
||||||
|
@ -81,9 +82,31 @@ static void testRasterizationQuality()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void testCloudQuality()
|
||||||
|
{
|
||||||
|
Scenery scenery;
|
||||||
|
scenery.autoPreset(3);
|
||||||
|
scenery.getCamera()->setLocation(Vector3(5.0, 5.0, 5.0));
|
||||||
|
scenery.getCamera()->setTarget(Vector3(8.0, 7.25, 8.0));
|
||||||
|
scenery.getTerrain()->height = 0.0;
|
||||||
|
scenery.getTerrain()->validate();
|
||||||
|
|
||||||
|
SoftwareCanvasRenderer renderer(&scenery);
|
||||||
|
renderer.setSize(600, 800);
|
||||||
|
SkyRasterizer *rasterizer = new SkyRasterizer(&renderer, renderer.getProgressHelper(), 0);
|
||||||
|
renderer.setSoloRasterizer(rasterizer);
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
renderer.setQuality((double)i / 5.0);
|
||||||
|
rasterizer->setQuality(0.2);
|
||||||
|
startTestRender(&renderer, "cloud_quality", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void runTestSuite()
|
void runTestSuite()
|
||||||
{
|
{
|
||||||
testGroundShadowQuality();
|
testGroundShadowQuality();
|
||||||
testRasterizationQuality();
|
testRasterizationQuality();
|
||||||
|
testCloudQuality();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent):
|
BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent):
|
||||||
parent(parent)
|
parent(parent)
|
||||||
{
|
{
|
||||||
|
setQuality(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseCloudLayerRenderer::~BaseCloudLayerRenderer()
|
BaseCloudLayerRenderer::~BaseCloudLayerRenderer()
|
||||||
|
@ -23,6 +24,11 @@ bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightComponent *, con
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseCloudLayerRenderer::setQuality(double quality)
|
||||||
|
{
|
||||||
|
this->quality = quality;
|
||||||
|
}
|
||||||
|
|
||||||
bool BaseCloudLayerRenderer::optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end)
|
bool BaseCloudLayerRenderer::optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end)
|
||||||
{
|
{
|
||||||
Vector3 diff;
|
Vector3 diff;
|
||||||
|
|
|
@ -17,8 +17,11 @@ public:
|
||||||
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location);
|
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location);
|
||||||
virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location);
|
virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location);
|
||||||
|
|
||||||
|
virtual void setQuality(double quality);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SoftwareRenderer* parent;
|
SoftwareRenderer* parent;
|
||||||
|
double quality;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,14 @@
|
||||||
#include "LightComponent.h"
|
#include "LightComponent.h"
|
||||||
#include "clouds/BaseCloudsModel.h"
|
#include "clouds/BaseCloudsModel.h"
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
typedef struct
|
struct CloudSegment
|
||||||
{
|
{
|
||||||
Vector3 start;
|
Vector3 start;
|
||||||
Vector3 end;
|
Vector3 end;
|
||||||
double length;
|
double length;
|
||||||
} CloudSegment;
|
};
|
||||||
|
|
||||||
CloudBasicLayerRenderer::CloudBasicLayerRenderer(SoftwareRenderer* parent):
|
CloudBasicLayerRenderer::CloudBasicLayerRenderer(SoftwareRenderer* parent):
|
||||||
BaseCloudLayerRenderer(parent)
|
BaseCloudLayerRenderer(parent)
|
||||||
|
@ -43,7 +44,7 @@ static inline double _getDistanceToBorder(BaseCloudsModel* model, Vector3 positi
|
||||||
* @param out_segments Allocated space to fill found segments
|
* @param out_segments Allocated space to fill found segments
|
||||||
* @return Number of segments found
|
* @return Number of segments found
|
||||||
*/
|
*/
|
||||||
static int _findSegments(BaseCloudsModel* model, SoftwareRenderer* renderer, Vector3 start, Vector3 direction, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments)
|
int CloudBasicLayerRenderer::findSegments(BaseCloudsModel *model, const Vector3 &start, const Vector3 &direction, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments)
|
||||||
{
|
{
|
||||||
double ymin, ymax;
|
double ymin, ymax;
|
||||||
int inside, segment_count;
|
int inside, segment_count;
|
||||||
|
@ -62,16 +63,7 @@ static int _findSegments(BaseCloudsModel* model, SoftwareRenderer* renderer, Vec
|
||||||
model->getAltitudeRange(&ymin, &ymax);
|
model->getAltitudeRange(&ymin, &ymax);
|
||||||
|
|
||||||
model->getDetailRange(&min_step, &max_step);
|
model->getDetailRange(&min_step, &max_step);
|
||||||
render_precision = 15.2 - 1.5 * (double)renderer->render_quality;
|
render_precision = max_step - quality * (max_step - min_step);
|
||||||
render_precision = render_precision * (ymax - ymin) / 50.0;
|
|
||||||
if (render_precision < min_step)
|
|
||||||
{
|
|
||||||
render_precision = min_step;
|
|
||||||
}
|
|
||||||
else if (render_precision > max_step)
|
|
||||||
{
|
|
||||||
render_precision = max_step;
|
|
||||||
}
|
|
||||||
if (render_precision > max_total_length / 10.0)
|
if (render_precision > max_total_length / 10.0)
|
||||||
{
|
{
|
||||||
render_precision = max_total_length / 10.0;
|
render_precision = max_total_length / 10.0;
|
||||||
|
@ -173,7 +165,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
|
||||||
model->getAltitudeRange(&ymin, &ymax);
|
model->getAltitudeRange(&ymin, &ymax);
|
||||||
double transparency_depth = (ymax - ymin) * 0.5;
|
double transparency_depth = (ymax - ymin) * 0.5;
|
||||||
|
|
||||||
segment_count = _findSegments(model, parent, start, direction, 20, transparency_depth, max_length, &inside_length, &total_length, segments);
|
segment_count = findSegments(model, start, direction, 20, transparency_depth, max_length, &inside_length, &total_length, segments);
|
||||||
for (i = segment_count - 1; i >= 0; i--)
|
for (i = segment_count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
SurfaceMaterial material(COLOR_WHITE);
|
SurfaceMaterial material(COLOR_WHITE);
|
||||||
|
@ -224,7 +216,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent*
|
||||||
double ymin, ymax;
|
double ymin, ymax;
|
||||||
model->getAltitudeRange(&ymin, &ymax);
|
model->getAltitudeRange(&ymin, &ymax);
|
||||||
double light_traversal = (ymax - ymin) * 1.2;
|
double light_traversal = (ymax - ymin) * 1.2;
|
||||||
_findSegments(model, parent, start, direction, 20, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth, segments);
|
findSegments(model, start, direction, 20, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth, segments);
|
||||||
|
|
||||||
if (light_traversal < 0.0001)
|
if (light_traversal < 0.0001)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include "BaseCloudLayerRenderer.h"
|
#include "BaseCloudLayerRenderer.h"
|
||||||
|
|
||||||
|
typedef struct CloudSegment CloudSegment;
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace software {
|
namespace software {
|
||||||
|
|
||||||
|
@ -21,6 +23,9 @@ public:
|
||||||
|
|
||||||
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location) override;
|
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location) override;
|
||||||
virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location) override;
|
virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int findSegments(BaseCloudsModel* model, const Vector3 &start, const Vector3 &direction, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
CloudsRenderer::CloudsRenderer(SoftwareRenderer* parent):
|
CloudsRenderer::CloudsRenderer(SoftwareRenderer* parent):
|
||||||
parent(parent)
|
parent(parent)
|
||||||
{
|
{
|
||||||
|
quality = 0.5;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
fake_renderer = new BaseCloudLayerRenderer(parent);
|
fake_renderer = new BaseCloudLayerRenderer(parent);
|
||||||
|
|
||||||
|
@ -40,6 +41,15 @@ CloudsRenderer::~CloudsRenderer()
|
||||||
delete fake_model;
|
delete fake_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloudsRenderer::setQuality(double factor)
|
||||||
|
{
|
||||||
|
this->quality = factor;
|
||||||
|
for (auto &renderer: layer_renderers)
|
||||||
|
{
|
||||||
|
renderer->setQuality(factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CloudsRenderer::setEnabled(bool enabled)
|
void CloudsRenderer::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
this->enabled = enabled;
|
this->enabled = enabled;
|
||||||
|
@ -94,6 +104,8 @@ void CloudsRenderer::update()
|
||||||
layer_models.push_back(model);
|
layer_models.push_back(model);
|
||||||
model->update();
|
model->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setQuality(quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseCloudLayerRenderer* CloudsRenderer::getLayerRenderer(unsigned int layer)
|
BaseCloudLayerRenderer* CloudsRenderer::getLayerRenderer(unsigned int layer)
|
||||||
|
|
|
@ -17,6 +17,11 @@ public:
|
||||||
CloudsRenderer(SoftwareRenderer* parent);
|
CloudsRenderer(SoftwareRenderer* parent);
|
||||||
virtual ~CloudsRenderer();
|
virtual ~CloudsRenderer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the quality factor (0.0-1.0) for clouds rendering.
|
||||||
|
*/
|
||||||
|
void setQuality(double factor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable the whole cloud rendering.
|
* Enable or disable the whole cloud rendering.
|
||||||
*/
|
*/
|
||||||
|
@ -63,6 +68,8 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
||||||
private:
|
private:
|
||||||
|
double quality;
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
SoftwareRenderer* parent;
|
SoftwareRenderer* parent;
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,16 @@ void SoftwareCanvasRenderer::setQuality(double factor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftwareCanvasRenderer::setSoloRasterizer(Rasterizer *rasterizer)
|
||||||
|
{
|
||||||
|
for (auto &rast: rasterizers)
|
||||||
|
{
|
||||||
|
delete rast;
|
||||||
|
}
|
||||||
|
rasterizers.clear();
|
||||||
|
rasterizers.push_back(rasterizer);
|
||||||
|
}
|
||||||
|
|
||||||
double SoftwareCanvasRenderer::getProgress() const
|
double SoftwareCanvasRenderer::getProgress() const
|
||||||
{
|
{
|
||||||
return progress->get();
|
return progress->get();
|
||||||
|
|
|
@ -23,10 +23,18 @@ public:
|
||||||
virtual ~SoftwareCanvasRenderer();
|
virtual ~SoftwareCanvasRenderer();
|
||||||
|
|
||||||
inline const Canvas *getCanvas() const {return canvas;}
|
inline const Canvas *getCanvas() const {return canvas;}
|
||||||
|
inline RenderProgress *getProgressHelper() const {return progress;}
|
||||||
inline bool isFinished() const {return finished;}
|
inline bool isFinished() const {return finished;}
|
||||||
|
|
||||||
virtual void setQuality(double factor) override;
|
virtual void setQuality(double factor) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the rasterizers list, and put a single one.
|
||||||
|
*
|
||||||
|
* The renderer takes ownership of the rasterizer.
|
||||||
|
*/
|
||||||
|
void setSoloRasterizer(Rasterizer *rasterizer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the global rendering progress (0.0-1.0).
|
* Get the global rendering progress (0.0-1.0).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -90,6 +90,7 @@ void SoftwareRenderer::prepare()
|
||||||
void SoftwareRenderer::setQuality(double quality)
|
void SoftwareRenderer::setQuality(double quality)
|
||||||
{
|
{
|
||||||
terrain_renderer->setQuality(quality);
|
terrain_renderer->setQuality(quality);
|
||||||
|
clouds_renderer->setQuality(quality);
|
||||||
|
|
||||||
// TEMP compat with old code
|
// TEMP compat with old code
|
||||||
render_quality = (int)(quality * 9.0) + 1;
|
render_quality = (int)(quality * 9.0) + 1;
|
||||||
|
|
|
@ -27,7 +27,7 @@ void BaseCloudsModel::getDetailRange(double *min_step, double *max_step) const
|
||||||
getAltitudeRange(&min_altitude, &max_altitude);
|
getAltitudeRange(&min_altitude, &max_altitude);
|
||||||
thickness = max_altitude - min_altitude;
|
thickness = max_altitude - min_altitude;
|
||||||
*min_step = thickness * 0.001;
|
*min_step = thickness * 0.001;
|
||||||
*max_step = thickness * 0.05;
|
*max_step = thickness * 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
double BaseCloudsModel::getProbability(const Vector3 &, double) const
|
double BaseCloudsModel::getProbability(const Vector3 &, double) const
|
||||||
|
|
Loading…
Reference in a new issue