Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    Get linear shaders

    Scheduled Pinned Locked Moved PYTHON Development
    10 Posts 0 Posters 719 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      On 14/11/2014 at 18:36, xxxxxxxx wrote:

      Using shader.initRender() I am rendering out a shader, however I can't get the InitRenderStruct() to be linear. In the docs I have found InitRenderStruct.linear_workflow but this feature is read only. how do I set this value to True?

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 17/11/2014 at 06:34, xxxxxxxx wrote:

        Hello,

        the Python implementation expects the IRS to be initiated by Cinema. So I'm afraid it is not possible to edit an ad hoc created IRS.

        Best wishes,
        Sebastian

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 08/01/2015 at 10:35, xxxxxxxx wrote:

          Finally got the chance to pick this project back up. It seems that I may not be facing a linear issue. Here are some examples of output:

          Original (How the cinema shader preview sees it) :
          _<_img src="http://shawnfrueh.com/references/c4d/original_cinemaoutput.png" height="512" width="512" border="0" /_>_

          This is what I get when I use initRender() :
          <_<_img src="http://shawnfrueh.com/references/c4d/original_initoutput.png" height="512" width="512" border="0" /_>_" />

          and here is what I get when I add a Gamma correction:_r="0" />

          So as you mentioned before I am guessing the IRS is not respecting the project color-space. Is there a way around this? How is the shader preview being rendered?

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 09/01/2015 at 07:23, xxxxxxxx wrote:

            Hi Shawn,

            InitRenderStruct.linear_workflow is passed to InitRender() so that shaders can check if they have to perform some color conversion to InitRenderStruct.document_colorprofile.
            c4d.utils.TransformColor() can then be called to return the expected color from Output().

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 09/01/2015 at 08:23, xxxxxxxx wrote:

              I really appreciate the help Yannick, worked like a charm! Thank you.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                On 09/01/2015 at 12:54, xxxxxxxx wrote:

                Looks like I spoke to soon. The scene I was testing in had the color profile disabled. This is what it looks like in a default scene:

                COLORSPACETRANSFORMATION_NONE: 
                _<_img src="http://shawnfrueh.com/references/c4d/colorspace_nOne.gif" height="278" width="633" border="0" /_>_

                COLORSPACETRANSFORMATION_LINEAR_TO_SRGB:
                <_<_img src="http://shawnfrueh.com/references/c4d/colorspace_linear_to_srgb.gif.gif" height="278" width="633" border="0" /_>_" />

                COLORSPACETRANSFORMATION_SRGB_TO_LINEAR:_r="0" />

                COLORSPACETRANSFORMATION_LINEAR_TO_VIEW_<_img src="http://shawnfrueh.com/references/c4d/colorspace_linear_to_view.gif" height="278" width="633" border="0" /_>_order="0" />

                COLORSPACETRANSFORMATION_SRGB_TO__<_img src="http://shawnfrueh.com/references/c4d/colorspace_srgb_to_view.gif" height="278" width="633" border="0" /_>_3" border="0" />

                So, I guess I'm Back to the drawing board. Am I missing something?

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  On 09/01/2015 at 12:59, xxxxxxxx wrote:

                  This is how I am getting the color:

                  s = shader.Sample(cd)
                  s = c4d.utils.TransformColor(s,profile)
                  r = int(s.x * 255)
                  g = int(s.y * 255)
                  b = int(s.z * 255)
                  bmp.SetPixel(x, y, r, g, b)
                  
                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    On 12/01/2015 at 01:39, xxxxxxxx wrote:

                    Hi Shawn,

                    The Cinema 4D shaders usually transform their input colors (in InitRender()) using irs.TransformColor() that calls the global TransformColor() according to the irs.linear_workflow state and irs.document_colorprofile.
                    InitRenderStruct.TransformColor() isn't defined in the Python API but its code is simple and included in the C++ API. Following is its code converted to Python:

                    def TransformColor(irs, input) :
                      if irs.linear_workflow and irs.document_colorprofile is c4d.DOCUMENT_COLORPROFILE_SRGB:
                        return c4d.utils.TransformColor(input, c4d.COLORSPACETRANSFORMATION_SRGB_TO_LINEAR);
                      elif not irs.linear_workflow and irs.document_colorprofile is c4d.DOCUMENT_COLORPROFILE_LINEAR:
                        return c4d.utils.TransformColor(input, c4d.COLORSPACETRANSFORMATION_LINEAR_TO_SRGB);
                      
                      return input;
                    

                    You should use this TransformColor() for the color sampled in your shader.
                    Note that c4d.utils.TransformColor() expects a COLORSPACETRANSFORMATION value as second parameter, not a DOCUMENT_COLORPROFILE value.
                    Also be sure that the bitmap in your shader uses the appropriate color profile.

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      On 12/01/2015 at 14:50, xxxxxxxx wrote:

                      I am not sure I follow. Using your code above I get the same result: the output is not the same. So when you say that the bitmap must use the correct profile. Does that mean that the bitmap I am creating must also have a profile attached to it?

                      playing with c4d.bitmaps.ColorProfile.GetDefaultLinearRGB() and adding it to the bitmap has no influence on the output.

                      here is the code I have for better understanding:

                      from __future__ import division
                      import c4d,timeit
                      from c4d import Vector, bitmaps, gui
                      from c4d.bitmaps import ShowBitmap
                      from c4d.modules.render import ChannelData, InitRenderStruct
                      # Bitmap maker created by Shawn Frueh
                        
                      class BasicDialog(gui.GeDialog) :
                          
                          RENDER = 10000
                          SHADERLINK = 10001
                          GROUP_SIZE = 10002
                          WIDTH_TEXT = 10003
                          WIDTH = 10004
                          HEIGHT_TEXT = 10005
                          HEIGHT = 10006
                          GROUPFIT = 10007
                          PROGRESS = 10008
                          GROUP_PERCENT = 10009
                          PROGRESS_SLIDER = 10010
                          GROUP_OF_GROUPS = 10011
                          RENDER_BIT = 10012
                          GROUP_ALL = 10013
                          PROFILESELECT = 10014
                          RENDERINFO = 10015
                          
                          CS_NONE = c4d.COLORSPACETRANSFORMATION_NONE
                          CS_L_TO_S = c4d.COLORSPACETRANSFORMATION_LINEAR_TO_SRGB
                          CS_S_TO_L = c4d.COLORSPACETRANSFORMATION_SRGB_TO_LINEAR
                          CS_L_TO_V = c4d.COLORSPACETRANSFORMATION_LINEAR_TO_VIEW
                          CS_S_TO_V = c4d.COLORSPACETRANSFORMATION_SRGB_TO_VIEW
                          
                          def CreateLayout(self) :
                              
                              self.SetTitle("Shader Renderer")
                              
                              self.GroupBegin(self.GROUPFIT,c4d.BFH_SCALEFIT, cols = 2)
                              
                              bc = c4d.BaseContainer()
                              bc.SetLong(c4d.BITMAPBUTTON_ICONID1, c4d.RESOURCEIMAGE_MOVE)
                              bc.SetBool(c4d.BITMAPBUTTON_BUTTON, True)
                              self.myBitButton=self.AddCustomGui(self.RENDER_BIT, c4d.CUSTOMGUI_BITMAPBUTTON, "Bend", c4d.BFH_CENTER | c4d.BFV_CENTER, 64, 64, bc)
                              bmp = bitmaps.BaseBitmap()
                              bmp.Init(120,120,24)
                              self.myBitButton.SetImage(bmp)
                              
                              self.GroupBegin(self.GROUP_ALL, c4d.BFH_SCALEFIT, cols = 1)
                              self.GroupBorderSpace(4,4,4,4)
                              self.AddComboBox(self.PROFILESELECT, c4d.BFH_SCALEFIT)
                              self.AddCustomGui(self.SHADERLINK, pluginid=c4d.CUSTOMGUI_LINKBOX, name="Link", flags=c4d.BFH_SCALEFIT, minw=200, minh=0) 
                              self.GroupBegin(self.GROUP_SIZE,c4d.BFH_SCALEFIT, cols = 4, title = "Render Size")
                              
                              self.AddStaticText(self.WIDTH_TEXT, c4d.BFH_LEFT, name = "Width")
                              self.AddEditNumber(self.WIDTH, c4d.BFH_SCALEFIT)
                              self.AddStaticText(self.HEIGHT_TEXT, c4d.BFH_LEFT, name = "Height")
                              self.AddEditNumber(self.HEIGHT, c4d.BFH_SCALEFIT)
                              self.GroupEnd()
                              
                              self.GroupBegin(self.GROUP_PERCENT,c4d.BFH_SCALEFIT, cols = 3)
                              self.GroupBorderSpace(4,4,4,4)
                              self.AddButton(self.RENDER, c4d.BFH_LEFT, name = "Render")
                              self.AddStaticText(self.PROGRESS,c4d.BFH_LEFT,name = " 100%!")
                              self.AddSlider(self.PROGRESS_SLIDER, c4d.BFH_SCALEFIT)
                        
                              self.GroupEnd()
                              
                              self.AddStaticText(self.RENDERINFO, c4d.BFH_LEFT, name = "Please add a shader.", initw = 500)
                              
                              self.GroupEnd()
                              self.GroupEnd()
                              return True
                          
                          def InitValues(self) :
                              self.SetString(self.PROGRESS," 0%")
                              self.SetReal(self.PROGRESS_SLIDER, 0.0,min = 0, max = 100.0)
                              self.SetInt32(self.WIDTH, 512, max = c4d.MAXLONGl)
                              self.SetInt32(self.HEIGHT, 512, max = c4d.MAXLONGl)
                              self.AddChild(self.PROFILESELECT, self.CS_NONE,"None")
                              self.AddChild(self.PROFILESELECT, self.CS_L_TO_S,"Linear to SRGB")
                              self.AddChild(self.PROFILESELECT, self.CS_S_TO_L,"SRGB to Linear")
                              self.AddChild(self.PROFILESELECT, self.CS_L_TO_V,"Linear to View")
                              self.AddChild(self.PROFILESELECT, self.CS_S_TO_V,"SRGB to View")
                              return True
                          
                          
                          def Command(self, id, msg) :
                              link = self.FindCustomGui(self.SHADERLINK,c4d.CUSTOMGUI_LINKBOX)
                              sh = link.GetLink(doc,0)
                              
                              def GetProfile(p) :
                                  if p == 0:
                                      return self.CS_NONE
                                  if p == 1:
                                      return self.CS_L_TO_S
                                  if p == 2:
                                      return self.CS_S_TO_L
                                  if p == 10:
                                      return self.CS_L_TO_V
                                  if p == 11:
                                      return self.CS_S_TO_V
                                  
                              def RenderShader(w,h,sh) :
                                  global percent
                                  global Pget
                                  
                                  shader = sh
                                  start = timeit.default_timer()
                                  irs = InitRenderStruct()
                                  #####
                                  shader.InitRender(irs)
                                  #####
                                  cd = ChannelData()
                                  cd.p = Vector(.5,.5,0)
                                  bmp = bitmaps.BaseBitmap()
                                  bmp.Init(w,h,24)
                                  c4d.StatusSetBar(0.0)
                                  pget = 100/w
                                  percent = 0.0
                                  profile = self.GetInt32(self.PROFILESELECT)
                                  profile = GetProfile(profile)# possibly not neccesarry?
                                  c4d.StatusSetText("Rendering: "+shader.GetName()+" shader")
                                  for x in xrange(w) :
                                      c4d.StatusSetBar(percent)
                                      self.SetReal(self.PROGRESS_SLIDER, percent,min = 0, max = 100.0)
                                      self.SetString(self.PROGRESS," "+str(percent)+"%")
                                      for y in xrange(h) :
                                          PX = x/w
                                          PY = y/h
                                          cd.p = Vector(PX,PY,0)
                                          s = shader.Sample(cd)
                                          s = c4d.utils.TransformColor(s,profile)
                                          r = int(s.x * 255)
                                          g = int(s.y * 255)
                                          b = int(s.z * 255)
                                          
                                          bmp.SetPixel(x, y, r, g, b)
                                      percent = percent + pget
                                      
                                  shader.FreeRender()
                                  
                                  stop = timeit.default_timer()
                                  
                                  c4d.StatusClear()
                                  
                                  self.SetString(self.PROGRESS," 100%!")
                                  self.SetReal(self.PROGRESS_SLIDER, 100,min = 0, max = 100.0)
                                  OutInfo = shader.GetName()+" shader rendered in "+str(stop - start)+" seconds"
                                  self.SetString(self.RENDERINFO, OutInfo)
                                  
                                  return bmp
                              
                              if id == self.RENDER:
                                  w = self.GetInt32(self.WIDTH)
                                  h = self.GetInt32(self.HEIGHT)
                                  Abmp = RenderShader(w,h,sh)
                                  ShowBitmap(Abmp)
                                  
                              if id == self.RENDER_BIT:
                                  Ibmp = RenderShader(120,120,sh)
                                  self.myBitButton.SetImage(Ibmp)
                                  self.SetString(self.PROGRESS,"0%")
                                  self.SetReal(self.PROGRESS_SLIDER, 0,min = 0, max = 100.0)
                                  self.myBitButton.SetImage(Ibmp)
                                  
                              if id == self.SHADERLINK:
                                  Ibmp = RenderShader(120,120,sh)
                                  self.myBitButton.SetImage(Ibmp)
                                  self.SetString(self.PROGRESS,"0%")
                                  self.SetReal(self.PROGRESS_SLIDER, 0,min = 0, max = 100.0)
                                  self.myBitButton.SetImage(Ibmp)
                                  
                              if id == self.PROFILESELECT:
                                  Ibmp = RenderShader(120,120,sh)
                                  self.myBitButton.SetImage(Ibmp)
                                  self.SetString(self.PROGRESS,"0%")
                                  self.SetReal(self.PROGRESS_SLIDER, 0,min = 0, max = 100.0)
                                  self.myBitButton.SetImage(Ibmp)
                                  
                              return True
                        
                      dlg = BasicDialog()
                      dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-1, ypos=-1)
                      
                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        On 14/01/2015 at 00:43, xxxxxxxx wrote:

                        Hi Shawn,

                        Thanks for posting your code. I should have asked in which context you where calling InitRender().
                        I thought you were invoking InitRender() from a ShaderData plugin.
                        Unfortunately InitRenderStruct.linear_workflow and InitRenderStruct.document_colorprofile are read-only in the Python API and can't be set.
                        I'll report this limitation to the development team.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post