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 "SurfaceMaterial.h"
|
||||
#include "FloatNode.h"
|
||||
#include "SkyRasterizer.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
@ -60,7 +61,7 @@ static void testGroundShadowQuality()
|
|||
renderer.setQuality(0.2);
|
||||
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);
|
||||
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()
|
||||
{
|
||||
testGroundShadowQuality();
|
||||
testRasterizationQuality();
|
||||
testCloudQuality();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent):
|
||||
parent(parent)
|
||||
{
|
||||
setQuality(0.5);
|
||||
}
|
||||
|
||||
BaseCloudLayerRenderer::~BaseCloudLayerRenderer()
|
||||
|
@ -23,6 +24,11 @@ bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightComponent *, con
|
|||
return false;
|
||||
}
|
||||
|
||||
void BaseCloudLayerRenderer::setQuality(double quality)
|
||||
{
|
||||
this->quality = quality;
|
||||
}
|
||||
|
||||
bool BaseCloudLayerRenderer::optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end)
|
||||
{
|
||||
Vector3 diff;
|
||||
|
|
|
@ -17,8 +17,11 @@ public:
|
|||
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 void setQuality(double quality);
|
||||
|
||||
protected:
|
||||
SoftwareRenderer* parent;
|
||||
double quality;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,13 +9,14 @@
|
|||
#include "LightComponent.h"
|
||||
#include "clouds/BaseCloudsModel.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
#include "Logs.h"
|
||||
|
||||
typedef struct
|
||||
struct CloudSegment
|
||||
{
|
||||
Vector3 start;
|
||||
Vector3 end;
|
||||
double length;
|
||||
} CloudSegment;
|
||||
};
|
||||
|
||||
CloudBasicLayerRenderer::CloudBasicLayerRenderer(SoftwareRenderer* parent):
|
||||
BaseCloudLayerRenderer(parent)
|
||||
|
@ -43,7 +44,7 @@ static inline double _getDistanceToBorder(BaseCloudsModel* model, Vector3 positi
|
|||
* @param out_segments Allocated space to fill found segments
|
||||
* @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;
|
||||
int inside, segment_count;
|
||||
|
@ -62,16 +63,7 @@ static int _findSegments(BaseCloudsModel* model, SoftwareRenderer* renderer, Vec
|
|||
model->getAltitudeRange(&ymin, &ymax);
|
||||
|
||||
model->getDetailRange(&min_step, &max_step);
|
||||
render_precision = 15.2 - 1.5 * (double)renderer->render_quality;
|
||||
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;
|
||||
}
|
||||
render_precision = max_step - quality * (max_step - min_step);
|
||||
if (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);
|
||||
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--)
|
||||
{
|
||||
SurfaceMaterial material(COLOR_WHITE);
|
||||
|
@ -224,7 +216,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent*
|
|||
double ymin, ymax;
|
||||
model->getAltitudeRange(&ymin, &ymax);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "BaseCloudLayerRenderer.h"
|
||||
|
||||
typedef struct CloudSegment CloudSegment;
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -21,6 +23,9 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
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):
|
||||
parent(parent)
|
||||
{
|
||||
quality = 0.5;
|
||||
enabled = true;
|
||||
fake_renderer = new BaseCloudLayerRenderer(parent);
|
||||
|
||||
|
@ -40,6 +41,15 @@ CloudsRenderer::~CloudsRenderer()
|
|||
delete fake_model;
|
||||
}
|
||||
|
||||
void CloudsRenderer::setQuality(double factor)
|
||||
{
|
||||
this->quality = factor;
|
||||
for (auto &renderer: layer_renderers)
|
||||
{
|
||||
renderer->setQuality(factor);
|
||||
}
|
||||
}
|
||||
|
||||
void CloudsRenderer::setEnabled(bool enabled)
|
||||
{
|
||||
this->enabled = enabled;
|
||||
|
@ -94,6 +104,8 @@ void CloudsRenderer::update()
|
|||
layer_models.push_back(model);
|
||||
model->update();
|
||||
}
|
||||
|
||||
setQuality(quality);
|
||||
}
|
||||
|
||||
BaseCloudLayerRenderer* CloudsRenderer::getLayerRenderer(unsigned int layer)
|
||||
|
|
|
@ -17,6 +17,11 @@ public:
|
|||
CloudsRenderer(SoftwareRenderer* parent);
|
||||
virtual ~CloudsRenderer();
|
||||
|
||||
/**
|
||||
* Set the quality factor (0.0-1.0) for clouds rendering.
|
||||
*/
|
||||
void setQuality(double factor);
|
||||
|
||||
/**
|
||||
* Enable or disable the whole cloud rendering.
|
||||
*/
|
||||
|
@ -63,6 +68,8 @@ public:
|
|||
*/
|
||||
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
||||
private:
|
||||
double quality;
|
||||
|
||||
bool enabled;
|
||||
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
|
||||
{
|
||||
return progress->get();
|
||||
|
|
|
@ -23,10 +23,18 @@ public:
|
|||
virtual ~SoftwareCanvasRenderer();
|
||||
|
||||
inline const Canvas *getCanvas() const {return canvas;}
|
||||
inline RenderProgress *getProgressHelper() const {return progress;}
|
||||
inline bool isFinished() const {return finished;}
|
||||
|
||||
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).
|
||||
*/
|
||||
|
|
|
@ -90,6 +90,7 @@ void SoftwareRenderer::prepare()
|
|||
void SoftwareRenderer::setQuality(double quality)
|
||||
{
|
||||
terrain_renderer->setQuality(quality);
|
||||
clouds_renderer->setQuality(quality);
|
||||
|
||||
// TEMP compat with old code
|
||||
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);
|
||||
thickness = max_altitude - min_altitude;
|
||||
*min_step = thickness * 0.001;
|
||||
*max_step = thickness * 0.05;
|
||||
*max_step = thickness * 0.2;
|
||||
}
|
||||
|
||||
double BaseCloudsModel::getProbability(const Vector3 &, double) const
|
||||
|
|
Loading…
Reference in a new issue