Demonstrates basic operations with the Redshift renderer in Cinema 4D.
About
With S26 the Redshift render engine has been integrated with Cinema 4D. While the render engine has already previously been available to Cinema 4D users, it was then a plugin and therefor not part of the public Cinema 4D SDK. With the integration come also architectural changes as for example the unification of camera and light types and a unified nodes model.
Current Limitations
In the current form of Redshift integration there are no Redshift specific frameworks yet exposed. But the core features of Redshift can be accessed through the classic and Nodes API. Currently missing from the public API are also the Redshift render engine ID and the Redshift node space ID for node materials. They must be provided manually in third party code at the moment as demonstrated by the examples here.
Redshift has also an anti-tampering mechanism which ensures Redshift is being run with a valid license. This mechanism triggers when a debugger, as for example provided by Visual Studio and XCode, is attached to Cinema 4D. The anti-tampering mechanism then obfuscates the rendering output of Redshift as shown in Figure I. Plugins making use of Redshift can still be debugged as any other plugin, but to see the final output of a plugin which generates for example a Redshift node material setup, the plugin must be compiled and loaded by a normal instance of the Cinema 4D application without a debugger attached.
Examples
Set Render Engine to Redshift
Sets the render engine of the active render data of a document to Redshift.
Also assures that the required Redshift video post node is present in the render data. This example requires defining the Redshift renderer plugin ID as shown here, as the ID is currently not exposed in the SDK.
{
if (rdata == nullptr)
return maxon::UnexpectedError(
{
if (rdata == nullptr)
return nullptr;
while (videoPost)
{
return videoPost;
}
return nullptr;
};
if (FindVideoPost(rdata, PID_REDSHIFT_RENDER_ENGINE) == nullptr)
{
if (!redshiftVideoPost)
return maxon::OutOfMemoryError(
}
}
Definition: c4d_basecontainer.h:47
void SetInt32(Int32 id, Int32 l)
Definition: c4d_basecontainer.h:505
Definition: c4d_basedocument.h:498
const BaseContainer * GetDataInstance() const
Definition: c4d_baselist.h:2328
Definition: c4d_videopost.h:24
static BaseVideoPost * Alloc(Int32 type)
BaseVideoPost * GetNext(void)
Definition: c4d_videopost.h:56
Bool IsInstanceOf(Int32 id) const
Definition: c4d_baselist.h:1418
Definition: c4d_basedocument.h:144
void InsertVideoPost(BaseVideoPost *pvp, BaseVideoPost *pred=nullptr)
BaseVideoPost * GetFirstVideoPost()
@ RDATA_RENDERENGINE
Definition: drendersettings.h:39
maxon::Int32 Int32
Definition: ge_sys_math.h:60
int32_t Int32
32 bit signed integer datatype.
Definition: apibase.h:176
return OK
Definition: apibase.h:2667
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
@ NEWOBJ
A new object, material, tag, or other classic API node instance has been inserted into the document....
@ CHANGE
Any change to an object, including hierarchy modifications, modification in positioning,...
const char * doc
Definition: pyerrors.h:226
#define iferr_scope
Definition: resultbase.h:1374
Render a Document with Redshift
Renders the current frame in a document with the Redshift render engine into a bitmap.
The bitmap is displayed with the Picture Viewer after the rendering has finished. Uses the function RenderDocument to render the document and the example snippet Set Render Engine to Redshift to set the render engine of the passed document.
{
if (rdata == nullptr)
return maxon::UnexpectedError(
}
RENDERRESULT RenderDocument(BaseDocument *doc, const BaseContainer &rdata, ProgressHook *prog, void *private_data, BaseBitmap *bmp, RENDERFLAGS renderflags, BaseThread *th, WriteProgressHook *wprog=nullptr, void *data=nullptr)
Bool ShowBitmap(const Filename &fn)
BaseBitmap * AddChannel(Bool internal, Bool straight)
static BaseBitmap * Alloc(void)
Int32 GetInt32(Int32 id, Int32 preset=0) const
Definition: c4d_basecontainer.h:303
Definition: c4d_basebitmap.h:962
static void Free(MultipassBitmap *&bm)
@ RDATA_XRES
Definition: drendersettings.h:154
@ RDATA_YRES
Definition: drendersettings.h:155
@ EXTERNAL
External render.
#define iferr_return
Definition: resultbase.h:1465
Create a Redshift Light Object
Instantiates a Redshift light object and inserts it into a document.
Also modifies the light type and shape, the color and intensity and the transform of the new light object to demonstrate setting up a light object in more detail. Finally, adds a target tag to the light object to orient towards a dummy geometry created alongside with this example.
{
if (redshiftLight == nullptr)
redshiftLight->
SetMg(transform);
doc->InsertObject(redshiftLight,
nullptr,
nullptr);
if (cubeObject == nullptr)
doc->InsertObject(cubeObject,
nullptr,
nullptr);
if (targetTag == nullptr)
}
void SetFloat(Int32 id, Float r)
Definition: c4d_basecontainer.h:533
void SetLink(Int32 id, C4DAtomGoal *link)
Definition: c4d_basecontainer.h:604
void SetVector(Int32 id, const Vector &v)
Definition: c4d_basecontainer.h:555
Definition: c4d_baseobject.h:225
void SetMg(const Matrix &m)
Definition: c4d_baseobject.h:488
static BaseObject * Alloc(Int32 type)
BaseTag * MakeTag(Int32 type, BaseTag *pred=nullptr)
Definition: c4d_basetag.h:48
maxon::Vec3< maxon::Float64, 1 > Vector
Definition: ge_math.h:145
#define Orslight
Redshift light.
Definition: ge_prepass.h:1029
#define Ocube
Cube.
Definition: ge_prepass.h:1095
#define Ttargetexpression
Target expression.
Definition: ge_prepass.h:1397
@ REDSHIFT_LIGHT_AREA_GEOMETRY_DISC
Definition: orslight.h:200
@ REDSHIFT_LIGHT_PHYSICAL_COLOR
Definition: orslight.h:47
@ REDSHIFT_LIGHT_TYPE
Definition: orslight.h:9
@ REDSHIFT_LIGHT_TYPE_PHYSICAL_AREA
Definition: orslight.h:189
@ REDSHIFT_LIGHT_PHYSICAL_INTENSITY
Definition: orslight.h:51
@ REDSHIFT_LIGHT_PHYSICAL_AREA_GEOMETRY
Definition: orslight.h:57
@ TARGETEXPRESSIONTAG_LINK
Definition: ttargetexpression.h:6
Create a Redshift Material
Creates a Redshift node material, modifies its node graph and inserts the material into a document.
The example adds two Texture nodes, a Color Mix node, and a Maxon Noise node to the node graph of the material and creates connections between these nodes. The two texture nodes are setup to reference texture assets delivered with Cinema 4D. See Asset API for more information on the asset system of Cinema 4D which is used here.
{
maxon::Id rustPaintId(
"file_edb3eb584c0d905c");
maxon::Id sketchBasicId(
"file_3b194acc5a745a2c");
if (!lookupRepo)
return maxon::UnexpectedError(
const maxon::Id fileTypeId = maxon::AssetTypes::File().GetId();
const maxon::AssetDescription rustAssetDescription = lookupRepo.FindLatestAsset(
if (!rustAssetDescription)
const maxon::AssetDescription sketchAssetDescription = lookupRepo.FindLatestAsset(
if (!sketchAssetDescription)
if (material == nullptr)
const
maxon::LiteralId redshiftId("com.redshift3d.redshift4c4d.class.nodespace");
const
maxon::nodes::NodesGraphModelRef& graph = material->GetGraph(redshiftId)
iferr_return;
const
maxon::Id colormixId("com.redshift3d.redshift4c4d.nodes.core.rscolormix");
const
maxon::Id noiseId("com.redshift3d.redshift4c4d.nodes.core.maxonnoise");
const
maxon::Id rsmaterialId("com.redshift3d.redshift4c4d.nodes.core.material");
const
maxon::Id textureId("com.redshift3d.redshift4c4d.nodes.core.texturesampler");
{
if (!outcolorOutportRust.
IsValid() || !input1InportColormix.
IsValid())
if (!outcolorOutportSketch.
IsValid() || !input2InportColormix.
IsValid())
if (!outcolorOutportColormix.
IsValid() || !diffusecolorInportRsmaterial.
IsValid())
if (!outcolorOutportNoise.
IsValid() || !mixamountInportColormix.
IsValid() ||
!reflectionroughnessInportRsmaterial.
IsValid())
if (!noisetypeInportNoise.
IsValid())
}
doc->InsertMaterial(material);
}
Definition: c4d_basematerial.h:28
Definition: c4d_basematerial.h:391
static MAXON_METHOD const UpdatableAssetRepositoryRef & GetUserPrefsRepository()
static MAXON_METHOD Result< Url > GetAssetUrl(const AssetDescription &asset, Bool isLatest)
Definition: basearray.h:412
MAXON_ATTRIBUTE_FORCE_INLINE Int GetCount() const
Definition: basearray.h:573
static MAXON_METHOD Result< void > FindNodesByAssetId(const GraphModelRef &graphModel, const Id &assetId, Bool exactId, const ValueReceiver< const GraphNode & > &callback)
Result< typename SFINAEHelper< GraphNode, BASE >::type > GetOutputs() const
Definition: graph.h:1191
Result< Bool > SetDefaultValue(T &&value) const
Definition: graph.h:1772
Result< typename SFINAEHelper< GraphNode, BASE >::type > FindChild(const InternedId &name) const
Definition: graph.h:1215
Result< typename SFINAEHelper< GraphNode, BASE >::type > GetInputs() const
Definition: graph.h:1180
Result< void > Connect(const GraphNode &target, Wires modes=WIRE_MODE::CONNECT_DEFAULT, Bool reverse=false) const
Definition: graph.h:1478
Bool IsValid() const
Definition: graph.h:1950
Definition: apibaseid.h:253
#define Mmaterial
Standard material.
Definition: ge_prepass.h:992
@ NOISE_WAVY_TURB
Wavy turbulence.
Definition: lib_noise.h:60
The maxon namespace contains all declarations of the MAXON API.
Definition: autoweight.h:14
Url GetAssetUrl(const DndAsset &asset)
@ LATEST
Set this flag to obtain only the latest version of the asset.