Shaders- Displace method problem



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/11/2011 at 09:27, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   13 
    Platform:   Windows  ;   
    Language(s) :   C.O.F.F.E.E  ;  C++  ;

    ---------
    Hey guys.
    I'm trying to learn how shaders work. And I'm having trouble with the displace() method.

    Here's my Coffee plugin code:

    var PLUGIN_ID = 1000000;  
      
    class MyVolumeShdr : VolumePlugin  
    {  
      public:  
          MyVolumeShdr();  
      
          GetName();  
          GetID();  
          InitSettings(settings);  
          InitRender(settings);  
          FillInfoData(settings,is);  
          EditData(settings);  
          CalcSurface(settings,render,vd);  
          Displace(settings, render, vd);  
      
    };  
      
    MyVolumeShdr::MyVolumeShdr()  //Constructor of volume shader  
    {  
    super();  
    }  
    MyVolumeShdr::GetName()     
    {  
    return "My COFFEE Volume Example";  //Name of volume shader  
    }  
    MyVolumeShdr::GetID()  
    {  
      return PLUGIN_ID;  
    }  
      
    class RenderData  
    {  
      public:  
          var col;  
          var fbm;  
    };  
      
    // Settings=BaseContainer, render=Optional data structure with precalculation data(filled in InitRender), vd = a VolumeData structure  
    MyVolumeShdr::CalcSurface(settings,render,vd)    
    {      
      var diff,spec;                         //Create two vector variables to hold the diffuse, and specular, values  
                       
      var p = vd->tdata_im->GetMulP(vd->p);  //Get the inverse texture matrix(tdata) and the global position of each pixel?. And assign it to a variable "p"  
      p = p*15;                              //Increase the number of spots      
        
      var renderfbm = render->fbm->Fbm(5,p.x,p.y,p.z)*0.25+0.5;  
        
      vd->Illuminance1(&diff,&spec,5.0);     //Calculate diffuse and specular component for an exponent of 5  
        
      vd->col = vector(diff.x*render->col.x,diff.y*render->col.y,diff.z*render->col.z);  //Calculate surface color and store into 'vd->col'  
      vd->col = vd->col * renderfbm + 0.2*spec;                                          //Add the FBM spots on top of the color data  
    }  
      
    MyVolumeShdr::InitSettings(settings)  
    {  
      // 'settings' is a BaseContainer holding settings data  
      settings->SetData(1000,vector(0.0,0.0,1.0));  //Set the color to blue...1000 is the container's ID# that holds the color data  
      return TRUE;  
    }  
      
    MyVolumeShdr::InitRender(settings)              //Initialize structures for fast rendering  
    {  
      var rd = new(RenderData);                   //Create an instance of the RenderData class  
      if (!rd) return NULL;  
      
      rd->fbm = new(Noise);                       //Create an instance of the FBM noise class  
      if (!rd->fbm) return NULL;  
      
      rd->fbm->InitFbm(51.87,1.0);               //Must be called once before Fbm() or RidgedMultifractal() is called. Parameters are(lacunarity, float h)  
                                                 //Lacunarity is a measure of how a fractal fills space  
                                                   
      rd->col = settings->GetData(1000);         //Set the color from the IntSettings() method  
      
      return rd;  
    }  
      
    CalcFak(p)  
    {  
      p.x += 222.0;      
      p.y +=  24.0;  
      p.z += -222.0;  
        
      return TRUE;  
    }  
      
    Displace(settings, render, vd)         //<-------This method is not working!!!  
    {  
      var i,dv,sam,tcol,col=0.0;  
      var p1 = vd->tdata_im->GetMulP(vd->ray->p);  
      var p2 = vd->tdata_im->GetMulP(vd->p);  
      p1.y = p1.y*0.15+0.5;  
      p2.y = p2.y*0.15+0.5;  
      
      dv  = p2 - p1;  
      sam = int(8*vlen(dv));  
      if (sam<4) sam=4; else if (sam>20) sam=20;  
      dv /= sam-1;  
      
      for (i=0; i<sam; i++)  
      {  
          tcol = CalcFak(p1);  
          col += tcol;  
          p1  += dv;  
      }  
      
      col /= sam;  
      if (col>1.0) col=1.0;  
      vd->col   = vector(col);  
      vd->trans = vector(1.0-col);  
      
       
     return TRUE;  
    }  
      
      
    main() // register the VolumeShader 'MyVolumeShdr'  
    {  
      Register(MyVolumeShdr);  
    }
    

    I will eventually switch to C++ for this shader stuff. But I'm using Coffee&R13 to learn on because I can make changes and update them without closing C4D. And right now I'm learning by changing things and this is the fastest work flow.

    Can anyone tell me why my displace() method doesn't do anything?
    No errors. It simply doesn't produce any result.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/11/2011 at 13:35, xxxxxxxx wrote:

    First, just a small error; don't forgot to implement Displace() as a member of MyVolumeShdr (MyVolumeShdr::Displace).

    And I found why Displace() wasn't called. By default CalcSurface() is always called. To get Displace() called, we have to override VolumePlugin::GetInfo() and implement it like this:

    MyVolumeShdr::GetInfo(settings)
    {
        return SHADER_DISPLACE;
    }
    

    And for example, to get also CalcTransparency() called, return SHADER_DISPLACE|SHADER_TRANSPARENCY.

    Have a nice week-end 🙂.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/11/2011 at 15:23, xxxxxxxx wrote:

    Thanks Yannick.

    I made those changes and it still didn't do anything.
    But then I found this in the docs:`  vd->p += vd->dispn * factor
    When I use that code. In combination with your changes. It works.

    Thanks a lot for the help.
    You have a good weekend too.🍺

    -ScottA
    `


Log in to reply