Hi guys,

I'm getting strange pixel artefacts in this plugin. you require a depth
pass and an image to distort.
set the output matte to alpha to clearly see the artefacts as you change
the disparity. also any help on the pixel stretch would be marvellous.

Thanks.

========CUT HERE========

// Copyright (c) 2013 Bryan "Fox" Dunkley.  All Rights Reserved.

static const char* const CLASS = "sf_DepthDistortion";
static const char* const HELP =
"Distortion tool.\n\n"
".\n";

#include "DDImage/Iop.h"
#include "DDImage/Row.h"
#include "DDImage/Knobs.h"
#include "DDImage/gl.h"
#include "DDImage/Thread.h"
#include "DDImage/Tile.h"
#include "DDImage/Pixel.h"
#include "DDImage/Filter.h"

#include <list>
#include <iostream>
#include <math.h>
#include <limits>

using namespace DD::Image;
using namespace std;

const char* const distortionDirections[] = {
"left",
"right",
NULL
};

const char* const blendModes[] = {
"over",
"plus",
NULL
};

class sf_DepthDistortionIop : public Iop
{
private:
//Gui variables
Channel depth_chan_set[1];
ChannelSet distChannelSet;
int disparity;
int distort_dir;
bool pixel_stretch;
bool effect_only;
int blend_mode;
Channel output_matte_set[1];
int dx;
Filter filter;
Lock _distort_lock;

public:
sf_DepthDistortionIop(Node* node);
void in_channels(int input, ChannelSet& mask) const;
int minimum_inputs() const;
int maximum_inputs() const;
void _validate(bool);
virtual void knobs(Knob_Callback);
int knob_changed(Knob* k);
void _request(int x, int y, int r, int t, ChannelMask channels, int count);
void engine(int y, int x, int r, ChannelMask channels, Row & out);
 static const Iop::Description d;
const char* Class() const { return d.name; }
const char* node_help() const { return HELP; }

};

static Iop* build(Node* node)
{
return new sf_DepthDistortionIop(node);
}

const Iop::Description sf_DepthDistortionIop::d(CLASS, 0, build);
//

sf_DepthDistortionIop::sf_DepthDistortionIop(Node* node) : Iop(node)
{
inputs(1);
distChannelSet = Mask_RGBA;
output_matte_set[0] = Chan_Black;
distort_dir = 0;
disparity = 0;
pixel_stretch = true;
effect_only = false;
blend_mode = 0;
dx = 0;
}

void sf_DepthDistortionIop::in_channels(int input, ChannelSet& mask) const
{
mask += depth_chan_set[0];
}

int sf_DepthDistortionIop::minimum_inputs() const
{
return 1;
}

int sf_DepthDistortionIop::maximum_inputs() const
{
return 1;
}

void sf_DepthDistortionIop::_validate(bool for_real)
{
filter.initialize();
copy_info(0);

if (this->disparity < 0)
{
this->disparity = 0;
}

ChannelSet main_output_channels = Mask_None;
main_output_channels += distChannelSet;
main_output_channels += output_matte_set[0];

set_out_channels(main_output_channels);
info_.turn_on(main_output_channels);
}

