Grabbing bitmap data off a Shader [SOLVED]



  • On 09/12/2014 at 02:01, xxxxxxxx wrote:

    Hello,

    this thread deals with getting the preview of a shader, not of a material. Please do not confuse this.

    The frame may be defined in the InitRenderStruct object. As documented it's parameters are currently read-only.

    Alternatively you could use the shader's Sample() function to sample the shader yourself. The time would be defined in the ChannelData parameter or setting the BaseDocument's time via SetTime() and calling ExecutePasses(). This may depend on the specific shader.

    Best wishes,
    Sebastian



  • On 09/12/2014 at 13:19, xxxxxxxx wrote:

    I'm having some difficulty getting 'Sample()' to do what I want.  I'll keep trying.

    What I'm trying to do is display an animated texture in a GeUserArea.
    I've displayed it with the method above, but alas only for the first frame.
    Is there another way of accomplishing what I'm trying to do?



  • On 09/12/2014 at 14:40, xxxxxxxx wrote:

    I can't seem to set the time to make 'Sample()' work.

    According to the docs, just like the working example above, you have to wrap 'Sample()' between 'InitRender()' and 'FreeRender()'.

    The render structure passed to 'InitRender()' says it is read only, and that the time is set to 'Current Time'.
    But when I do the following:

     
    irs=render.InitRenderStruct()
    print 'Render structure frame: ', irs.time.GetFrame(irs.fps)
    	
    colShader.InitRender(irs)
      
    cd = c4d.modules.render.ChannelData()
    cd.t = 2.0
    cd.p = Vector(0.25, 0.25, 0)
    smpl = colShader.Sample(cd)
    print smpl
      
    colShader.FreeRender()
    

    ...the time printed out for the irs is always 0, no matter what the doc is set to.

    Also, setting the channel data time as I did above seems to have no effect on the sample either.
    I am getting a correct sample of the color at the 'cd.p' I specify, but only at frame 0.

    What am I doing wrong?



  • On 10/12/2014 at 03:12, xxxxxxxx wrote:

    Hello,

    as described above the behavior of a shader depends on the shader. For example the output result may depend on the current state of some animated parameter. In this case the time member of ChannelData may be ignored and the shader has to be animated by setting the time of the host document and calling ExecutePasses().

    Best wishes,
    Sebastian



  • On 10/12/2014 at 08:59, xxxxxxxx wrote:

    I tried:

    doc.ExecutePasses(None, True, True, True, 0)
    

    ...in every spot of my code above, and set the document time to different frames, and I still can't get a sample at a time other than the first frame.

    It seems that when you call:

    irs=render.InitRenderStruct()
    colShader.InitRender(irs)
    

    ...the default render structure time of 0 is what is used for the sample no matter what you do after that.

    Has anyone sampled a:

    material[c4d.MATERIAL_COLOR_SHADER]
    

    ...at a time other than 0?

    Help!



  • On 10/12/2014 at 10:18, xxxxxxxx wrote:

    Hello,

    you must animate the document before calling InitRender() as this function is used by the shader to prepare chaches etc. The exact behavior depends on the shader. Something like this should work:

      
      fps = doc.GetFps()  
      
      # frame 30  
      time = c4d.BaseTime(30,fps)  
        
      doc.SetTime(time)  
      doc.ExecutePasses(None,True,False,False,c4d.BUILDFLAGS_0)  
        
      irs=render.InitRenderStruct()  
      colShader.InitRender(irs)  
        
      # sample shader here      
      # ....  
      
      colShader.FreeRender()   
    

    best wishes,
    Sebastian



  • On 10/12/2014 at 11:10, xxxxxxxx wrote:

    Hello,

    just a small additional note.
    If your shader has a movie or a picture sequence in it, than ExecutePasses seems to be not enough.
    In my plugin I have to fake and recalculate the:
     Shader[c4d.BITMAPSHADER_TIMING_FROM]
    parameter do make it happen.

    Best wishes
    Martin



  • On 10/12/2014 at 12:29, xxxxxxxx wrote:

    Exactly!

    I said I have an animated texture.  It can be either an image sequence, or a movie.
    It just doesn't work.

    Are you just setting the value for [c4d.BITMAPSHADER_TIMING_FROM] back and fourth to make it work?

    Thanks



  • On 10/12/2014 at 12:45, xxxxxxxx wrote:

    first of all I calculate the right frame,
    with
    [c4d.BITMAPSHADER_TIMING_MODE]
    [c4d.BITMAPSHADER_TIMING_TIMING]
    [c4d.BITMAPSHADER_TIMING_RANGEFROM]
    [c4d.BITMAPSHADER_TIMING_RANGETO]
    because the user might have set a loop or a specific startframe e.g.

    But than I simply set the value for [c4d.BITMAPSHADER_TIMING_FROM]
    for every frame to the corresponding doctime

    I asked the question a few month ago, but there seems to be no other way.

    Best wishes
    Martin



  • On 10/12/2014 at 13:52, xxxxxxxx wrote:

    Martin,

    Thank you very much, you just saved me a lot of time.
    It is a hack for sure, but it works like a charm, and now I don't have to use Sample() either, I can get the whole bitmap....whew!

    Whoever did this:

    irs=render.InitRenderStruct() #helper class, members are currently read-only (13.029)
    

    ...as read only blew it.
    You need to be able to set the time in the render structure so you can get the bitmap at different times.

    Thanks again.

    Chris


Log in to reply