Optimization: replaced some divisions by inverse multiplications

This commit is contained in:
Michaël Lemaire 2014-08-20 16:45:45 +02:00
parent 14e0320848
commit 13904be001
10 changed files with 49 additions and 43 deletions

View file

@ -43,17 +43,17 @@ else
endif endif
run_cli:build run_cli:build
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/commandline/paysages-cli LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS)
run:build run:build
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS)
profile:build profile:build
LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g fp ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS) LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS)
perf report -g perf report -g
profile_cli:build profile_cli:build
LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g fp ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS) LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS)
perf report -g perf report -g
package:build package:build

View file

@ -45,7 +45,7 @@ void NoiseGenerator::save(PackStream* stream)
{ {
NoiseLevel* level = levels + x; NoiseLevel* level = levels + x;
stream->write(&level->wavelength); stream->write(&level->frequency);
stream->write(&level->amplitude); stream->write(&level->amplitude);
stream->write(&level->minvalue); stream->write(&level->minvalue);
} }
@ -69,7 +69,7 @@ void NoiseGenerator::load(PackStream* stream)
{ {
NoiseLevel* level = levels + x; NoiseLevel* level = levels + x;
stream->read(&level->wavelength); stream->read(&level->frequency);
stream->read(&level->amplitude); stream->read(&level->amplitude);
stream->read(&level->minvalue); stream->read(&level->minvalue);
} }
@ -215,7 +215,7 @@ void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxv
{ {
NoiseLevel level; NoiseLevel level;
level.wavelength = scaling; level.frequency = 1.0 / scaling;
level.minvalue = minvalue; level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue; level.amplitude = maxvalue - minvalue;
@ -230,7 +230,7 @@ void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double s
{ {
addLevel(start_level); addLevel(start_level);
start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor; start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor;
start_level.wavelength *= scaling_factor; start_level.frequency /= scaling_factor;
start_level.amplitude *= amplitude_factor; start_level.amplitude *= amplitude_factor;
} }
} }
@ -239,7 +239,7 @@ void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double min
{ {
NoiseLevel level; NoiseLevel level;
level.wavelength = scaling; level.frequency = 1.0 / scaling;
level.minvalue = minvalue; level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue; level.amplitude = maxvalue - minvalue;
addLevels(level_count, level, 0.5, 0.5, center_factor); addLevels(level_count, level, 0.5, 0.5, center_factor);
@ -284,7 +284,7 @@ void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue,
{ {
NoiseLevel level; NoiseLevel level;
level.wavelength = scaling; level.frequency = 1.0 / scaling;
level.minvalue = minvalue; level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue; level.amplitude = maxvalue - minvalue;
@ -313,7 +313,7 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad
levels[level].amplitude *= factor; levels[level].amplitude *= factor;
if (adjust_scaling) if (adjust_scaling)
{ {
levels[level].wavelength *= factor; levels[level].frequency /= factor;
} }
} }
height_offset = minvalue + (height_offset - current_minvalue) * factor; height_offset = minvalue + (height_offset - current_minvalue) * factor;
@ -371,7 +371,7 @@ static inline double _fixValue(double value, double ridge, double curve)
inline double NoiseGenerator::_get1DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x) inline double NoiseGenerator::_get1DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x)
{ {
return level->minvalue + _fixValue(_func_noise_1d(x / level->wavelength + offset.x), function.ridge_factor, function.curve_factor) * level->amplitude; return level->minvalue + _fixValue(_func_noise_1d(x * level->frequency + offset.x), function.ridge_factor, function.curve_factor) * level->amplitude;
} }
double NoiseGenerator::get1DLevel(int level, double x) double NoiseGenerator::get1DLevel(int level, double x)
@ -428,7 +428,7 @@ double NoiseGenerator::get1DDetail(double x, double detail)
inline double NoiseGenerator::_get2DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y) inline double NoiseGenerator::_get2DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y)
{ {
return level->minvalue + _fixValue(_func_noise_2d(x / level->wavelength + offset.x, y / level->wavelength + offset.y), function.ridge_factor, function.curve_factor) * level->amplitude; return level->minvalue + _fixValue(_func_noise_2d(x * level->frequency + offset.x, y * level->frequency + offset.y), function.ridge_factor, function.curve_factor) * level->amplitude;
} }
double NoiseGenerator::get2DLevel(int level, double x, double y) double NoiseGenerator::get2DLevel(int level, double x, double y)
@ -485,7 +485,7 @@ double NoiseGenerator::get2DDetail(double x, double y, double detail)
inline double NoiseGenerator::_get3DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z) inline double NoiseGenerator::_get3DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z)
{ {
return level->minvalue + _fixValue(_func_noise_3d(x / level->wavelength + offset.x, y / level->wavelength + offset.y, z / level->wavelength + offset.z), function.ridge_factor, function.curve_factor) * level->amplitude; return level->minvalue + _fixValue(_func_noise_3d(x * level->frequency + offset.x, y * level->frequency + offset.y, z * level->frequency + offset.z), function.ridge_factor, function.curve_factor) * level->amplitude;
} }
double NoiseGenerator::get3DLevel(int level, double x, double y, double z) double NoiseGenerator::get3DLevel(int level, double x, double y, double z)

