Recent

Author Topic: Need help with phong  (Read 3500 times)

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Need help with phong
« on: June 04, 2024, 06:02:53 pm »
I am working on a component and I want to add some 3D effect by using phong.
My problem is with the phong working on the whole bitmap, but I need to keep the background in one color.
In the screenshot, I want the area outside the arc to remain in background color.

Here is the complete drawing procedure:
Code: Pascal  [Select][+][-]
  1. procedure TBSelector.Redraw;
  2. const
  3.   pi15 = pi * 1.5;
  4. var
  5.   textBmp: TBGRABitmap;
  6.   textStr: string;
  7.   EffectiveSize: integer;
  8.   EffectiveLineWidth: single;
  9.   r: single;
  10.   RMinAngle, RMaxAngle, RMinTicksAngle, RMaxTicksAngle, RAngle: single;
  11.   blur: TBGRABitmap;
  12.   mask: TBGRABitmap;
  13.   phong: TPhongShading;
  14.  
  15.   procedure DoDrawArc(a, b: single; c: TColor);
  16.   begin
  17.     FBitmap.Canvas2D.strokeStyle(c);
  18.     FBitmap.Canvas2D.beginPath;
  19.     FBitmap.Canvas2D.arc(0, 0, r, a, b, False);
  20.     FBitmap.Canvas2D.stroke;
  21.   end;
  22.  
  23.   procedure DoDrawTicks(a, b: single; c: TColor);
  24.   begin
  25.      //ToDo
  26.   end;
  27.  
  28. begin
  29.   FBitmap.SetSize(Width, Height);
  30.   FBitmap.Fill(FBkgColor);
  31.  
  32.   if Width < Height then
  33.     EffectiveSize := Width
  34.   else
  35.     EffectiveSize := Height;
  36.  
  37.   if EffectiveSize < 2 then exit;
  38.  
  39.  
  40.   FBitmap.Canvas2D.resetTransform;
  41.   FBitmap.Canvas2D.translate(FBitmap.Width / 2, FBitmap.Height / 2);
  42.   FBitmap.Canvas2D.rotate(pi15);
  43.  
  44.   if FLineWidth = 0 then
  45.     EffectiveLineWidth := EffectiveSize / 12
  46.   else
  47.     EffectiveLineWidth := FLineWidth;
  48.   r := (EffectiveSize - EffectiveLineWidth) / 2;
  49.  
  50.   FBitmap.Canvas2D.lineWidth := EffectiveLineWidth;
  51.  
  52.   RMinAngle := (180 + FMinAngle) * pi / 180;
  53.   RMaxAngle := ((180 + FMaxAngle) * pi / 180) - RMinAngle;
  54.  
  55.   RMinTicksAngle := (180 + FMinTicksAngle) * pi / 180;
  56.   RMaxTicksAngle := ((180 + FMaxTicksAngle) * pi / 180) - RMinTicksAngle;
  57.  
  58.   FBitmap.Canvas2D.lineCapLCL := pecRound;
  59.   // background line
  60.   if FLineBkgColor <> clNone then
  61.     DoDrawArc(RMinAngle, (RMaxAngle + RMinAngle), FLineBkgColor);
  62.  
  63.   RAngle := (RMaxTicksAngle / (FTicksCount + FOffset)) * ((FValue + FOffset) - ((FTicksCount + FOffset) / 2));
  64.  
  65.   if Enabled then
  66.   begin
  67.     if FValue >= 0 then
  68.       DoDrawArc(RAngle - FPointerSize / 100, RAngle + FPointerSize / 100, FLineColor);
  69.   end
  70.   else
  71.     DoDrawArc(RAngle - FPointerSize / 100, RAngle + FPointerSize / 100, clGray);
  72.  
  73.   if FDrawText then
  74.   begin
  75.     if FItems.Count >= FValue then
  76.       textStr := FItems[FValue]
  77.     else
  78.       textStr := 'NaN';
  79.     textBmp := TextShadow(Width, Height, textStr, Font.Height,
  80.       Font.Color, FontShadowColor, FontShadowOFfsetX,
  81.       FontShadowOffsetY, FontShadowRadius, Font.Style, Font.Name) as TBGRABitmap;
  82.     FBitmap.PutImage(0, 0, textBmp, dmDrawWithTransparency);
  83.     textBmp.Free;
  84.   end;
  85.  
  86.   if FDrawTicks then
  87.     DoDrawTicks(-(FBitmap.Width / 2 - 5), 0, clBlack);
  88.  
  89.   if FDrawPhong then
  90.   begin
  91.     mask := FBitmap.FilterGrayscale as TBGRABitmap;
  92.     mask.Negative;
  93.     blur := Mask.FilterBlurRadial(5, 5, rbFast) as TBGRABitmap;
  94.     blur.FillMask(0, 0, mask, BGRAPixelTransparent, dmSet);
  95.  
  96.     phong := TPhongShading.Create;
  97.     phong.Draw(FBitmap, blur, 2, 0, 0, FBitmap);
  98.  
  99.     phong.Free;
  100.     blur.Free;
  101.     Mask.Free;
  102.   end;
  103.  
  104.   FBitmap.Draw(Canvas, 0, 0, True);
  105. end;

