On 29/04/2015 at 10:12, xxxxxxxx wrote:
Hi Sebastian,
I've doctored this code since the actual codebase is much larger and more complex. But
basically it mimics what a certain code branch will do:
virtual Vector Output(BaseShader* shader, ChannelData* cd) {
if (!shader || !cd) return Vector(1.0, 0, 0);
BaseContainer* bc = shader->GetDataInstace();
if (!bc) return Vector(1.0, 1.0, 0);
BaseShader* subShader = static_cast<BaseShader*>(
bc->GetLink(MYSHADER_SUBSHADER, shader->GetDocument(), Xbase));
if (!subShader) return Vector(0.0, 1.0, 0);
static const Int32 stepu = 1.0 / 6;
static const Int32 stepv = 1.0 / 6;
Float u = fmod(Abs(cd->p.x), 1);
Float v = fmod(Abs(cd->p.y), 1);
// This function calculates the stepped value of *x* based on
// the specified *step*.
auto steppit = [](const Float x, const Float step) -> Float {
if (Abs(step - 1.0) <= EPSILON) return 0.0;
Float r = (x - fmod(x, step)) / (1.0 - step);
// Rounding errors could lead r to exceed 1.0 *sligthly*,
// but we really need to make sure it does not, otherwise we
// will start sampling the other end of the shader again.
if (r > 1.0) r = 1.0;
else if (r < 0.0) r = 0.0;
return r;
};
u = steppit(i, stepu);
v = steppit(i, stepv);
ChannelData data = *cd;
data.p = Vector(u, v, 0);
return subShader->Sample(&data);
}
Of course, InitRender() and FreeRender() are called on the subShader.
Thanks,
Niklas