View file

@ -28,7 +28,7 @@ public:
typedef struct typedef struct
{ {
double wavelength; double frequency;
double amplitude; double amplitude;
double minvalue; double minvalue;
} NoiseLevel; } NoiseLevel;

View file

@ -90,11 +90,14 @@ void CameraDefinition::validate()
projector = mperspective.mult(Matrix4::newLookAt(location, target, up)); projector = mperspective.mult(Matrix4::newLookAt(location, target, up));
unprojector = projector.inversed(); unprojector = projector.inversed();
inv_x_factor = 1.0 / (0.5 * width);
inv_y_factor = 1.0 / (0.5 * height);
} }
double CameraDefinition::getRealDepth(const Vector3 &projected) const double CameraDefinition::getRealDepth(const Vector3 &projected) const
{ {
Vector3 v(projected.x / (0.5 * width) - 1.0, -(projected.y / (0.5 * height) - 1.0), projected.z); Vector3 v(projected.x * inv_x_factor - 1.0, -(projected.y * inv_x_factor - 1.0), projected.z);
return unperspective.transform(v).z; return unperspective.transform(v).z;
} }

View file

@ -85,6 +85,8 @@ private:
Matrix4 projector; Matrix4 projector;
Matrix4 unprojector; Matrix4 unprojector;
Matrix4 unperspective; Matrix4 unperspective;
double inv_x_factor;
double inv_y_factor;
}; };
} }

View file

@ -9,13 +9,13 @@
#include "Scenery.h" #include "Scenery.h"
#include "RenderConfig.h" #include "RenderConfig.h"
void startRender(SoftwareRenderer *renderer, char *outputpath, const RenderConfig &params) void startRender(SoftwareCanvasRenderer *renderer, char *outputpath)
{ {
/*printf("\rRendering %s ... \n", outputpath); printf("\rRendering %s ... \n", outputpath);
renderer->start(params); renderer->render();
printf("\rSaving %s ... \n", outputpath); printf("\rSaving %s ... \n", outputpath);
remove(outputpath); remove(outputpath);
renderer->render_area->saveToFile(outputpath);*/ //renderer->render_area->saveToFile(outputpath);
} }
void displayHelp() void displayHelp()
@ -179,12 +179,13 @@ int main(int argc, char** argv)
camera->setLocation(camera->getLocation().add(step)); camera->setLocation(camera->getLocation().add(step));
renderer = new SoftwareCanvasRenderer(); renderer = new SoftwareCanvasRenderer();
renderer->setConfig(conf_render_params);
renderer->setScenery(scenery); renderer->setScenery(scenery);
if (outputcount >= conf_first_picture) if (outputcount >= conf_first_picture)
{ {
sprintf(outputpath, "output/pic%05d.png", outputcount); sprintf(outputpath, "output/pic%05d.png", outputcount);
startRender(renderer, outputpath, conf_render_params); startRender(renderer, outputpath);
} }
delete renderer; delete renderer;

View file

