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
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
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
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
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
package:build

View file

@ -45,7 +45,7 @@ void NoiseGenerator::save(PackStream* stream)
{
NoiseLevel* level = levels + x;
stream->write(&level->wavelength);
stream->write(&level->frequency);
stream->write(&level->amplitude);
stream->write(&level->minvalue);
}
@ -69,7 +69,7 @@ void NoiseGenerator::load(PackStream* stream)
{
NoiseLevel* level = levels + x;
stream->read(&level->wavelength);
stream->read(&level->frequency);
stream->read(&level->amplitude);
stream->read(&level->minvalue);
}
@ -215,7 +215,7 @@ void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxv
{
NoiseLevel level;
level.wavelength = scaling;
level.frequency = 1.0 / scaling;
level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue;
@ -230,7 +230,7 @@ void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double s
{
addLevel(start_level);
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;
}
}
@ -239,7 +239,7 @@ void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double min
{
NoiseLevel level;
level.wavelength = scaling;
level.frequency = 1.0 / scaling;
level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue;
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;
level.wavelength = scaling;
level.frequency = 1.0 / scaling;
level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue;
@ -313,7 +313,7 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad
levels[level].amplitude *= factor;
if (adjust_scaling)
{
levels[level].wavelength *= factor;
levels[level].frequency /= 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)
{
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)
@ -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)
{
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)
@ -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)
{
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)

View file

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

View file

@ -90,11 +90,14 @@ void CameraDefinition::validate()
projector = mperspective.mult(Matrix4::newLookAt(location, target, up));
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
{
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;
}

View file

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

View file

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

View file

@ -282,7 +282,7 @@ void DialogNoise::addLevel()
NoiseGenerator::NoiseLevel level;
level.amplitude = 0.1;
level.wavelength = 0.1;
level.frequency = 0.1;
_current->addLevel(level);
@ -330,7 +330,7 @@ void DialogNoise::levelChanged(int row)
((PreviewLevel*)previewLevel)->setLevel(row);
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 ...
}
@ -345,7 +345,7 @@ void DialogNoise::heightChanged(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);
previewLevel->redraw();
previewTotal->redraw();

View file

@ -63,8 +63,8 @@ void CanvasPreview::setSize(int real_width, int real_height, int preview_width,
dirty_up = -1;
scaled = (real_width != preview_height or real_height != preview_height);
factor_x = (double)real_width / (double)preview_width;
factor_y = (double)real_height / (double)preview_height;
factor_x = (double)preview_width / (double)real_width;
factor_y = (double)preview_height / (double)real_height;
factor = factor_x * factor_y;
lock->release();
@ -125,12 +125,10 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co
{
int x, y;
lock->acquire();
if (scaled)
{
x = int(real_x / factor_x);
y = int(real_y / factor_y);
x = int(real_x * factor_x);
y = int(real_y * factor_y);
x = (x >= width) ? width - 1 : x;
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);
lock->acquire();
Color* pixel = pixels + (y * width + x);
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->b = pixel->b - old_color.b / factor + new_color.b / 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->b = pixel->b - old_color.b * factor + new_color.b * factor;
// Set pixel dirty
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 vecdiff(diff->pixel.x, diff->pixel.y, diff->pixel.z);
double v1depth = camera->getRealDepth(vec1);
double v2depth = camera->getRealDepth(vec1.add(vecdiff));
double factor = ((1.0 - value) / v1depth + value / v2depth);
double v1depth = 1.0 / camera->getRealDepth(vec1);
double v2depth = 1.0 / camera->getRealDepth(vec1.add(vecdiff));
double factor = 1.0 / ((1.0 - value) * v1depth + value * v2depth);
result->pixel.x = v1->pixel.x + diff->pixel.x * value;
result->pixel.y = v1->pixel.y + diff->pixel.y * 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.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.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.z = ((1.0 - value) * (v1->location.z * v1depth) + value * (v1->location.z + diff->location.z) * v2depth) * factor;
result->client = v1->client;
}

View file

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