Solved 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!