Examples
This is by no means, an exhaustive reference of all functions available to plugins.
*All examples assume a Dogwaffle object has been created.
* Note, VB.Net will require a change in data types. VB5/6 uses 32 bit longs, and 16 bit Integers. VB.Net uses 64 bit longs, and 32 bit integers. Usage of VB5/6 is assumed in this document except where specified. See your VB.net migration documentation for full details.
The Basics and Image Related |
||
Brush Related |
||
Colors, Gradients, and Wells |
||
Animation Related |
||
Input Boxes and Special Functions |
||
All functions available to plugins are evoked through a Dogwaffle object.
'create a dogwaffle object
Dim Dogwaffle As Object
Set Dogwaffle = CreateObject("Dogwaffle.Dogwaffle_Class")
Getting a copy of the current image
'allocate the main buffers
Dim MainRBuffer() As Byte
Dim MainGBuffer() As Byte
Dim MainBBuffer() As Byte
Dim MainaBuffer() As Byte
'get the buffers
MainRBuffer() = Dogwaffle.Dog_GetRBuffer
MainGBuffer() = Dogwaffle.Dog_GetGBuffer
MainBBuffer() = Dogwaffle.Dog_GetBBuffer
MainaBuffer() = Dogwaffle.Dog_GetaBuffer
Sending an image back to Project Dogwaffle
'send the buffers back to dogwaffle.
Dogwaffle.Dog_SetRbuffer MainRBuffer()
Dogwaffle.Dog_SetGbuffer MainGBuffer()
Dogwaffle.Dog_SetBbuffer MainBBuffer()
'and refresh the screen
Dogwaffle.Dog_Refresh
Getting the width and height of the current image
'get the width and height of the buffer
dim tw as long, th as long
th = Dogwaffle.Dog_BufferHeight
tw = Dogwaffle.Dog_BufferWidth
Creating a new image (new buffer)
Dim MyFilename As String
MyFilename = "My new buffer"
tw = 640
th = 480
Dogwaffle.Dog_NewBuffer CInt(tw), CInt(th)
'Give the new buffer a name
'and update dogwaffles internal filename string
Dogwaffle.Dog_RenameBuffer (MyFilename)
Dogwaffle.Dog_NewFilename (MyFilename)
Dim alphabits As Long
alphabits = Dogwaffle.Dog_GetAlphabits
If alphabits is 0, then the alpha is active.
You can achieve alpha mixing like this. ((r * a) + (r2 * (255-a))) \ 255
‘r2,g2,b2 should be defined.
r = MainRBuffer(x, y)
g = MainGBuffer(x, y)
b = MainBBuffer(x, y)
If alphabits = 0 Then
a = MainaBuffer(x, y)
a2 = 255 - a
r = ((r * a) + (r2 * a2)) \ 255
g = ((g * a) + (g2 * a2)) \ 255
b = ((b * a) + (b2 * a2)) \ 255
End If
As your plugin executes code, you can keep the user informed about the progress with the plugin progress bar. It is called with a Single value between 0 and 100, like this:
Dim Value As Single
Value = 50
Dogwaffle.Dog_SetProgress Value
Always remember to reset the progress bar when finished.
Dogwaffle.Dog_SetProgress 0
Changing the mouse pointer to an hourglass pointer
Dogwaffle.Dog_ChangePointer (11)
Change it back
Dogwaffle.Dog_RestorePointer
You are not required to save an undo when running a plugin, since one is automatically saved, however, the function is available.
Dogwaffle.Dog_SaveUndo
A buffer can be locked to keep the user from making changes while a plugin is in progress. You must unlock a buffer once you have finished with it.
Dogwaffle.Dog_Lock
Unlock buffer
Dogwaffle.Dog_Unlock
The locking mechanism keeps a count of buffer locks. If a plugin should happen to crash before unlocking the buffer, it may be required to perform a hard unlock.
Dogwaffle.Dog_UnlockHard
Custom Brushes
Getting the current custom brush image
If the width of the current custom brush is 0, then there is no custom brush currently defined. See Getting the current custom brush’s width and height
'dim the buffers
Dim MainRBuffer() As Byte
Dim MainGBuffer() As Byte
Dim MainBBuffer() As Byte
Dim MainABuffer() As Byte
'get the buffers from dogwaffle
MainRBuffer() = Dogwaffle.Dog_GetBrushRBuffer
MainGBuffer() = Dogwaffle.Dog_GetBrushGBuffer
MainBBuffer() = Dogwaffle.Dog_GetBrushBBuffer
MainABuffer() = Dogwaffle.Dog_GetBrushABuffer
Getting the current custom brush’s width and height
Dim tw As Long, th As Long
tw = Dogwaffle.Dog_GetBrushWidth
th = Dogwaffle.Dog_GetBrushHeight
To create a new custom brush, first you initialize it by calling CreateEmptyBrush, then you send your own imagery defined in a set of byte arrays.
Dim tw As Long, th As Long
'create a brush at 100x100 pixel...
tw = 100
th = 100
'dim the buffers
ReDim BrushRBuffer(tw, th) As Byte
ReDim BrushGBuffer(tw, th) As Byte
ReDim BrushBBuffer(tw, th) As Byte
'brushes have a 'key' channel, similar to an alpha channel.
ReDim BrushABuffer(tw, th) As Byte
'create a new, empty brush. This must be done before sending any imagery.
Dogwaffle.Dog_CreateEmptyBrush tw, th
'Do something to fill in the brush arrays here...
For y = 0 To th - 1
For x = 0 To tw - 1
BrushRBuffer(x, y) = Rnd * 255
BrushGBuffer(x, y) = Rnd * 255
BrushBBuffer(x, y) = Rnd * 255
BrushABuffer(x, y) = Rnd * 255
Next
Next
'send the brush buffers to dogwaffle.
Dogwaffle.Dog_SetBrushRBuffer BrushRBuffer()
Dogwaffle.Dog_SetBrushGBuffer BrushGBuffer()
Dogwaffle.Dog_SetBrushBBuffer BrushBBuffer()
Dogwaffle.Dog_SetBrushABuffer BrushABuffer()
'can optionally activate the brush tool.
Dogwaffle.Dog_ActivateCustomBrush
'Also optional, but refreshes things like the brush key panel when the brush changes.
Dogwaffle.Dog_Refresh_BrushDisplays
User input
There are several pre-defined requesters (dialog boxes) that plugins can access. They include file requesters, text and value input, and message boxes.
Presents a file dialog to the user
MyFilename = Dogwaffle.Dog_RequestFile_Open("Select a file to open", "", "BMP|*.bmp")
MyFilename = Dogwaffle.Dog_RequestFile_Save("Select a file to save", "", "BMP|*.bmp")
A result of “” means the requester was canceled.
Presents a message to the user
Dogwaffle.dog_MessageBox "Done"
Presents the user with a choice of Ok or Cancel.
Dummy = Dogwaffle.Dog_QuestionBox("Shall I proceed?")
If Dummy = 2 Then Exit Sub
*Messages with multiple lines can be created by instering chr$(13) into the message string for message and question boxes.
MyString = "The first line of text" + Chr$(13) + "The second line of text"
Dummy = Dogwaffle.Dog_QuestionBox(MyString)
Value boxes
Retrieves a value from the user within a specific range.
Value = Dogwaffle.Dog_ValueBox("Enter new value ", 1, 100)
If Value = -1 Then Exit Sub
A variation on this allows a caption and a default value to be applied to the window
Value = Dogwaffle.Dog_ValueBox2("Enter new value ", "Caption", 1, 100, 10)
The Primary and Secondayr Colors
Getting the primary or secondary colors
Dim tempcolor
tempcolor = Dogwaffle.Dog_getPrimaryColor
‘tempcolor = Dogwaffle.Dog_getSecondaryColor
r = tempcolor And &HFF& 'the extra '&' coerces it into a long. VB is 16 bit by default. Go figure.
g = (tempcolor And &HFF00&) \ 256
b = (tempcolor And &HFF0000) \ 65536
The gradient
Getting a copy of the gradient
An example. This displays the gradient on a picturebox control with scalemode set to pixel.
Dim MyArray() As Byte
ReDim MyArray(255, 2)
MyArray = Dogwaffle.Dog_GetGradient(Dogwaffle.Dog_GetGradientIndex)
h = Picture1.ScaleWidth
For X = 0 To 255
r = MyArray(X, 0)
g = MyArray(X, 1)
b = MyArray(X, 2)
Picture1.Line (X, 0)-(X, h), RGB(r, g, b)
Next
Wells
Setting colors in the color wells
'example, put random colors in the color wells
Dim MyWell() As Long
ReDim MyWell(63) '64 colors
For n = 0 To 63
MyWell(n) = RGB(Rnd * 255, Rnd * 255, Rnd * 255)
Next
'send it to dogwaffle
Dogwaffle.Dog_SetWells MyWell
Animation
Dogwaffle.dog_gotoframe frame
Getting the number of frames in an animation
TotalFrames = Dogwaffle.dog_GetTotalFrames
Play and stop animation playback
Dogwaffle.dog_PlayAnimation
Dogwaffle.dog_StopAnimation
An example of asking the user how many frames of a new animation to create.
Dim Value As Long
Value = Val(InputBox("Create new animation", "Frame count", "30"))
If Value <= 1 Then Exit Sub
Dogwaffle.Dog_CreateAnim Value
Dogwaffle.Dog_ShowScrub 0, Dogwaffle.Dog_GetTotalFrames
Processing the frames of an animation
To process the frames of an animation, simply go to each frame with a call to Dog_GotoFrame, then use the regular buffer functions to retrieve and set the RGB buffers. When finished with every frame, return to the first frame with a final call to Dog_GotoFrame.
'allocate the main buffers
Dim n As Long
Dim MainRBuffer() As Byte
Dim MainGBuffer() As Byte
Dim MainBBuffer() As Byte
Dim MainaBuffer() As Byte
Dim tw As Long, th As Long, x As Long, y As Long
Dim Begin_Frame As Long, End_Frame As Long
th = Dogwaffle.Dog_BufferHeight
tw = Dogwaffle.Dog_BufferWidth
Begin_Frame = 0
End_Frame = Dogwaffle.dog_GetTotalFrames - 1
For n = Begin_Frame To End_Frame
Dogwaffle.Dog_GotoFrame n
'Get the buffers for the current frame
MainRBuffer() = Dogwaffle.Dog_GetRBuffer
MainGBuffer() = Dogwaffle.Dog_GetGBuffer
MainBBuffer() = Dogwaffle.Dog_GetBBuffer
MainaBuffer() = Dogwaffle.Dog_GetaBuffer
'Process the buffer in some way.
For y = 0 To th-1
For x = 0 To tw-1
MainRBuffer(x, y) = 255 - MainRBuffer(x, y)
MainGBuffer(x, y) = 255 - MainGBuffer(x, y)
MainBBuffer(x, y) = 255 - MainBBuffer(x, y)
Next
Next
'Send it back
Dogwaffle.Dog_SetRbuffer MainRBuffer
Dogwaffle.Dog_SetGbuffer MainGBuffer
Dogwaffle.Dog_SetBbuffer MainBBuffer
'should probably use progress bar
Next
Dogwaffle.Dog_GotoFrame Begin_Frame
Dogwaffle.dog_Refresh
Special Functions
Project Dogwaffle maintains a Temp directory for temporary storage. You may use this directory for your own use, and you are required to clean up after yourself. Here’s how to get the pathname for the Temp directory.
Dim tempdir As String
tempdir = Dogwaffle.Dog_GetTempDir
Here’s an example that lets the user explore the temp directory.
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Const SW_SHOWNORMAL = 1
Sub Main()
Dim Dogwaffle As Object, Dim tempdir As String
Set Dogwaffle = CreateObject("Dogwaffle.Dogwaffle_Class")
tempdir = Dogwaffle.Dog_GetTempDir
ShellExecute 0, vbNullString, "", vbNullString, tempdir, SW_SHOWNORMAL
End Sub
These functions are exported by Drpaint.dll.
There are some structures in the Windows OS that require direct access to memory, such as Dibs. The following functions are exported for your convenience, but use them with caution.
'send by ref and returns a pointer in a long
Declare Function GetAddressByte Lib "Drpaint.dll" (ByRef MyArray As Byte) As Long
Declare Function GetAddressWord Lib "Drpaint.dll" (ByRef MyArray As Integer) As Long
Declare Function GetAddressLong Lib "Drpaint.dll" (ByRef MyArray As Long) As Long
'
Declare Sub WriteByte Lib "Drpaint.dll" (ByVal Address As Long, ByVal val As Byte)
Declare Sub WriteWord Lib "Drpaint.dll" (ByVal Address As Long, ByVal val As Integer)
Declare Sub WriteLong Lib "Drpaint.dll" (ByVal Address As Long, ByVal val As Long)
'
Declare Function ReadByte Lib "Drpaint.dll" (ByVal Address As Long) As Byte
Declare Function ReadWord Lib "Drpaint.dll" (ByVal Address As Long) As Integer
Declare Function ReadLong Lib "Drpaint.dll" (ByVal Address As Long) As Long
These are not members of the plugin interface, but are functions exported from drfilter.dll for general image processing
Convolution Kernel
This function performs a convolution kernel filter on an image contained in an byte array, and stores it in another array.
Declare Function Convolve8 Lib "drfilter.dll" (source As Byte, dest As Byte, ByVal W As Integer, ByVal h As Integer, ByVal v1 As Single, ByVal v2 As Single, ByVal v3 As Single, ByVal v4 As Single, ByVal v5 As Single, ByVal v6 As Single, ByVal v7 As Single, ByVal v8 As Single, ByVal v9 As Single, ByVal vsum As Single, ByVal mean As Integer) As Long
Example of using a convolution kernel to emboss an image. In this case, it’s a greyscale image; Apply once for each buffer of a color image.
With different kernels, you could also apply blur, edge detect, sharpen, and other effects.
'do an emboss
v1 = -1 : v2 = -1 : v3 = 0
v4 = -1 : v5 = 0 : v6 = 1
v7 = 0 : v8 = 1 : v9 = 1
vsum = 1
dummy = Convolve8(TempBuffer(0, 0), Mainbuffer(0, 0), TempWidth, TempHeight, v1, v2, v3, v4, v5, v6, v7, v8, v9, vsum, 128)
Sobel Edge Detection
Sobel Edge detection is an important component of many of the routines used to mimic traditional pencil drawing, such as ‘Loose and Sketchy’. This implementation uses a floating point buffer, so a Dogwaffle buffer needs to be converted to single before use, and then back.
Declare Function SobelF Lib "drfilter.dll" (Source As Single, Dest As Single, ByVal W As Long, ByVal h As Long) As Long
This function multiplies all the values in a byte array by a specified value. You could use this once for each R,G, and B channels to make a color adjustment filter, or to adjust the value of a greyscale image.
Declare Function ChannelValue Lib "drfilter.dll" (source As Byte, dest As Byte, abuf As Byte, ByVal alphabits As Byte, ByVal W As Integer, ByVal h As Integer, ByVal value As Single) As Long
These functions apply color or value noise to all the arrays of an image.
Declare Sub ApplyValueNoise Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, abuf As Byte, ByVal alphabits As Byte, ByVal W As Long, ByVal h As Long, ByVal value As Long)
Declare Sub ApplyColorNoise Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, abuf As Byte, ByVal alphabits As Byte, ByVal W As Long, ByVal h As Long, ByVal value As Long)
Blue Screen and Green Screen
The blue and greenscreen functions require a lookup table of 256 bytes that define a ramp.
Declare Sub FastBluescreen Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, abuf As Byte, ByVal W As Long, ByVal h As Long, rbuf2 As Byte, gbuf2 As Byte, bbuf2 As Byte, rbuf3 As Byte, gbuf3 As Byte, bbuf3 As Byte, lut As Byte, ByVal Fakeblue As Long, ByVal alphabits As Long)
Declare Sub FastGreenscreen Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, abuf As Byte, ByVal W As Long, ByVal h As Long, rbuf2 As Byte, gbuf2 As Byte, bbuf2 As Byte, rbuf3 As Byte, gbuf3 As Byte, bbuf3 As Byte, lut As Byte, ByVal Fakegreen As Long, ByVal alphabits As Long)
Threshold
Converts an image to black or white, with the median being a specified value.
Declare Sub FastThreshold Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, rbuf2 As Byte, gbuf2 As Byte, bbuf2 As Byte, ByVal W As Long, ByVal h As Long, ByVal Threshold As Long, ByVal Invert As Long)
Median
Declare Sub FastMedian Lib "drfilter.dll" (uRbuf As Byte, ugBuff As Byte, ubBuff As Byte, Rbuff As Byte, Gbuff As Byte, BBuff As Byte, abuf As Byte, ByVal alphabits As Byte, ByVal W As Long, ByVal h As Long)
Jitter
Declare Sub FastJitter Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, abuf As Byte, ByVal W As Long, ByVal h As Long, rbuf2 As Byte, gbuf2 As Byte, bbuf2 As Byte, ByVal value As Long, ByVal alphabits As Long)
Posterize
Declare Sub FastPosterize Lib "drfilter.dll" (rbuf As Byte, gbuf As Byte, bbuf As Byte, abuf As Byte, ByVal W As Long, ByVal h As Long, rbuf2 As Byte, gbuf2 As Byte, bbuf2 As Byte, ByVal value As Long, ByVal alphabits As Long)
Tint
Declare Sub FastTint Lib "drfilter.dll" (ByRef rbuffer As Byte, ByRef GBuffer As Byte, ByRef bbuffer As Byte, ByRef destrbuffer As Byte, ByRef destgbuffer As Byte, ByRef destbbuffer As Byte, ByVal r As Long, ByVal g As Long, ByVal b As Long, ByVal W As Long, ByVal h As Long)
Drawing Functions
Draws a pen into a single channel. Requires 3 calls for color, one for each channel. The pen is fully antialiased and uses floating point coordinates.
Declare Sub AAcpen Lib "drfilter.dll" (ByRef Dest As Byte, ByVal X As Single, ByVal Y As Single, ByVal Size As Single, ByVal intensity As Single, ByVal opacity As Single, ByVal W As Long, ByVal h As Long)
Declare Sub AAcpenAlhpa Lib "drfilter.dll" (ByRef Dest As Byte, ByRef Alpha As Byte, ByVal X As Single, ByVal Y As Single, ByVal Size As Single, ByVal intensity As Single, ByVal opacity As Single, ByVal W As Long, ByVal h As Long)
AngleOf
Returns the angle between x, y, and 0, 0.
Declare Function Angleof Lib "drfilter.dll" (ByVal X As Single, ByVal Y As Single) As Single
HSV
Declare Sub RGB_To_HSV Lib "drfilter.dll" (ByVal r As Single, ByVal g As Single, ByVal b As Single, h As Single, s As Single, v As Single)
Declare Sub HSV_To_RGB Lib "drfilter.dll" (r As Single, g As Single, b As Single, ByVal h As Single, ByVal s As Single, ByVal v As Single)
Bit Shift
Shift Right
Public Function ShiftR(ByVal e As Long, ByVal v As Long) As Long
If v = 0 Then ShiftR = e: Exit Function
Dim n As Long
For n = 0 To v - 1
e = e \ 2
Next
ShiftR = e
End Function
Shift Left
Public Function ShiftL(ByVal e As Long, ByVal v As Long) As Long
If v = 0 Then ShiftL = e: Exit Function
Dim n As Long
For n = 0 To v - 1
e = e * 2
Next
ShiftL = e
End Function
Swap
Public Sub Swap(ByRef v1, ByRef v2)
'swap two variables. saves declairing spare storage
'simple enough to do inline.
v1 = v1 Xor v2
v2 = v2 Xor v1
v1 = v1 Xor v2
End Sub
Return minimum of two values
Public Function Minimum(ByVal v1 As Long, ByVal v2 As Long) As Long
'returns the min of two values
If v1 > v2 Then Minimum= v2 Else Minimum= v1
End Function
Return maximum of two values
Public Function Maximum(ByVal v1 As Long, ByVal v2 As Long) As Long
'returns the max of two values
If v1 > v2 Then Maximum= v1 Else Maximum= v2
End Function
Swaps two values so the first is the smallest value
Public Function MinSwap(ByRef v1 As Long, ByRef v2 As Long) As Long
'swaps the values to make the smallest first
'returns 1 if values swapped or 0 if not
If v1 > v2 Then
v1 = v1 Xor v2
v2 = v2 Xor v1
v1 = v1 Xor v2
MinSwap = 1
Else
MinSwap = 0
End If
End Function
Swaps two values so the first is the largest value
Public Function MaxSwap(ByRef v1 As Long, ByRef v2 As Long) As Long
'swaps the values to make the smallest first
'returns 1 if values swapped or 0 if not
If v1 < v2 Then
MaxSwap = 1
v1 = v1 Xor v2
v2 = v2 Xor v1
v1 = v1 Xor v2
Else
MaxSwap = 0
End If
End Function
Rotates a 2-D point around 0
Public Sub RotatePoint(ByVal angle As Single, ByRef u As Single, ByRef v As Single)
'currently rotates around 0
'Rotating a 2d object is around a single axis
'rotating a 3d object is around 3 axisis,
'so call this once for each axis.
angle = angle * 0.01745
Dim New_U As Single
Dim New_V As Single
New_U = u * Cos(angle) - v * Sin(angle)
New_V = u * Sin(angle) + v * Cos(angle)
u = New_U
v = New_V
End Sub
Converting ‘packed’ colors
Dim R As Long, G As Long, B As Long, C As Long
C = Picture1.Point(X, Y)
R = C And &HFF&
G = (C And &HFF00&) \ &H100&
B = (C And &HFF0000) \ &H10000
Distance between two points
Public Function Distance(x1 As Single, y1 As Single, x2 As Single, y2 As Single) As Single
'Find the distance
Dim xSum As Single
Dim ySum As Single
Dim Totalsum As Single
xSum = x1 - x2
xSum = Abs(xSum)
xSum = xSum ^ 2
ySum = y1 - y2
ySum = Abs(ySum)
ySum = ySum ^ 2
Totalsum = xSum + ySum
Distance = Sqr(Totalsum) 'return value
End Function
Smoothstep
Public Function smoothstep(ByVal a As Single, ByVal b As Single, ByVal x As Single) As Single
If (x < a) Then smoothstep = 0: Exit Function
If (x >= b) Then smoothstep = 1: Exit Function
x = (x - a) / (b - a)
smoothstep = (x * x * (3 - 2 * x))
End Function
A Simple lattice noise function (requires smoothstep from above)
For best results, sum several layers of the noise function at different scales and offsets.
Public Static Function Noise(ByVal x As Single, ByVal y As Single) As Single
Const LatticeSize As Long = 64
Dim Lattice() As Single
Dim Initialized As Boolean
Dim lx As Long, ly As Long
Dim difx As Single, dify As Single
Dim x1 As Long, y1 As Long, x2 As Long, y2 As Long
Dim x3 As Long, y3 As Long, x4 As Long, y4 As Long
Dim v1 As Single, v2 As Single, v3 As Single, v4 As Single
'initialize if this is the first call
If Initialized <> True Then
ReDim Lattice(LatticeSize - 1, LatticeSize - 1)
For ly = 0 To LatticeSize - 1
For lx = 0 To LatticeSize - 1
Lattice(lx, ly) = Rnd
Next
Next
Initialized = True
End If
x = Abs(x) : y = Abs(y)
difx = x - Int(x)
dify = y - Int(y)
'smoothstep the differences
difx = smoothstep(0, 1, difx)
dify = smoothstep(0, 1, dify)
x1 = Int(x) : y1 = Int(y)
x2 = x1 + 1: y2 = y1
x3 = x1 : y3 = y1 + 1
x4 = x1 + 1 : y4 = y1 + 1
x1 = x1 Mod LatticeSize : y1 = y1 Mod LatticeSize
x2 = x2 Mod LatticeSize : y2 = y2 Mod LatticeSize
x3 = x3 Mod LatticeSize : y3 = y3 Mod LatticeSize
x4 = x4 Mod LatticeSize : y4 = y4 Mod LatticeSize
v1 = Lattice(x1, y1) : v2 = Lattice(x2, y2)
v3 = Lattice(x3, y3) : v4 = Lattice(x4, y4)
Noise = (((v1 * (1 - difx)) + (v2 * difx)) * (1 - dify)) _
+ (((v3 * (1 - difx)) + (v4 * difx)) * dify)
End Function