-
Notifications
You must be signed in to change notification settings - Fork 0
(Predator Vision, Blood effect, Fire effect)
Yoann Berenguer edited this page Apr 17, 2022
·
1 revision
cpdef inline predator_vision(
object surface_,
unsigned int sobel_threshold=12,
unsigned int bpf_threshold=50,
unsigned int bloom_threshold=50,
bint inv_colormap=False,
bint fast=False,
int blend=pygame.BLEND_RGB_ADD
)
"""
CONVERT A SURFACE OR DISPLAY TO AN EQUIVALENT PREDATOR MODE
:param surface_ : pygame.Surface; compatible 24 - 32 bit
:param sobel_threshold : integer; value for sobel edge detection, default is 12
:param bpf_threshold : integer; value for the bright pass filter pixel detection,
default is 50
:param bloom_threshold : integer; Value for the bloom effect intensity default is 50
:param inv_colormap : boolean True | False inverse the colormap aspect, default is False
:param fast : boolean True | False for a fast process, default is False
:param blend : boolean True | False; final blending mode (New in version 1.0.4)
:return : Return a pygame surface
"""
e.g:
predator_vision(IMAGE,
sobel_threshold=1,
bpf_threshold=1,
bloom_threshold=20,
inv_colormap=True,
blend=pygame.BLEND_RGBA_ADD)
predator_vision(IMAGE,
sobel_threshold=1,
bpf_threshold=1,
bloom_threshold=20,
inv_colormap=True,
blend=pygame.BLEND_RGBA_MIN)
blood(object surface_, float [:, :] mask_, float perc_)
"""
SHADER 2D GAME "HURT EFFECT"
This effect is used in 2D game when the player is being hurt
THE MASK DETERMINE THE CONTOUR USED FOR THE BLOOD EFFECT.
:param surface_ : pygame.Surface; compatible surface 24 - 32 bit
:param mask_ : numpy.ndarray shape (w, h) of float values in range [0.0...1.0]
:param perc_ : Percentage value in range [0.0 ... 1.0] with 1.0 being 100%
:return : void
"""
blood_surface = pygame.image.load("../Assets/redvignette.png").convert_alpha()
blood_surface = pygame.transform.smoothscale(blood_surface, (WIDTH, HEIGHT))
BLOOD_MASK = numpy.asarray(pygame.surfarray.pixels_alpha(blood_surface) / 255.0, numpy.float32)
PERCENTAGE = 0.2
blood(image, BLOOD_MASK, PERCENTAGE)
PERCENTAGE = 0.8
blood(image, BLOOD_MASK, PERCENTAGE)
fire_effect(
int width_,
int height_,
float factor_,
unsigned int [::1] palette_,
float [:, ::1] fire_,
# OPTIONAL
unsigned short int reduce_factor_ = 3,
unsigned short int fire_intensity_= 32,
bint smooth_ = True,
bint bloom_ = True,
bint fast_bloom_ = True,
unsigned char bpf_threshold_ = 0,
unsigned int low_ = 0,
unsigned int high_ = 600,
bint brightness_ = True,
float brightness_intensity_ = 0.15,
object surface_ = None,
bint adjust_palette_ = False,
tuple hsl_ = (10, 80, 1.8),
bint transpose_ = False,
bint border_ = False,
bint blur_ = True
)
"""
FIRE SHADER EFFECT
* FIRE TEXTURE SIZES
input width_ : integer,
input height_ : integer
width_ and height_ values define the size of the texture e.g Surface(width x height)
* FIRE ASPECT (CONTROL OVER THE WIDTH):
inputs low_ : integer
input high_ : integer
Optional arguments low_ & high_ (integer values) define the width 's limits of the fire effect.
low_ for the starting point and high_ for the ending of the effect.
e.g low_ = 10 and high_ = 200. The fire effect will be contain within width = 10 and 200
low_ & high_ values must be in range [0 ... width_]
* FIRE HEIGHT:
input factor_ : float
The fire maximum height can be adjust with the variable factor_ (float value)
value > 3.95 will contain the effect within the display
value < 3.95 will enlarge the effect over the display height
Recommended value is 3.95 with reduce_factor_ = 3 otherwise adjust the value manually
to contain the fire effect within the display
* SPEED CONSIDERATION
input reduce_factor_ : integer
The argument reduce_factor_ control the size of the texture to be processed
e.g : a value of 2, divide by 4 the pygame surface define by the values (width_ & height_)
Smaller texture improve the overall performances but will slightly degrade the fire aspect,
especially if the blur and smooth option are not enabled.
Recommended value for reduce_factor_ is 3 (fast process)
reduce_factor_ values must be an integer in range [ 0 ... 4]
The reduce_factor_ value will have a significant impact on the fire effect maximum height,
adjust the argument factor_ accordingly
* FIRE INTENSITY AT THE SOURCE
input fire_intensity_: integer
Set the fire intensity with the variable fire_intensity_, 0 low flame,
32 maximum flame effect
Values must be an int in range [0 ... 32]
* SMOOTHING THE EFFECT
input smooth_: True | False
When smooth_ is True the algorithm will use the pygame function smoothscale (bi-linear
filtering) or False the final texture will be adjust with the scale function.
Set this variable to False if you need the best performance for the effect or if you require
a pixelated fire effect. Otherwise set the variable to True for a more realistic effect.
* BLOOM EFFECT
input bloom_ : True | False
input fast_bloom_ : True | False
input bpf_threshold_ : integer
Fire effect produce a bright and smooth light effect to the background texture where the fire
intensity is at its maximum.
Use the flag fast_bloom_ for a compromise between a realistic effect and the best performances
The flag fast_bloom_ define a very fast bloom algo using only the smallest texture
to create a bloom effect (all the intermediate textures will be bypassed). See the bloom effect
project for more details.
When fast_bloom is False, all the sub-surfaces will be blit to the final effect and will
produce a more realistic fire effect (this will slightly degrade the overall performances).
If the fire effect is too bright, you can always adjust the bright pass filter value
bpf_threshold_(this will adjust the bloom intensity)
bpf_threshold_ value must be in range [ 0 ... 255]
Below 128 the bloom effect will be more noticeable and above 128 only the brightest
area will be enhanced.
* LIGHT EFFECT INTENSITY
input brightness_ : True | False
input brightness_intensity_ : float
When the flag is set to True, the algorithm will use an external function,
<shader_brightness24_exclude_inplace_c> to increase the brightness of the effect / texture
A custom color can be passed to the function defining the pixels to be ignored during the
process (default is black color).
the value must be in range [-1.0 ... 1.0]. Values below zero will decrease the brightness
of the flame effect and positive values will increase the brightness of the effect (causing
bright white patches on the fire texture).
Values below -0.4 will cause the fire effect to be translucent and this effect can also be
used for simulating ascending heat convection effects on a background texture.
* OPTIONAL SURFACE
input surface_ : pygame.Surface
This is an optional surface that can be passed to the shader to improve the performances
and to avoid a new surface to be generated every iterations. The surface size must match
exactly the reduce texture dimensions otherwise an exception will be raise.
see reduce_factor_ option to determine the fire texture size that will be processed.
* COLOR PALETTE ADJUSTMENT
input adjust_palette_ : True | False
input hsl_ : (10, 80, 1.8)
Set this flag to True to modify the color palette of the fire texture.
This allow the HSL color model to be apply to the palette values
You can redefine the palette when the flag is True and by customizing a tuple of 3 float
values, default is (10, 80, 1.8).
The first value control the palette hue value, the second is for the saturation and last,
the palette color lightness.
With the variable hsl_ you can rotate the palette colors and define a new flame
aspect/color/intensity
If adjust_palette_ is True the original palette define by the argument palette_, will
be disregarded.Instead a new palette will be created with the hsl values
* FLAME ORIENTATION / DIRECTION & BORDER FLAME EFFECT
input transpose_ = True | False,
input border_ = True | False,
transpose_ = True, this will transpose the final array
for e.g :
If the final fire texture is (w, h) after setting the transpose flag, the final
fire texture will become (h, w). As a result the fire effect will be transversal (starting
from the right of the display to the left side).
You can always transpose / flip the texture to get the right flame orientation
BORDER FLAME EFFECT
border_ = True to create a flame effect burning the edge of the display. This version is only
compatible with symmetrical display or textures (same width & height). If the display
is asymmetric, the final border fire effect will be shown within the display and not neccessary
on the frame border
* FINAL TOUCH
input blur_ : True | False
This will will blur the fire effect for a more realistic appearance, remove all the jagged
edge when and pixelated effect
:param width_ : integer; Size (width) of the surface or display in pixels
:param height_ : integer; size (height) of the surface or display in pixels
:param factor_ : float; Value controlling the fire height value
must be in range [3.95 ... 4.2].
The value 3.95 gives the highest flame effect
:param palette_ : numpy.ndarray, buffer containing mapped RGB colors (uint values)
:param fire_ : numpy.ndarray shape (w, h) containing float values (fire intensity).
For better performance it is advised to set the array to the size
of the texture after applying the reduction_factor_.
For example if the reduction_factor_ is 2, the texture would have
width >> 1 and height >> 1 and the fire_array should be set to
numpy.empty((height >> 1, width >> 1), float32)
:param reduce_factor_ : unsigned short int ; Can be either 0, 1, 2, 3, 4.
2 and 3 provide the best performance and the best looking effect.
:param fire_intensity_ : Integer; Control the original amount of energy at the
bottom of the fire, must be in range of [0 ... 32].
32 being the maximum value and the maximum fire intensity
:param smooth_ : boolean; True smoothscale (bi-linear filtering) or
scale algorithm jagged edges (mush faster)
:param bloom_ : boolean; True or False, True apply a bloom effect to the fire effect
:param fast_bloom_ : boolean; Fastest bloom. This reduce the amount of calculation
:param bpf_threshold_ : integer; control the bright pass filter threshold
value, must be in range [0 ... 255].
Maximum brightness amplification with threshold = 0,
when bpf_threshold_ = 255, no change.
:param low_ : integer; Starting position x for the fire effect
:param high_ : integer; Ending position x for the fire effect
:param brightness_ : boolean; True apply a bright filter shader to the array.
Increase overall brightness of the effect
:param brightness_intensity_: float; must be in range [-1.0 ... 1.0] control
the brightness intensity
of the effect
:param surface_ : pygame.Surface. Pass a surface to the shader for
better performance, otherwise a new surface will be created each
calls.
:param adjust_palette_ : boolean; True adjust the palette setting HSL
(hue, saturation, luminescence).
Be aware that if adjust_palette is True, the optional palette
passed to the Shader will be disregarded
:param hsl_ : tuple; float values of hue, saturation and luminescence.
Hue in range [0.0 ... 100], saturation [0...100],
luminescence [0.0 ... 2.0]
:param transpose_ : boolean; Transpose the array (w, h) become (h, w).
The fire effect will start from the left and move to the right
:param border_ : boolean; Flame effect affect the border of the texture
:param blur_ : boolean; Blur the fire effect
:return : Return a pygame surface that can be blit directly to the game display
"""
e.g:
WIDTH = 1024
HEIGHT = 768
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT), vsync=True)
SCREEN.convert(32, RLEACCEL)
SCREEN.set_alpha(None)
BACKGROUND = pygame.image.load("../Assets/background.jpg")
BACKGROUND = pygame.transform.smoothscale(BACKGROUND, (WIDTH, HEIGHT))
image = BACKGROUND.copy()
pygame.display.set_caption("Test fire_effect")
FRAME = 0
CLOCK = pygame.time.Clock()
GAME = True
arr = numpy.array([0, 1, # violet
0, 1, # blue
0, 1, # green
2, 619, # yellow
620, 650, # orange
651, 660], # red
numpy.int)
HEATMAP = [custom_map(i - 20, arr, 1.0) for i in range(380, 800)]
heatmap_array = numpy.zeros((800 - 380, 3), uint8)
heatmap_rescale = numpy.zeros(255, numpy.uint)
i = 0
for t in HEATMAP:
heatmap_array[i, 0] = t[0]
heatmap_array[i, 1] = t[1]
heatmap_array[i, 2] = t[2]
i += 1
for r in range(0, 255):
s = int(r * (800.0 - 380.0) / 255)
heatmap_rescale[r] = rgb_to_int(heatmap_array[s][0], heatmap_array[s][1],
heatmap_array[s][2])
heatmap_rescale = numpy.ascontiguousarray(heatmap_rescale[::-1])
FIRE_ARRAY = numpy.zeros((HEIGHT, WIDTH), dtype=numpy.float32)
t = time.time()
while GAME:
pygame.event.pump()
for event in pygame.event.get():
keys = pygame.key.get_pressed()
if keys[pygame.K_ESCAPE]:
GAME = False
break
SCREEN.blit(BACKGROUND, (0, 0))
surface_ = fire_effect(
WIDTH, HEIGHT, 3.97 + uniform(0.002, 0.008),
heatmap_rescale,
FIRE_ARRAY, reduce_factor_=3, bloom_=True, fast_bloom_=False, bpf_threshold_=48,
brightness_=True, brightness_intensity_=0.095, transpose_=False, border_=False,
low_=0, high_=WIDTH, blur_=True).convert(
32, RLEACCEL)
SCREEN.blit(surface_, (0, 0), special_flags=BLEND_RGB_ADD)
pygame.display.flip()
CLOCK.tick()
FRAME += 1
pygame.display.set_caption(
"Test fire_effect %s fps "
"(%sx%s)" % (round(CLOCK.get_fps(), 2), WIDTH, HEIGHT))
image = BACKGROUND.copy()
if time.time() - t > 5:
break
demo