Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2012-07-03 13:05:19 +0400
committerJeroen Bakker <j.bakker@atmind.nl>2012-07-03 13:05:19 +0400
commit2f5735a9d4745f33e850a163248c6c18a1305f64 (patch)
treea6f2712af50c9abcfc3c4853f0bda7c5e04df958 /source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
parent63810ffcef825930b034899f54107fc35b159349 (diff)
Optimized the area of interest of the lensdistortion node.
This will have faster feedback to the user, as lensdistortion is mostly a node that is located at the end of a composite
Diffstat (limited to 'source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp')
-rw-r--r--source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp194
1 files changed, 169 insertions, 25 deletions
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
index e3abf2aa70b..ea8483734d3 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
@@ -42,6 +42,10 @@ ScreenLensDistortionOperation::ScreenLensDistortionOperation() : NodeOperation()
void ScreenLensDistortionOperation::initExecution()
{
this->m_inputProgram = this->getInputSocketReader(0);
+ this->initMutex();
+ this->m_cx = 0.5f * (float)getWidth();
+ this->m_cy = 0.5f * (float)getHeight();
+
}
void *ScreenLensDistortionOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers)
@@ -139,52 +143,192 @@ void ScreenLensDistortionOperation::executePixel(float *outputColor, int x, int
void ScreenLensDistortionOperation::deinitExecution()
{
+ this->deinitMutex();
this->m_inputProgram = NULL;
}
-void ScreenLensDistortionOperation::determineUV(float result[2], float x, float y) const
+void ScreenLensDistortionOperation::determineUV(float result[4], float x, float y, float distortion, float dispersion)
+{
+ if (!this->m_valuesAvailable) {
+ updateVariables(distortion, dispersion);
+ }
+ determineUV(result, x, y);
+}
+
+void ScreenLensDistortionOperation::determineUV(float result[4], float x, float y) const
{
+ const float height = this->getHeight();
+ const float width = this->getWidth();
+
+ float d, t, ln[6] = {0, 0, 0, 0, 0, 0};
const float v = this->m_sc * ((y + 0.5f) - this->m_cy) / this->m_cy;
const float u = this->m_sc * ((x + 0.5f) - this->m_cx) / this->m_cx;
- const float t = ABS(MIN3(this->m_kr, this->m_kg, this->m_kb) * 4);
- float d = 1.f / (1.f + sqrtf(t));
- result[0] = (u * d + 0.5f) * getWidth() - 0.5f;
- result[1] = (v * d + 0.5f) * getHeight() - 0.5f;
+ const float uv_dot = u * u + v * v;
+
+ if ((t = 1.f - this->m_kr4 * uv_dot) >= 0.f) {
+ d = 1.f / (1.f + sqrtf(t));
+ ln[0] = (u * d + 0.5f) * width - 0.5f, ln[1] = (v * d + 0.5f) * height - 0.5f;
+ }
+ if ((t = 1.f - this->m_kg4 * uv_dot) >= 0.f) {
+ d = 1.f / (1.f + sqrtf(t));
+ ln[2] = (u * d + 0.5f) * width - 0.5f, ln[3] = (v * d + 0.5f) * height - 0.5f;
+ }
+ if ((t = 1.f - this->m_kb4 * uv_dot) >= 0.f) {
+ d = 1.f / (1.f + sqrtf(t));
+ ln[4] = (u * d + 0.5f) * width - 0.5f, ln[5] = (v * d + 0.5f) * height - 0.5f;
+ }
+
+ float jit = this->m_data->jit;
+ float z;
+ {
+ // RG
+ const int dx = ln[2] - ln[0], dy = ln[3] - ln[1];
+ const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f;
+ const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
+ const float sd = 1.f / (float)ds;
+
+ z = ds;
+ const float tz = ((float)z + (1.0f)) * sd;
+ t = 1.0f - (this->m_kr4 + tz * this->m_drg) * uv_dot;
+ d = 1.0f / (1.f + sqrtf(t));
+ const float nx = (u * d + 0.5f) * width - 0.5f;
+ const float ny = (v * d + 0.5f) * height - 0.5f;
+ result[0] = nx;
+ result[1] = ny;
+ }
+ {
+ // GB
+ const int dx = ln[4] - ln[2], dy = ln[5] - ln[3];
+ const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f;
+ const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
+ const float sd = 1.f / (float)ds;
+
+ z = ds;
+ const float tz = ((float)z + (1.0f)) * sd;
+ t = 1.f - (this->m_kg4 + tz * this->m_dgb) * uv_dot;
+ d = 1.f / (1.f + sqrtf(t));
+ const float nx = (u * d + 0.5f) * width - 0.5f;
+ const float ny = (v * d + 0.5f) * height - 0.5f;
+ result[2] = nx;
+ result[3] = ny;
+ }
}
bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
+ rcti newInputValue;
+ newInputValue.xmin = 0;
+ newInputValue.ymin = 0;
+ newInputValue.xmax = 2;
+ newInputValue.ymax = 2;
+
+ NodeOperation *operation = getInputOperation(1);
+ if (operation->determineDependingAreaOfInterest(&newInputValue, readOperation, output) ) {
+ return true;
+ }
+
+ operation = getInputOperation(2);
+ if (operation->determineDependingAreaOfInterest(&newInputValue, readOperation, output) ) {
+ return true;
+ }
+
+#define MARGIN 64
+
+#define UPDATE_INPUT \
+ newInput.xmin = MIN3(newInput.xmin, coords[0], coords[2]); \
+ newInput.ymin = MIN3(newInput.ymin, coords[1], coords[3]); \
+ newInput.xmax = MAX3(newInput.xmax, coords[0], coords[2]); \
+ newInput.ymax = MAX3(newInput.ymax, coords[1], coords[3]);
+
rcti newInput;
- newInput.xmin = 0;
- newInput.ymin = 0;
- newInput.ymax = this->m_inputProgram->getHeight();
- newInput.xmax = this->m_inputProgram->getWidth();
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+ float margin;
+ float coords[4];
+ if (m_valuesAvailable) {
+ determineUV(coords, input->xmin, input->ymin);
+ newInput.xmin = coords[0];
+ newInput.ymin = coords[1];
+ newInput.xmax = coords[0];
+ newInput.ymax = coords[1];
+ UPDATE_INPUT;
+ determineUV(coords, input->xmin, input->ymax);
+ UPDATE_INPUT;
+ determineUV(coords, input->xmax, input->ymax);
+ UPDATE_INPUT;
+ determineUV(coords, input->xmax, input->ymin);
+ UPDATE_INPUT;
+ margin = (ABS(this->m_distortion)+this->m_dispersion)*MARGIN;
+ }
+ else
+ {
+ determineUV(coords, input->xmin, input->ymin, 1.0f, 1.0f);
+ newInput.xmin = coords[0];
+ newInput.ymin = coords[1];
+ newInput.xmax = coords[0];
+ newInput.ymax = coords[1];
+ UPDATE_INPUT;
+ determineUV(coords, input->xmin, input->ymin, -1.0f, 1.0f);
+ UPDATE_INPUT;
+
+ determineUV(coords, input->xmin, input->ymax, -1.0f, 1.0f);
+ UPDATE_INPUT;
+ determineUV(coords, input->xmin, input->ymax, 1.0f, 1.0f);
+ UPDATE_INPUT;
+
+ determineUV(coords, input->xmax, input->ymax, -1.0f, 1.0f);
+ UPDATE_INPUT;
+ determineUV(coords, input->xmax, input->ymax, 1.0f, 1.0f);
+ UPDATE_INPUT;
+
+ determineUV(coords, input->xmax, input->ymin, -1.0f, 1.0f);
+ UPDATE_INPUT;
+ determineUV(coords, input->xmax, input->ymin, 1.0f, 1.0f);
+ UPDATE_INPUT;
+ margin=MARGIN;
+ }
+
+#undef UPDATE_INPUT
+ newInput.xmin -= margin;
+ newInput.ymin -= margin;
+ newInput.xmax += margin;
+ newInput.ymax += margin;
+
+ operation = getInputOperation(0);
+ if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) {
+ return true;
+ }
+ return false;
+}
+
+void ScreenLensDistortionOperation::updateVariables(float distortion, float dispersion)
+{
+ this->m_kg = MAX2(MIN2(distortion, 1.f), -0.999f);
+ // smaller dispersion range for somewhat more control
+ const float d = 0.25f * MAX2(MIN2(dispersion, 1.f), 0.f);
+ this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f);
+ this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f);
+ this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb);
+ this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk));
+ this->m_drg = 4.f * (this->m_kg - this->m_kr);
+ this->m_dgb = 4.f * (this->m_kb - this->m_kg);
+
+ this->m_kr4 = this->m_kr * 4.0f;
+ this->m_kg4 = this->m_kg * 4.0f;
+ this->m_kb4 = this->m_kb * 4.0f;
}
void ScreenLensDistortionOperation::updateDispersionAndDistortion(MemoryBuffer **inputBuffers)
{
+ if (this->m_valuesAvailable) return;
+
+ this->lockMutex();
if (!this->m_valuesAvailable) {
float result[4];
this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers);
this->m_distortion = result[0];
this->getInputSocketReader(2)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers);
this->m_dispersion = result[0];
- this->m_kg = MAX2(MIN2(this->m_distortion, 1.f), -0.999f);
- // smaller dispersion range for somewhat more control
- const float d = 0.25f * MAX2(MIN2(this->m_dispersion, 1.f), 0.f);
- this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f);
- this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f);
- this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb);
- this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk));
- this->m_drg = 4.f * (this->m_kg - this->m_kr);
- this->m_dgb = 4.f * (this->m_kb - this->m_kg);
-
- this->m_kr4 = this->m_kr * 4.0f;
- this->m_kg4 = this->m_kg * 4.0f;
- this->m_kb4 = this->m_kb * 4.0f;
- this->m_cx = 0.5f * (float)getWidth();
- this->m_cy = 0.5f * (float)getHeight();
+ updateVariables(this->m_distortion, this->m_dispersion);
this->m_valuesAvailable = true;
}
+ this->unlockMutex();
}