void sf_DepthDistortionIop::knobs(Knob_Callback f)
{
Input_ChannelSet_knob(f, &distChannelSet,0,"channels");
Divider(f,"");
InputOnly_Channel_knob(f, depth_chan_set, 1, 0, "distortion_matte",
"distortion matte");
Divider(f,"");
Int_knob(f,&disparity,"disparity");
Enumeration_knob(f, &distort_dir, distortionDirections,
"distortion_direction", "direction");
Bool_knob(f, &pixel_stretch, "enable_pixel_stretch", "pixel stretch");
Divider(f,"");
filter.knobs(f);
Enumeration_knob(f, &blend_mode, blendModes, "blend_mode", "mode");
Bool_knob(f,&effect_only,"effect_only","effect only");
Divider(f,"");
Channel_knob(f, output_matte_set, 1, "matte_channel", "output distortion
matte");
}

int sf_DepthDistortionIop::knob_changed(Knob* k)
{
//cout << k->name() << endl;
if(k->name() == "disparity")
{
if (disparity < 0)
{
disparity = 0;
}
}
return 1;
}

void sf_DepthDistortionIop::_request(int x, int y, int r, int t,
ChannelMask channels, int count)
{
ChannelSet c1(channels);
    in_channels(0, c1);
    input0().request(input0().info().x(), input0().info().y(),
input0().info().r(), input0().info().t(), c1, count * 2);
}

void sf_DepthDistortionIop::engine(int y, int x, int r, ChannelMask
channels, Row& out)
{
if (distChannelSet != Mask_None)
{
Guard guard(_distort_lock);
////Channel Setup
ChannelSet c1(channels);
in_channels(0, c1);
Tile tile(input0(), x, y, r + 1, y + 2, c1);
if (aborted())
{
return;
}

Channel distort_chan = depth_chan_set[0];
if (!intersect(tile.channels(), distort_chan))
{
distort_chan = Chan_Black;
}
const float* in_z = tile[distort_chan][y];

InterestRatchet interestRatchet;
Pixel pixel(c1);
pixel.setInterestRatchet(&interestRatchet);
////

int X = x;
int R = r;
int Y = y;

//
Row drow(X-disparity,R+disparity);

foreach(z, c1)
{
Row::WritablePtr ptr = drow.writable(z);
//set row to zero
memset(ptr + X-disparity, 0, ((R+disparity) - (X-disparity)) *
sizeof(float));
//
out.writable(z);
}

Channel matte_chan = output_matte_set[0];
if (!intersect(drow.writable_channels(), matte_chan))
{
drow.writable(matte_chan);
}
 //
 for (int k = X; k < R; k++)
{
float shift = in_z[k];

float pixel_shift = shift * disparity;
 int temp = int(pixel_shift + 0.5f);
if (disparity > 0)
{
if (distort_dir == 1)
{
//not yet implemented
input0().get(y,x,r, channels, out);
//
}
else
{
//drow.offset(temp);
if (pixel_stretch)
{
input0().sample(k+.5f,Y+.5f,1,1,&filter,pixel);
for (int j=0;j<temp;j++)
{
foreach (z, c1)
{
((float*)(drow[z]))[(k-temp)+j] = pixel[z];
}
if (j == 0)
{
((float*)(drow[matte_chan]))[(k-temp)+j] = 1.0f;
}
else
{
((float*)(drow[matte_chan]))[(k-temp)+j] = .5f;
}
}
}
else
{
input0().sample(k+.5f,Y+.5f,1,1,&filter,pixel);
foreach (z, c1)
{
((float*)(drow[z]))[k-temp] = pixel[z];
//drow.get(input0(), Y, k-temp, R-temp, c1);
}
((float*)(drow[matte_chan]))[k-temp] = 1.0f;
}
//drow.offset(-temp);
}
}
}

for (; x < R; x++)
{
const float* AMASK = drow[matte_chan];

//Blur
float value = 0.0f;
int div = 0;
int size = disparity;
float pb = 0.0f;
//

foreach (z, c1)
{
const float* AFROM = drow[z];

//X Box Blur
/*value = 0.0f;
div = 0;
for (int px = -size; px<size; px++)
{
value += AFROM[x+px];
div++;
}
if (AMASK[x] == .5f)
{
pb = value/div;
}
else
{
pb = AFROM[x];
}*/
pb = AFROM[x];
//

if (effect_only)
{
((float*)(out[z]))[x] = pb;
}
else
{
const float* BFROM = tile[z][y];
if (blend_mode == 0)
{
if (AMASK[x] == .5f)
{
((float*)(out[z]))[x] = (BFROM[x]*(1-1.0f)) + pb;
}
else
{
                            ((float*)(out[z]))[x] = (BFROM[x]*(1-AMASK[x]))
+ pb;
}
}
else
{
((float*)(out[z]))[x] = BFROM[x] + pb;
}
}
}
 }
}//if statement
else
{
input0().get(y,x,r, channels, out);
}
}

=========================

-- 
Bryan 'Fox' Dunkley
Compositor / Python, C++ Developer

tel: +44 755 268 2117
website: www.slyfoxfx.com
linkedin: http://www.linkedin.com/pub/bryan-dunkley/26/b21/bab
_______________________________________________
Nuke-dev mailing list
Nuke-dev@support.thefoundry.co.uk, http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-dev

Reply via email to