@ -282,7 +282,7 @@ void DialogNoise::addLevel()
NoiseGenerator::NoiseLevel level; NoiseGenerator::NoiseLevel level;
level.amplitude = 0.1; level.amplitude = 0.1;
level.wavelength = 0.1; level.frequency = 0.1;
_current->addLevel(level); _current->addLevel(level);
@ -330,7 +330,7 @@ void DialogNoise::levelChanged(int row)
((PreviewLevel*)previewLevel)->setLevel(row); ((PreviewLevel*)previewLevel)->setLevel(row);
slider_height->setValue(_current_level_params.amplitude * 1000.0); slider_height->setValue(_current_level_params.amplitude * 1000.0);
slider_scaling->setValue(_current_level_params.wavelength * 1000.0); slider_scaling->setValue(_current_level_params.frequency * 1000.0);
} }
// TODO else ... // TODO else ...
} }
@ -345,7 +345,7 @@ void DialogNoise::heightChanged(int value)
void DialogNoise::scalingChanged(int value) void DialogNoise::scalingChanged(int value)
{ {
_current_level_params.wavelength = ((double)value) / 1000.0; _current_level_params.frequency = ((double)value) / 1000.0;
_current->setLevel(_current_level, _current_level_params); _current->setLevel(_current_level, _current_level_params);
previewLevel->redraw(); previewLevel->redraw();
previewTotal->redraw(); previewTotal->redraw();

View file

@ -63,8 +63,8 @@ void CanvasPreview::setSize(int real_width, int real_height, int preview_width,
dirty_up = -1; dirty_up = -1;
scaled = (real_width != preview_height or real_height != preview_height); scaled = (real_width != preview_height or real_height != preview_height);
factor_x = (double)real_width / (double)preview_width; factor_x = (double)preview_width / (double)real_width;
factor_y = (double)real_height / (double)preview_height; factor_y = (double)preview_height / (double)real_height;
factor = factor_x * factor_y; factor = factor_x * factor_y;
lock->release(); lock->release();
@ -125,12 +125,10 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co
{ {
int x, y; int x, y;
lock->acquire();
if (scaled) if (scaled)
{ {
x = int(real_x / factor_x); x = int(real_x * factor_x);
y = int(real_y / factor_y); y = int(real_y * factor_y);
x = (x >= width) ? width - 1 : x; x = (x >= width) ? width - 1 : x;
y = (y >= height) ? height - 1 : y; y = (y >= height) ? height - 1 : y;
@ -143,10 +141,12 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co
CHECK_COORDINATES(x, y); CHECK_COORDINATES(x, y);
lock->acquire();
Color* pixel = pixels + (y * width + x); Color* pixel = pixels + (y * width + x);
pixel->r = pixel->r - old_color.r / factor + new_color.r / factor; pixel->r = pixel->r - old_color.r * factor + new_color.r * factor;
pixel->g = pixel->g - old_color.g / factor + new_color.g / factor; pixel->g = pixel->g - old_color.g * factor + new_color.g * factor;
pixel->b = pixel->b - old_color.b / factor + new_color.b / factor; pixel->b = pixel->b - old_color.b * factor + new_color.b * factor;
// Set pixel dirty // Set pixel dirty
if (x < dirty_left) if (x < dirty_left)

View file

@ -174,16 +174,16 @@ void Rasterizer::scanInterpolate(CameraDefinition* camera, ScanPoint* v1, ScanPo
{ {
Vector3 vec1(v1->pixel.x, v1->pixel.y, v1->pixel.z); Vector3 vec1(v1->pixel.x, v1->pixel.y, v1->pixel.z);
Vector3 vecdiff(diff->pixel.x, diff->pixel.y, diff->pixel.z); Vector3 vecdiff(diff->pixel.x, diff->pixel.y, diff->pixel.z);
double v1depth = camera->getRealDepth(vec1); double v1depth = 1.0 / camera->getRealDepth(vec1);
double v2depth = camera->getRealDepth(vec1.add(vecdiff)); double v2depth = 1.0 / camera->getRealDepth(vec1.add(vecdiff));
double factor = ((1.0 - value) / v1depth + value / v2depth); double factor = 1.0 / ((1.0 - value) * v1depth + value * v2depth);
result->pixel.x = v1->pixel.x + diff->pixel.x * value; result->pixel.x = v1->pixel.x + diff->pixel.x * value;
result->pixel.y = v1->pixel.y + diff->pixel.y * value; result->pixel.y = v1->pixel.y + diff->pixel.y * value;
result->pixel.z = v1->pixel.z + diff->pixel.z * value; result->pixel.z = v1->pixel.z + diff->pixel.z * value;
result->location.x = ((1.0 - value) * (v1->location.x / v1depth) + value * (v1->location.x + diff->location.x) / v2depth) / factor; result->location.x = ((1.0 - value) * (v1->location.x * v1depth) + value * (v1->location.x + diff->location.x) * v2depth) * factor;
result->location.y = ((1.0 - value) * (v1->location.y / v1depth) + value * (v1->location.y + diff->location.y) / v2depth) / factor; result->location.y = ((1.0 - value) * (v1->location.y * v1depth) + value * (v1->location.y + diff->location.y) * v2depth) * factor;
result->location.z = ((1.0 - value) * (v1->location.z / v1depth) + value * (v1->location.z + diff->location.z) / v2depth) / factor; result->location.z = ((1.0 - value) * (v1->location.z * v1depth) + value * (v1->location.z + diff->location.z) * v2depth) * factor;
result->client = v1->client; result->client = v1->client;
} }

View file

@ -40,10 +40,10 @@ double TexturesRenderer::getTriplanarNoise(NoiseGenerator *noise, const Vector3
double mXY = fabs(normal.z); double mXY = fabs(normal.z);
double mXZ = fabs(normal.y); double mXZ = fabs(normal.y);
double mYZ = fabs(normal.x); double mYZ = fabs(normal.x);
double total = mXY + mXZ + mYZ; double total = 1.0 / (mXY + mXZ + mYZ);
mXY /= total; mXY *= total;
mXZ /= total; mXZ *= total;
mYZ /= total; mYZ *= total;
return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ; return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ;
} }