Hello,
What's the proper way to sample a shader (noise, gradient, etc.) in 3D space without a given VolumeData object?
I understand how to map the ChannelData's p (uvw) parameter to my object's uvw coordinates, but how do I sample in a way that works like Mograph's shader effector works?
When I sample a noise, and put my objects uvw coordinates in the ChannelData object, if I switch the noise to "World Space", that doesn't work obviously, cause i'm still sampling in texture space in the code. Do you have to manually check that parameter in the BaseShader object?
See simplified code:
BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
{
GeData myData;
Bool cacheDirty, dirty, frameUpdate;
BaseObject *outObject, *customShape;
BaseShader *shader;
BaseDocument *doc = hh->GetDocument();
InitRenderStruct irs(doc);
outObject = BaseObject::Alloc(Onull); // dummy output object
cacheDirty = op->CheckCache(hh);
dirty = op->IsDirty(DIRTYFLAGS_DATA | DIRTYFLAGS_MATRIX);
op->GetParameter(DescLevel(FROMSHADER_FRAME_UPDATE), myData, DESCFLAGS_GET_0);
frameUpdate = myData.GetBool();
if (frameUpdate)
{
Int32 curFrame = doc->GetTime().GetFrame(doc->GetFps());
if (curFrame != prevFrame){
dirty = true;
prevFrame = curFrame;
}
}
if (!dirty && !cacheDirty)
{
blDelete(outObject);
return op->GetCache();
}
op->GetParameter(DescLevel(FROMSHADER_SHADER), myData, DESCFLAGS_GET_0);
shader = (BaseShader *)myData.GetLink(doc);
if (!shader)
goto error;
StatusSetSpin();
customShape = BaseObject::Alloc(Ocube);
customShape->SetParameter(DescLevel(PRIM_CUBE_LEN), GeData(Vector(shapeSize)), DESCFLAGS_SET_0);
customShape = MakeEditable(customShape, doc, true);
if (!customShape)
goto error;
if (shader->InitRender(irs) != INITRENDERRESULT_OK)
goto error;
if (!helper->grid)
return false;
StatusSetText("Sampling Noise");
Vector rad = customShape->GetRad();
for ( ; iter; ++iter)
{
ChannelData cd;
cd.off = 0;
cd.scale = 0;
cd.t = time;
cd.texflag = CALC_TEXINFO(0, CHANNEL_COLOR);
cd.d = Vector(1, 1, 1);
cd.n = Vector(0, 1, 0);
cd.vd = nullptr;
Vector pos = iter.getPos();
Vector worldPos = op->GetMg() * Vector(pos.x(), pos.y(), pos.z());
Float min = 1 - ((rad.x + rad.y + rad.z) / 3);
Float max = ((rad.x + rad.y + rad.z) / 3);
cd.p = Vector((c4dPos.x - min) / (max - min),
(c4dPos.y - min) / (max - min),
(c4dPos.z - min) / (max - min));
Vector col = shader->Sample(&cd);
Float luma = 0.2126 * col.x + 0.7152 * col.y + 0.0722 * col.z; // calc luminence
iter.setValue(luma);
}
shader->FreeRender();
StatusClear();
customShape->InsertUnder(outObject);
return outObject;
error:
blDelete(outObject);
StatusClear();
return nullptr;
}