Render Shader to image

On 03/06/2014 at 09:18, xxxxxxxx wrote:

I am trying to figure out how to take a shader such as the fusion or layer shader and save the output as a an image file. I've noticed the c4d.BaseShader has an example in the doc but does not work with any shaders other than Xbitmap.

material = doc.GetFirstMaterial()
  
shader = material[c4d.MATERIAL_COLOR_SHADER]
  
irs = render.InitRenderStruct()
if shader.InitRender(irs)==c4d.INITRENDERRESULT_OK:
    bitmap = shader.GetBitmap()
    shader.FreeRender()
    if bitmap is not None:
        bitmaps.ShowBitmap(bitmap)

Does anyone know of any examples that show how this can be done?

On 03/06/2014 at 22:02, xxxxxxxx wrote:

The docs are pretty clear about what GetBitmap() does:

Originally posted by xxxxxxxx

Returns the bitmap of shaders of type Xbitmap, otherwise None.

http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/BaseList2D/BaseShader/index.html?highlight=getbitmap#BaseShader.GetBitmap

Use Sample() to get the color for a pixel and write this to a new Bitmap.

-NIklas

On 04/06/2014 at 08:40, xxxxxxxx wrote:

Thanks for the help Niklas.

So I think I have the initial idea down as to getting the pixel information using the following code:

import c4d
from c4d import Vector, bitmaps
from c4d.modules.render import ChannelData, InitRenderStruct
  
  
def main() :
    w = 10
    h = 10
    
    mat = doc.GetActiveMaterial()
    
    mati = mat[c4d.MATERIAL_COLOR_SHADER]
    
    irs = InitRenderStruct()
    mati.InitRender(irs)
    cd = ChannelData()
    cd.p = Vector(.5, .5, .5) 
    print mati.Sample(cd)
    bitmap = bitmaps.BaseBitmap()
    bitmap.FlushAll()
    bitmap.Init(w,h, depth=8,flags = 0)
    pos = [1,1]
    col = [200,200,200]
    bitmap.SetPixel(pos[0],pos[1],col[0],col[1],col[2])
    bitmaps.ShowBitmap(bitmap)
    
if __name__=='__main__':
    main()

When I show the bitmap however it is all black, am I missing something?

On 04/06/2014 at 12:36, xxxxxxxx wrote:

Ok I figured it out!

For anyone trying to do the same here is some code to get you started. (so far it's working 🙂)

from __future__ import division
import c4d
from c4d import Vector, bitmaps
from c4d.bitmaps import ShowBitmap
from c4d.modules.render import ChannelData, InitRenderStruct
  
  
def main() :
    w = 100
    h = 100
    
    mat = doc.GetActiveMaterial()
    
    shader = mat[c4d.MATERIAL_COLOR_SHADER]
    
    irs = InitRenderStruct()
    shader.InitRender(irs)
    cd = ChannelData()
    cd.p = Vector(.5,.5,0)
    bmp = bitmaps.BaseBitmap()
    bmp.Init(w,h,24)
    
    print shader.Sample(cd)
    for x in xrange(w) :
        for y in xrange(h) :
            PX = x/w
            PY = y/h
            cd.p = Vector(PX,PY,0)
            s = shader.Sample(cd)
            r = int(s.x * 255)
            g = int(s.y * 255)
            b = int(s.z * 255)
            bmp.SetPixel(x, y, r, g, b)
            
    shader.FreeRender()       
    ShowBitmap(bmp)
    
if __name__=='__main__':
    main()