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.