Is it possible to create a "Displacement Bitmap" or "Pixel Displacement Map" to achieve the effects in my image, by pre-calculating pixel displacements, storing the displacement vectors in an array, and offloading the heavy lifting to the GPU? My Googling leads me to suspect GDI+ and Direct2D can do it, but I can't find any examples I can learn from.
The furthest I've gotten is these two links:
https://docs.microsoft.com/en-us/win...splacement-map
https://innerdrivestudios.com/home/d...t-maps-basics/
Can anyone help me figure out how to do this through VB6?
Code:Option Explicit 'SeabrookStan 12/2021 Dim hW As Long, hH As Long Const Pi = 3.14159265 Const HalfPi = 3.14159265 / 2 Private Sub Form_Load() hW = PBo.ScaleWidth / 2 'halfWidth (PBo contains the original image) hH = PBo.ScaleHeight / 2 'halfHeight Show PB1.Picture = PBo.Picture PB2.Picture = PBo.Picture PB3.Picture = PBo.Picture PB4.Picture = PBo.Picture DisplacePixels End Sub Private Sub DisplacePixels() Dim DisplacementRadius As Single Dim x As Long, y As Long Dim dX As Single, dY As Single Dim D As Single, P As Single, A As Single DisplacementRadius = hH * 0.94 'arbitrary radius size of circular distortion For x = 0 To PBo.ScaleWidth For y = 0 To PBo.ScaleHeight dX = (x - hW): dY = (y - hH) 'Horizontal and Vertical distances from center of distortion D = Sqr(dX * dX + dY * dY) 'Distance of Destination Pixel from Distortion Center (vector length) If D > DisplacementRadius Then Else 'Magnify -> PB1 P = D / DisplacementRadius PB1.PSet (x, y), PBo.Point(hW + dX * P, hH + dY * P) 'Shrink -> PB2 P = 2 - (D / DisplacementRadius) PB2.PSet (x, y), PBo.Point(hW + dX * P, hH + dY * P) 'Rotate -> PB3 'A = ArcTanRadians(dX, dY) 'Current angle 'PB3.PSet (x, y), PBo.Point(hW + D * Sin(A + 10), hH + D * Cos(A + 10)) 'Ripple -> PB3 A = ArcTanRadians(dX, dY) 'Current angle PB3.PSet (x, y), PBo.Point(hW + (D + Cos(D * 0.1) * 8) * Sin(A), hH + (D + Cos(D * 0.1) * 8) * Cos(A)) 'Spiral -> PB4 P = (DisplacementRadius - D) / (D + 0.0001) ' 0.0001 to avoid division by zero error A = A + P * HalfPi * 0.25 'Current angle, plus additional varying angle PB4.PSet (x, y), PBo.Point(hW + D * Sin(A), hH + D * Cos(A)) End If 'Waves -> PB5 PB5.PSet (x, y), PBo.Point(x, y + Cos(x * 0.02) * 20) Next y Refresh Next x End Sub Public Function ArcTanRadians(y As Single, x As Single) As Single If x > 0 Then ArcTanRadians = Atn(y / x) ElseIf x < 0 Then ArcTanRadians = Sgn(y) * (Pi - Atn(Abs(y / x))) ElseIf y = 0 Then ArcTanRadians = 0 Else ArcTanRadians = Sgn(y) * HalfPi End If End Function




Reply With Quote
