Material and Shader Questions
-
Hi guys!
I want to get the shader preview image , but i can't find any method in Python SDK.So the question is :
is there have some tricks to get shader preview image ?Another question is :
Is that posible to change Material Preview size before i use BaseMaterial.GetPreview() ?
Because i see the material preview image size is 90*90, it's small to me. -
Hi @gheyret, in C++ there is a direct way of doing that by calling RenderShaderPreview to retrieve the shader preview and RenderMaterialPreview to retrieve the material preview. But this is not exposed in Python therefor the Material Preview can only be access by
BaseMaterial.GetPreview
which is as you said is limited to 90*90 and there is no way for you to change it. However for the shader preview, you can sample the shader manually with the next code.import c4d def main() -> None: # Retrieve the first shader of the active material, otherwise leave mat = doc.GetActiveMaterial() sha = mat.GetFirstShader() if not sha: return # Create a BaseBitmap that will contain the result of the sampling bmp = c4d.bitmaps.BaseBitmap() width = height = 1024 if bmp.Init(width, height) != c4d.IMAGERESULT_OK: raise RuntimeError("Failed to initialize output bitmap") # Initialize data used by the render to sample the shader for each pixel irs = c4d.modules.render.InitRenderStruct() if sha.InitRender(irs) != c4d.INITRENDERRESULT_OK: raise RuntimeError("Failed to initialize shader render") cd = c4d.modules.render.ChannelData() cd.p = c4d.Vector(0, 0, 0) cd.n = c4d.Vector(0, 0, 1) cd.d = c4d.Vector(0, 0, 0) cd.t = 0.0 cd.texflag = 0 cd.off = 0.0 cd.scale = 0.0 # Sample each pixel of the pixel with the shader for x in range(bmp.GetBw()): for y in range(bmp.GetBh()): cd.p = c4d.Vector(x, y, 0) pixel = sha.Sample(cd) bmp.SetPixel(x, y, pixel.x * 255, pixel.y * 255, pixel.z * 255) # Display the produced bitmap c4d.bitmaps.ShowBitmap(bmp) """ def state(): # Defines the state of the command in a menu. Similar to CommandData.GetState. return c4d.CMD_ENABLED """ if __name__ == '__main__': main()
As a side note some shaders will not work as they require scene information only available during a full rendering of the scene e.g. the proximal shader, but most of the simple one should work.
Cheers,
Maxime. -
@m_adam
OK~ Thank you so much!