Render Preview Image of Shader



  • On 30/03/2013 at 04:08, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:    
    Platform:      
    Language(s) :

    ---------
    I'm trying to render a preview-image of a BaseShader, but I get crashes in sdl.cdl. I guess it's because
    I don't pass a VolumeData to the ChannelData? I can't get it right. Strange thing is, that the call-stack
    only shows one call to my plugin which is the BaseContainer destructor.. And I don't even use a
    BaseContainer in this code.

    Code:
        sla.cdl!5f9f1ac6()    
        [Unten angegebene Rahmen sind möglicherweise nicht korrekt und/oder fehlen, keine Symbole geladen für sla.cdl]   
        xtensions.cdl!5f73a5e7()    
        CINEMA 4D.exe!01718250()    
        CINEMA 4D.exe!01718250()    
        CINEMA 4D.exe!016a2b74()    
        CINEMA 4D.exe!01bcd2d2()    
        CINEMA 4D.exe!01bd0012()    
        CINEMA 4D.exe!01509238()    
        CINEMA 4D.exe!0145a4de()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!016186e1()    
        CINEMA 4D.exe!016186e1()    
        CINEMA 4D.exe!01716a94()    
        CINEMA 4D.exe!016a17bb()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!016186e1()    
        CINEMA 4D.exe!016186e1()    
        CINEMA 4D.exe!01716a94()    
        CINEMA 4D.exe!01716a94()    
        CINEMA 4D.exe!016a2595()    
        CINEMA 4D.exe!017024ef()    
        CINEMA 4D.exe!01711f53()    
        CINEMA 4D.exe!01626739()    
        CINEMA 4D.exe!016975ce()    
        CINEMA 4D.exe!01b71a3c()    
        CINEMA 4D.exe!0161130f()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!0161132c()    
        CINEMA 4D.exe!016186e1()    
        CINEMA 4D.exe!01716b74()    
        CINEMA 4D.exe!01701696()    
        CINEMA 4D.exe!01711f53()    
        CINEMA 4D.exe!01626739()    
        CINEMA 4D.exe!016975ce()    
        CINEMA 4D.exe!01716b74()    
        CINEMA 4D.exe!0170e612()    
        CINEMA 4D.exe!01716f63()    
        CINEMA 4D.exe!0172088e()    
        CINEMA 4D.exe!0171a86d()    
        CINEMA 4D.exe!01b71a3c()    
        CINEMA 4D.exe!0171cd91()    
        CINEMA 4D.exe!0174e19c()    
        CINEMA 4D.exe!0174e19c()    
        user32.dll!75368e63()    
        user32.dll!75368e9f()    
        msctf.dll!74dc5123()    
        msctf.dll!74dc439e()    
        msctf.dll!74dc3ad3()    
        user32.dll!7537491f()    
        user32.dll!75374902()    
        user32.dll!753729d5()    
        user32.dll!753729b8()    
        user32.dll!75368112()    
        CINEMA 4D.exe!01b58efc()    
        CINEMA 4D.exe!0161a415()    
        CINEMA 4D.exe!01619581()    
        CINEMA 4D.exe!016975ce()    
        CINEMA 4D.exe!0169fbe9()    
        CINEMA 4D.exe!01701696()    
        CINEMA 4D.exe!01711f53()    
        CINEMA 4D.exe!01711f53()    
        CINEMA 4D.exe!01711f53()    
        CINEMA 4D.exe!01643962()    
        CINEMA 4D.exe!01619581()    
        CINEMA 4D.exe!016975ce()    
        CINEMA 4D.exe!01696d7a()    
        CINEMA 4D.exe!01619581()    
        CINEMA 4D.exe!016975ce()    
        CINEMA 4D.exe!016975ce()    
        KernelBase.dll!75195338()    
    >   myplugin.cdl!BaseContainer::~BaseContainer()  Zeile 41   C++
        0039c634()   
        CINEMA 4D.exe!01bd59cd()    
        CINEMA 4D.exe!01ba3054()    
        CINEMA 4D.exe!01b1bd67()    
        CINEMA 4D.exe!00e60ef9()    
        CINEMA 4D.exe!01bc7dbf()    
        CINEMA 4D.exe!01707671()    
        CINEMA 4D.exe!0147ad67()

    Code:
    Bool RenderShader(BaseShader* shader, BaseBitmap* bmp, Real scale=1.0) {
        InitRenderStruct irs;
        if (shader->InitRender(irs) != INITRENDERRESULT_OK) return FALSE;

    LONG w = bmp->GetBw();
        LONG h = bmp->GetBh();
        ChannelData cd;

    for (LONG x=0; x < w; x++) {
          for (LONG y=0; y < h; y++) {

    cd.p.x = x * scale;
            cd.p.y = y * scale;
            cd.p.z = 0.0;

    Vector pixel = shader->Sample(&cd);
            LONG r = pixel.x * 255;
            LONG g = pixel.y * 255;
            LONG b = pixel.z * 255;
            bmp->SetPixel(x, y, r, g, b);
          }
        }

    shader->FreeRender();
        return TRUE;
    }

    Any tips much appreciated. Thanks in advance!

    -Niklas



  • On 30/03/2013 at 05:27, xxxxxxxx wrote:

    The only bad thing I notice is that you are not checking any pointers for NULL.
    An empty VolumeData pointer in the ChannelData should not a problem.



  • On 30/03/2013 at 05:50, xxxxxxxx wrote:

    Hi Jack,

    I ensure to pass valid pointers before calling the function anyway so I
    decided to not include these checks in the function.

    Hm.. I'll try again in another environment, since you say it actually
    looks to be correct.

    Thanks,

    -Niklas



  • On 30/03/2013 at 06:13, xxxxxxxx wrote:

    I've tried to do it in Python first:

    from __future__ import division
      
    import c4d
    from c4d.modules import render
      
    def RenderShader(shader, bmp, scale=1.0) :
        irs = render.InitRenderStruct(doc)
        if shader.InitRender(irs) != c4d.INITRENDERRESULT_OK:
            return False
      
        cd = render.ChannelData()
        w, h = bmp.GetSize()
        for x in xrange(w) :
            for y in xrange(h) :
                cd.p.x = x * scale
                cd.p.y = y * scale
                c = shader.Sample(cd)
      
                r = int(c.x * 255)
                g = int(c.y * 255)
                b = int(c.z * 255)
                bmp.SetPixel(x, y, r, g, b)
      
        shader.FreeRender()
        return True
      
    def main() :
        bmp = c4d.bitmaps.BaseBitmap()
        bmp.Init(128, 128, 24)
      
        mat = doc.GetActiveMaterial()
        sha = mat.GetFirstShader()
        if not RenderShader(sha, bmp, 1.0) :
            print "Rendering shader was not successful."
            return
      
        c4d.bitmaps.ShowBitmap(bmp)
      
    main()
    

    But all I get is a mono-coloured image (black or grey, depending on the shader in the active
    material).



  • On 30/03/2013 at 11:06, xxxxxxxx wrote:

    This works!! :)

    Bool RenderShader(BaseShader* shader, BaseBitmap* bmp, Real scale=1.0) {
        InitRenderStruct irs;
        if (shader->InitRender(irs) != INITRENDERRESULT_OK) return FALSE;
      
        LONG w = bmp->GetBw();
        LONG h = bmp->GetBh();
        ChannelData cd;
        cd.p = Vector(0, 0, 0);
        cd.n = Vector(0, 0, 1);
        cd.d = Vector(0, 0, 0);
        cd.t = 0.0;
        cd.texflag = 0;
        cd.vd = NULL;
        cd.off = 0.0;
        cd.scale = 0.0;
      
        for (LONG x=0; x < w; x++) {
            for (LONG y=0; y < h; y++) {
                cd.p.x = (Real) x * scale;
                cd.p.y = (Real) y * scale;
                Vector pixel = shader->Sample(&cd);
      
                LONG r = MIN(255, pixel.x * 255);
                LONG g = MIN(255, pixel.y * 255);
                LONG b = MIN(255, pixel.z * 255);
                bmp->SetPixel(x, y, r, g, b);
            }
        }
      
        shader->FreeRender();
        return TRUE;
    }
    

    I just initialized every value of the ChannelData.

    -Niklas



  • On 30/03/2013 at 11:11, xxxxxxxx wrote:

    Works for most shaders.. But eg. the tile shader is black only.. :/



  • On 30/03/2013 at 11:24, xxxxxxxx wrote:

    hm,

    i haven't red everything, but this might help. it is a class to sample a baseshader into 
    vertexmap data.

    http://codepad.org/qD96O7rR


Log in to reply