# Copyright (c) Jose Luis Vergara 2010 # CC-by licensed: http://creativecommons.org/licenses/by/3.0/ # # This is actually a python script, change the file extension! # # You need a 200x200 8-bit greyscale bitmap called "relieve.bmp" # in this script's folder for it to work! # # You need PyGame, Numpy and Python 2.X to run this!. # Most parameters can be analogued to the Phong Illumination Model # described in the references. # If you want to play with the illumination source, change the coordinates # of light_unit_vector. (0, 0, 1) is light coming straight from above. # import os, sys, time, math import pygame from pygame.locals import * from numpy import * pygame.init() height_map = pygame.image.load("relieve.bmp") height_array = pygame.PixelArray(height_map) vector_x = 0 vector_y = 0 time1 = time.clock() normals_array = zeros([198, 198, 3]) reflections_array = zeros([198, 198, 3]) bumpmapped_bitmap = zeros([198, 198], uint8) light_unit_vector = array([3, 3, 3]) light_unit_vector = light_unit_vector / linalg.norm(light_unit_vector) vision_unit_vector = array([0, 0, 1]) Il = 0xFF Ka = 0.0 Kd = 0.5 Ks = 0.3 shiny_exp = 80 for x in xrange(1, (198+1)): for y in xrange(1, (198+1)): vector_x = [1, 0, height_array[x+1][y] - height_array[x-1][y]] vector_y = [0, 1, height_array[x][y+1] - height_array[x][y-1]] vector_normal = cross(vector_x, vector_y) vector_normal = vector_normal / linalg.norm(vector_normal) normals_array[x-1][y-1] = vector_normal reflections_array[x-1][y-1] = (2 * pow(dot(vector_normal, light_unit_vector), shiny_exp)) * vector_normal - light_unit_vector I = Ia = Id = Is = 0 for x in xrange(198): for y in xrange(198): Ia = Ka * Il Id = Kd * Il * dot(normals_array[x][y], light_unit_vector) if (Id < 0): Id = 0 #print("Id negativo") Is = Ks * Il * dot(vision_unit_vector, reflections_array[x][y]) if (Is < 0): Is = 0 #print("Is negativo") I = Ia + Id + Is if (I > 0xFF): I = 0xFF print("OVERLOAD") if (I < 0): I = 0 print("NEGATIVE OVERLOAD") bumpmapped_bitmap[x][y] = I print bumpmapped_bitmap bumpmap = pygame.Surface((198, 198), flags=0, depth=8) for x in range(256): bumpmap.set_palette_at(x, [x, x, x, 255]) pygame.surfarray.blit_array(bumpmap, bumpmapped_bitmap) ventanita = pygame.display.set_mode((200,200), pygame.RESIZABLE, 8) for x in range(256): ventanita.set_palette_at(x, [x, x, x, 255]) ventanita.blit(bumpmap, [0, 0]) pygame.display.flip() print("time taken was " ) print(time.clock() - time1) def main(): clock = pygame.time.Clock() while 1: clock.tick(6) for event in pygame.event.get(): if event.type == QUIT: return elif event.type == KEYDOWN and event.key == K_ESCAPE: return if __name__ == '__main__': main()