Edit: added another screenshot. Top is with inverted mask, bottom without inversion. Right is the flat component without phong effect

lainz

  • Hero Member
  • *****
  • Posts: 4618
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: Need help with phong
« Reply #1 on: June 05, 2024, 02:29:50 am »
Hi you need to use masks. Check the bgrabitmap wiki from the links at the left in the forum.

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #2 on: June 05, 2024, 07:46:46 pm »
Two components (almost) finished: TBSelector and TBRingSlider

circular

  • Hero Member
  • *****
  • Posts: 4356
    • Personal webpage
Re: Need help with phong
« Reply #3 on: June 05, 2024, 07:52:26 pm »
Beautitful! Using Phong in this case is nice touch :)

I suggest to draw the text after the Phong effect, so that it would not be affected by it, to improve readability.
Conscience is the debugger of the mind

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #4 on: June 05, 2024, 08:00:16 pm »
I suggest to draw the text after the Phong effect, so that it would not be affected by it, to improve readability.
I got the same idea after I've posted the screenshot here. I'll probably make it a selectable property.

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #5 on: June 05, 2024, 08:07:16 pm »
I would like to add a glow to the pointer, to be more like a lightning LED, but it is too much for my knowledge of graphics.
Selector is also missing the ticks, but it is also too much for my knowledge.

Next thing on ToDo list is a component for displaying algorithms (in the scope of FM synthesizers), something like on the screenshot from Dexed

circular

  • Hero Member
  • *****
  • Posts: 4356
    • Personal webpage
Re: Need help with phong
« Reply #6 on: June 05, 2024, 10:06:58 pm »
To do a lighting effect, something you could try is to draw in a separate bitmap the shape of the LED with a bright color, apply blur and blend it using BlendImageOver with the boGlow blend operation.

Here is a sample done with LazPaint.
Conscience is the debugger of the mind

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #7 on: June 06, 2024, 07:49:27 pm »
Thank you circular. I've done a LED component with some glow and blending.

circular

  • Hero Member
  • *****
  • Posts: 4356
    • Personal webpage
Re: Need help with phong
« Reply #8 on: June 06, 2024, 10:10:54 pm »
Hmmm I may be missing something but I don't see the glow around the object. With blur, the glow would go beyond the border of the shape.
Conscience is the debugger of the mind

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #9 on: June 06, 2024, 10:44:30 pm »
I have phong on the shape, and that is making shadow on the whole background (just like in my opening post here). I have a mask to cut off everything outside the original shape in order to preserve the original background color.
I'll need to play a little bit more with this...

If you would like to take a look at the current state of the code, it is in the attachment

circular

  • Hero Member
  • *****
  • Posts: 4356
    • Personal webpage
Re: Need help with phong
« Reply #10 on: June 07, 2024, 03:05:51 am »
Hi Bobby!

Sure, I'm glad to help. Making the glow effect depend on subtle settings.

I've looked at your code and made the following adjustments:
- draw the glow afterwards, with a transparent background and with BlendImageOver (with Over suffix)
- scale blur size used for Phong depending on DPI
- scale LED size depending on DPI
- a few changes in coordinates for centering

Scaling for DPI makes it look similar when zooming elements (in display settings of the OS).

 :)
Conscience is the debugger of the mind

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #11 on: June 07, 2024, 01:40:15 pm »
Thank you circular.
I did try BlendImageOver and I got similar results - there is a glow just on the outer edge of the LED. I was searching for an effect of the whole LED glowing/shinning.

circular

  • Hero Member
  • *****
  • Posts: 4356
    • Personal webpage
Re: Need help with phong
« Reply #12 on: June 07, 2024, 04:00:23 pm »
Ok. Yeah maybe there is more to it with a LED turned on.

Would you have a photograph of a LED that would resemble most what you would like to do?
Conscience is the debugger of the mind

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Need help with phong
« Reply #13 on: June 07, 2024, 05:54:02 pm »
Nah, this is already more than just good.
Take a look at this:
https://stock.adobe.com/at/images/neumorphic-knob-ui-kit-mobile-application-buttons-user-interface-or-ux-buttons-on-off-sliders-switches-and-volume-control-knobs-of-mobile-and-website-app-gui-minimal-neumorphism/461148823
I like it, and I am already satisfied with the resemblance. And your glow effect is the same as the one on the link.


 

TinyPortal © 2005-2018