[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Bump mapping
On Wed, 30 Jun 2004, Sami Hangaslammi wrote:
> I was bored, so here. ;)
>
> def shadeMapSurfArray( surface, shadeSurf, elevation=55.0, compensate=False ):
> array = pygame.surfarray.array3d(surface)
> shade = pygame.surfarray.array3d(shadeSurf).astype(N.Float64)
> if compensate:
> compensation = sin(elevation)
> shade /= compensation
> shade /= 255.0
>
> # repeat the shade pattern as many times as needed
> # to cover the whole surface
> x,y = surface.get_size()
> xx,yy = shadeSurf.get_size()
> mx,my = (x+xx)//xx, (y+yy)//yy
> shade = N.concatenate((shade,)*mx,0)
> shade = N.concatenate((shade,)*my,1)
> shade = shade[:x,:y,...]
>
> array = array * shade
> array = N.where(array > 255, 255, array).astype(N.Int0)
> return pygame.surfarray.make_surface(array)
>
> Probably someone more familiar with the surfarray can make it faster,
> but should beat get_at/set_at at least.
Cool, thanks! This helped quite a bit, as I was fumbling around trying to
find a way to multiply 2 arrays of different sizes, and also didn't know
about N.where().
For 380x360 I got .35 seconds for a ~3.7x speed improvement.
For 1220x840 I got 1.30 seconds for a ~7.5x speed improvement.
For the next size up (~2000x2000) it appears to suck up memory/cpu and hang!
Not sure what's going on here. :-/
Some comments:
-You left out the radian conversion for elevation.
-This requires changing the rest of the code to store shades as
(shade,shade,shade) instead of (shade,0,0)
-I upped the speed a bit by doing the N.where() conditionally
-How is "//" different than "/" ?
-Jasper
PS Here's my tweaked version:
def shadeMap( surface, shadeSurf, compensate=False, elevation=55.0 ):
'''Bump map from a pre calculated shade map'''
array = pygame.surfarray.array3d( surface )
shade = pygame.surfarray.array3d( shadeSurf ).astype( N.Float64 )
if compensate:
elevation = radians( elevation )
compensation = sin( elevation )
shade /= compensation
shade /= 255.0
shade = expandShadeMap( shade, shadeSurf.get_size(), surface.get_size() )
array = array * shade
if compensate:
array = N.where( array > 255, 255, array )
array = array.astype( N.Int8 )
return pygame.surfarray.make_surface( array )
def expandShadeMap( shade, (wOrig,hOrig), (wEnd,hEnd) ):
'''Tile the shade surfarray up to newSize'''
xTiles = (wEnd+wOrig)/wOrig
yTiles = (hEnd+hOrig)/hOrig
shade = N.concatenate((shade,)*xTiles,0)
shade = N.concatenate((shade,)*yTiles,1)
return shade[:wEnd,:hEnd,...]