Announcement

Collapse
No announcement yet.

3DSMax Bitmap Flags: (Output Amount, RGB Level, RGB Offset

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 3DSMax Bitmap Flags: (Output Amount, RGB Level, RGB Offset

    Dear all,

    this might be off-Topic, since it is not directy Vray-related:

    I would like to create the Bitmap operations that 3dsmax offers in a shader:

    RGB-Level, Offset, Output-Amount.

    Also I would like to Combine These operations with Premultiplied Image or Not, Image Alpha (None, From RGB Intensity, From Alpha), RGB Output taken from (Alpha as Grey, RGB) and with Mono Channel or RGB Channel Output.

    I have started with these lines, but the Output amount does't seem to deliver the correct results:

    Code:
    Bitmap.rgb *= rgbLevel //RGB Level;
    Bitmap.rgb = clamp(Bitmap.rgb + Offset * Bitmap.a, 0, 1) //RGB Offset
    Bitmap.rgba *= outputAmount; //Output Amount
    Can anybody help?

    To simplify this, I have assumed that Alpha is 1.0 and that the underlying Color, if any, is black. Even if I clamp the Alpha after Output-Amount calculation to 1.0, the result is wrong.
    Robert

    Max, VRay, Fusion:

    https://www.youtube.com/watch?v=g5fSLrVzpxg
    https://www.youtube.com/watch?v=bpmJgTb_9Ro

  • #2
    Hello,

    The Max output filter clamps after applying the output amount and only if the option is set.

    So it does something like this:

    1. If there are curve corrections - result.rgb = curves*input.rgb
    2. result.rgb *= rgbLevel
    3. result.rgb += (offset*input.a)
    4. result.rgba *= outputAmount
    5. If invert - result.rgb = 1 - result.rgb
    6. If clamp - clamp(result.rgba)
    7. If alpha from rgb - result.a=(result.r+result.g+result.b)/3

    Hope that helps

    Best regards,
    Yavor
    Yavor Rubenov
    V-Ray for 3ds Max developer

    Comment


    • #3
      Dear Yavor,

      thank you for the quick response.
      I have some additional questions, I hope, you don't mind.

      1. From my opinion in the offset-equation, one needs an obligatory clamp-part which is independent from the clamp-checkbox. When I do without and put an offset of -0.5, I get with my shader a Magenta-Color, with the max material I get a dark blue Color. The Bitmap is a light blue/Cyan. So the equation should be, is this true, or am I misunderstanding something?:

      result.rgb = clamp(result.rgb + offset * Input.a, 0,1);

      2. If I want to incorporate also the Parameter Alpha Source, where do I have to put them in your listing of code? From my opinion it should be in advance?
      Alpha Source = Image-Alpha -> do nothing
      Alpha Source = RGB Intensity -> result.a = intensityFromRGB(Input.rgb) //(Input.r + Input.g + Input b)/3.0
      Alpha Source = None -> result.a = 1.0;

      3.Premultiplied Alpha. When the Checkbox is checked, the code to be implemented is:
      result.rgb /= result.a;

      Is that true? And where in the listing should it be? This separate line is for the reason, that I can use a single blend function, when I want to blend the Bitmap with the underlying diffuse Color:

      result.rgb = Bitmap.rgb * Bitmap.a + diffuseColor.rgb * (1.0 - Bitmap.a); //same as result.rgb = lerp(Bitmap.rgb, diffuseColor.rgb, Bitmap.a);

      4. RGB Channel Output:
      -RGB -> Do nothing
      -Alpha as Grey -> result.rgb = result.aaa;

      Is it true and where in the code listing should it be?

      Sorry for all These questions. I have tried a lot but didn't find a solution that works in all directions. I could also post a shader-example with a generic Bitmap and a max-vray-material
      Robert

      Max, VRay, Fusion:

      https://www.youtube.com/watch?v=g5fSLrVzpxg
      https://www.youtube.com/watch?v=bpmJgTb_9Ro

      Comment


      • #4
        Hi Robert,

        1. Negative colors are clamped in various places in V-Ray. For example if you put your texture in the diffuse slot of the material - every component is clamped to 0 if negative. The clamping happens in the material so your texture should allow for negative values. In simple experiments with a Light material, VRayColor and an Output texture I get negative components.

        As for the rest - I'm not sure what are you trying to accomplish and what are you comparing against? If you can post the example and the Max textures that you want to match?
        Yavor Rubenov
        V-Ray for 3ds Max developer

        Comment


        • #5
          Hi Yavor,

          I have written a workflow to create a vr scene from a 3dsmax scene with texture baking. For this purpose I have created fragment-shaders that incorporate most of the properties from VRayMaterials with the different map types that Vray and Max offer, including bitmaps.


          What I want to achieve now is to incorporate most of the bitmap flags that the Output-rollout and the transparency/RGB/mono-Output section of the bitmap offer. I want to script this because I would like to have the option to properly blend the bitmap with any underlying (diffuse or any other) color if the bitmap is adjusted in a way to be transparent or if it carries transparency information. All the math should be done in a fragment shader. I have tried for two days now to achieve the result with experiments and testing.


          So far I have understood what the flags do, and here would be my proposal for a code. But this code doesn't deliver the same color as the bitmap blending does when I put it in the selfillumination section of the VrayMaterial. I have also attached some screenshots of 3dsmax and attached the png-image that I overlay with the selfilluminating color. I know that I throw to you quite a big pile of questions, hope you don't mind.
          Maybe in the following equations there are some clampings missing here and there, or some gamma corrections or the premultiplied alpha is wrong.

          //underlying color (e.g. diffuse color)
          float4 baseColor = ( 1.0f, 0.0f, 0.0f, 1.0f);

          //RGB Channel Output (RGB, Alpha as Grey)
          int rgbChannelOutput = 1;

          //Mono Channel Output (RGB Intensity, Alpha)
          int monoChannelOutput = 1;

          //Alpha Source: 1= Image Alpha, 2 = RGB Intensity, 3 = None (Opaque)
          int alphaSource = 3;


          //Premultiplied Alpha Checkbox
          bool premultipliedAlpha = false;

          //Output rollout

          float rgbLevel = 1.0;
          float offset = 0.0;
          float outputAmount = 1.0;
          bool invert = false;
          bool clampBool = false;
          bool alphaFromRGB = false;
           
          //intensityFromRGB = (bitmap.r + bitmap.g + bitmap.b) / 3.0
          if (alphaSource == 2) {
          bitmap.a = intensityFromRgb(bitmap.rgb);
          }
          else if (alphaSource == 3) {
          bitmap.a = 1.0;
          }
           
          //to compensate for premultiplied alpha in images: or bitmap.rgb *= bitmap.a; ??
          if (premultipliedAlpha) {
          bitmap.rgb /= bitmap.a;
          }
           
          //level, offset, outputAmount
          bitmap.rgb *= rgbLevel;
          bitmap.rgb = bitmap.rgb + offset * bitmap.a;
          bitmap.rgba *= outputAmount;
           
          if (invert) {
          bitmap.rgb = 1.0 - bitmap.rgb;
          }
          if (clampBool){
          bitmap.rgba = clamp(bitmap.rgba, 0, 1);
          }
          if (alphaFromRgb) {
          bitmap.a = intensityFromRgb(bitmap.rgb);
          }
           
          //rgb and mono channel outputs RGB-Channel-Output is for all color values, Mono-Channel-Output for Masks and skalar values like glossiness, fresnel. Seems to be not correct, or in the wrong place:
          if (rgbChannelOutput == 2) {
          bitmap.rgb = bitmap.aaa;
          }
           
          if (monoChannelOutput = 1) {
          bitmap.a = intensityFromRGB(bitmap.a);
          }
           
          //blending of bitmap with underlying color, same as lerp-function in shader-language (result = lerp(image1.rgb, image2.rgb, image1.a);
          psOut.Colour.rgb = bitmap.rgb * bitmap.a + baseColor.rgb * (1.0 -bitmap.a);
          Attached Files
          Last edited by Robert1977; 16-01-2017, 02:24 PM.
          Robert

          Max, VRay, Fusion:

          https://www.youtube.com/watch?v=g5fSLrVzpxg
          https://www.youtube.com/watch?v=bpmJgTb_9Ro

          Comment


          • #6
            Sorry, wrong images, here is the one that matches the code:
            Attached Files
            Robert

            Max, VRay, Fusion:

            https://www.youtube.com/watch?v=g5fSLrVzpxg
            https://www.youtube.com/watch?v=bpmJgTb_9Ro

            Comment


            • #7
              And here is the used png inside the material:
              Attached Files
              Robert

              Max, VRay, Fusion:

              https://www.youtube.com/watch?v=g5fSLrVzpxg
              https://www.youtube.com/watch?v=bpmJgTb_9Ro

              Comment


              • #8
                Hi Robert

                Now I get what are you trying to do

                The Bitmap does roughly this:

                First - All Max textures have two methods - one that gets Color result and one that gets float (mono) result. So when a color result is needed - the RGB Channel Output option is used and if a mono result is required - the Mono Channel Output.

                So for Color results they do something like this:

                if RGB Channel Output = RGB:

                1. AColor c=get rgba from image - here we apply UV mapping, filtering etc.. With a flat color image these won't matter
                2. Alpha source -
                Code:
                   if alphaSource = NONE - c.a=1.0f;
                   if alpha from rgb {
                	c.a=intensityFromRgb(c.rgb)
                	c.a=clamp(c.a,0,1)
                }
                3. Apply Output corrections - as per my previous post.
                4. if (!premultAlpha) c= AColor(c.r*c.a, c.g*c.a, c.b*c.a, c.a); So if the premultAlpha is OFF - do nothing
                5. If you want to blend with some fixed color - I think here is the place to do it.

                else (alphaAsRGB):

                1. AColor c=same as steps 1 and 2. No premultAlpha here.
                2. float f=intensityFromRgb(c.rgb)
                3. apply Output Corrections on f
                4. return AColor(f,f,f,f);


                Then the VRayMtl will do the following with the color:
                VRayMtl
                clampMin(rgb,0)
                clamp(alpha,0,1)

                Best regards,
                Yavor
                Yavor Rubenov
                V-Ray for 3ds Max developer

                Comment


                • #9
                  //red base color
                  float4 baseColor = float4(1.0, 0.0, 0.0, 1.0);

                  //output corrections
                  float outputAmount = 1.0;
                  float offset = 0.0;
                  float rgbLevel = 1.0;
                  bool
                  invert = false;
                  bool alphaFromRgb = false;
                  bool clampBool = false;

                  //Image Alpha: Premultiplied or not
                  bool premultipliedAlpha = false;

                  // "Alpha Src (Img Alpha, RGB Intens, None)"
                  int alphaSource = 1;

                  //Channel Outputs
                  // "RGB Channel Output (RGB, Alpha as Grey)"
                  int rgbChannelOutput = 1;

                  //"Mono Channel Output (RGB Intensity, Alpha)"
                  int monoChannelOutput = 1;

                  // "Use Output (RGB, Mono)"
                  int useRGBorMonoChannelOutput = 1;

                  float3 intensityFromRgb(float3 theColor)
                  {
                  return float((theColor.r + theColor.g + theColor. b) /3.0 );
                  }

                  float getAlpha(int alphaSource, float4 Bitmap)
                  {
                  float alpha = 1.0;

                  //Image alpha
                  if (alphaSource == 1)
                  {
                  alpha = bitmap.a;
                  }

                  //intensity from rgb
                  else if (alphaSource == 2)
                  {
                  alpha = intensityFromRgb(bitmap.rgb);
                  alpha = clamp(alpha, 0,1);
                  }

                  //NONE
                  else if (alphaSource == 3)
                  {
                  alpha = 1.0f;
                  }
                  return alpha;
                  }

                  float4 doCorrections(float4 bm, float rgbLevel, float offset, float outputAmount, bool clampBool, bool alphaFromRgb, bool invert)
                  {
                  //level, offset, outputAmount
                  bm.rgb *= rgbLevel;
                  bm.rgb = bm.rgb + offset * bm.a;
                  bm.rgba *= outputAmount;

                  //invert
                  if (invert){
                  bm.rgb = 1.0 - bm.rgb;
                  }

                  //clamp
                  if (clampBool){
                  bm.rgba = clamp(bm.rgba, 0, 1);
                  }
                  //alpha from rgb
                  if (alphaFromRgb) {
                  bm.a = intensityFromRgb(bm.rgb);
                  }
                  return bm;
                  }

                  //main body: Pixel Shader
                  float4 bitmap = float4(1,1,1,1);
                  float4 mask = float4(1,1,1,1);

                  bitmap.rgba = bitmaptexture_Map.rgba; //RGB channel output
                  mask.rgba = bitmaptexture_Mask.rgba; //mono channel output

                  //RGB Channel Output
                  if (useRGBorMonoChannelOutput == 1)
                  {
                  //RGB Channel Output = RGB
                  if (rgbChannelOutput == 1)
                  {
                  //alpha method
                  bitmap.a = getAlpha(alphaSource, bitmap);

                  //corrections from the output rollout
                  bitmap = doCorrections(bitmap, rgbLevel, offset, outputAmount, clampBool, alphaFromRgb, invert);

                  //to compensate for premultiplied alpha in images
                  if (premultipliedAlpha == false) {
                  bitmap.rgb *= bitmap.a;
                  }
                  }
                  //RGB Channel Output = Intensity from RGB
                  else if (rgbChannelOutput == 2)
                  {
                  //deactivated, has no effect in 3dsmax material
                  //bitmap.a = getAlpha(alphaSource, bitmap);
                  float f = intensityFromRgb(bitmap.aaa);
                  float4 bm = float4(f,f,f,bitmap.a);
                  bm = doCorrections(bm, rgbLevel, offset, outputAmount, clampBool, alphaFromRgb, invert);
                  bitmap.rgba = float4(bm.r,bm.r,bm.r,bm.r);
                  }
                  bitmap.rgb = bitmap.rgb + (baseColor.rgb * (1.0 - bitmap.a));
                  }
                  //Mono channel Output
                  else if (useRGBorMonoChannelOutput == 2)
                  {
                  //RGB intensity
                  if (monoChannelOutput == 1)
                  {
                  mask.a = intensityFromRgb(mask.rgb);
                  }
                  //Alpha
                  else if (monoChannelOutput == 2)
                  {
                  mask.a = getAlpha(alphaSource, mask);
                  }
                  //blending, this time we use a composite mapto show the effect of mono channel output
                  bitmap.rgb = bitmap.rgb + (baseColor.rgb * (1.0 - mask.a));
                  }

                  //clamp values after blending with fixed color
                  bitmap.rgb = max(bitmap.rgb,0);
                  bitmap.a = clamp(bitmap.a, 0,1);
                  Last edited by Robert1977; 18-01-2017, 04:10 AM.
                  Robert

                  Max, VRay, Fusion:

                  https://www.youtube.com/watch?v=g5fSLrVzpxg
                  https://www.youtube.com/watch?v=bpmJgTb_9Ro

                  Comment


                  • #10
                    Dear Yavor,

                    thank you for your valuable input. I have scripted the shader with your input and it seems to work now, except for the monochannel-output. I have posted the shader here (except for the texture-definitions, structs and vertex and fragment-shader-functions). So if you have a clue, how I could modify the monochannel-output, this would be great.In the shader I switch between rgb- and monochannel-output. This would be later in my workflow a decision made by maxscript so that the output shader wouldn’t include all options. Also the Vraymaterial “decides” itself which output to use.
                    I made two posts, because of the character Limitation. sorry for this inconvenience. The posted code has lost its indents (Tabs), sorry for this.
                    Last edited by Robert1977; 18-01-2017, 03:58 AM.
                    Robert

                    Max, VRay, Fusion:

                    https://www.youtube.com/watch?v=g5fSLrVzpxg
                    https://www.youtube.com/watch?v=bpmJgTb_9Ro

                    Comment


                    • #11
                      The VRayMtl uses the mono output only for mapped float values - for example the IOR parameter. If you put the shader there V-Ray will ask for mono output.

                      Apart from this for mono output I think you should do something like this:

                      Code:
                      else if (useRGBorMonoChannelOutput == 2)
                          {
                      		//RGB intensity
                      		if (monoChannelOutput == 1)
                      		{
                      			float f = intensityFromRgb(bitmap.rgb)
                      			bitmap.rgba = float4(f,f,f,f);
                      		}
                      		//Alpha
                      		else if (monoChannelOutput == 2)
                      		{
                      			float f = getAlpha(alphaSource, mask);
                      			bitmap.rgba = float4(f,f,f,f);
                      		}
                      		//blending, this time we use a composite mapto show the effect of mono channel output
                      		bitmap.rgb = bitmap.rgb + (baseColor.rgb * (1.0 - mask.a));
                          }
                      Yavor Rubenov
                      V-Ray for 3ds Max developer

                      Comment


                      • #12
                        Dear Yavor,

                        thank you for your input, I will test it now.
                        Concerning the indents I will use next time the code-brackets from the advanced menue .
                        Concerning the mono-channel-output, when I place the bitmap as a mask in a composite map inside e.g. the diffuse color slot, 3dsmax reacts on my selection between rgb intensity and alpha in the mono channel output, but not on the selection in the rgb-channel output. So my assumption was, that the mono-channel output is used by 3ds max also on bitmap masks, not only on mapped float values, is this possible?
                        Robert

                        Max, VRay, Fusion:

                        https://www.youtube.com/watch?v=g5fSLrVzpxg
                        https://www.youtube.com/watch?v=bpmJgTb_9Ro

                        Comment


                        • #13
                          Yes the composite map uses the float output for masks.
                          Yavor Rubenov
                          V-Ray for 3ds Max developer

                          Comment


                          • #14
                            I have now a working shader. Thanks for your input! For the monochannel output, I also used the output-corrections, once in rgb, once in alpha-mode.
                            If anyone is interested, I can post the finished shader as JPG.
                            Robert

                            Max, VRay, Fusion:

                            https://www.youtube.com/watch?v=g5fSLrVzpxg
                            https://www.youtube.com/watch?v=bpmJgTb_9Ro

                            Comment


                            • #15
                              Glad that my input helped
                              Yavor Rubenov
                              V-Ray for 3ds Max developer

                              Comment

                              Working...
                              X