def __init__(self, render_size): global glLibInternal_ray_shader, glLibInternal_draw_volume_shader self.render_size = list(render_size) self.ray_fbo = glLibFBO(self.render_size) self.ray_fbo.add_render_target(1, GLLIB_RGBA) self.ray_fbo.add_render_target(2, GLLIB_RGBA) try: glLibInternal_ray_shader glLibInternal_draw_volume_shader except: glLibInternal_ray_shader = glLibShader() glLibInternal_ray_shader.use_prebuilt(GLLIB_INTERNAL_VOLUME_RAY) glLibInternal_draw_volume_shader = glLibShader() glLibInternal_draw_volume_shader.use_prebuilt( GLLIB_INTERNAL_VOLUME_DRAW) self.box = glLibRectangularSolid([0.5, 0.5, 0.5], texture=GLLIB_TEXTURE_3D, normals=GLLIB_FACE_NORMALS)
def __init__(self, size, pos_data, rip_texture=None, stretched=1.0): #TODO: Make kernel size work! #Angle limiting forces #Size if type(size) in [type([]), type(())]: self.size = list(size) else: self.size = [size, size] #Misc. self.view_2d = glLibView2D((0, 0, self.size[0], self.size[1])) #Physics self.forces = [0.0, 0.0, 0.0] #Cloth Parameters self.dampening = 0.98 self.tensor = 1.0 self.angle_tensor = 0.0 #1.0 self.max_jitter_length = 1.0 self.gravity = [0.0, 0.0, 0.0] self.kernel_size = 1 self.steps = 1 self.normal_flip = False self.loop = [False, False] self.time_step = 1.0 #Collision Objects self.num_obstacles = 0 self.collidable = {} self.is_garment = False #Geometry self.particles = glLibGrid2D(self.size) self.particles_mesh = glLibGrid2DMesh(self.size) #Textures self.pos_restrained_tex = glLibTexture2D( pos_data, (0, 0, self.size[0], self.size[1]), GL_RGBA, precision=32) ## self. self.original_pos_restrained_tex = self.pos_restrained_tex self.velocity_tex = glLibTexture2D(None, (0, 0, self.size[0], self.size[1]), GL_RGB, precision=32) self.vec_tex = None self.normal_tex = None self.dist_edges_tex = None self.dist_corners_tex = None self.diffuse_texture = None self.obstacles_tex = None self.obstacles_aux_param_tex = None self.texture_repeat = [1.0, 1.0] #FBOs self.update_framebuffer = glLibFBO(self.size) self.update_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.update_framebuffer.add_render_target(2, precision=32) self.update_framebuffer.add_render_target(3, precision=8) #for debugging self.collision_framebuffer = glLibFBO(self.size) self.collision_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.collision_framebuffer.add_render_target(2, precision=32) self.collision_framebuffer.add_render_target(3, precision=8) self.normal_framebuffer = glLibFBO(self.size) self.normal_framebuffer.add_render_target(1) self.dist_angle_framebuffer = glLibFBO(self.size) self.dist_angle_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.dist_angle_framebuffer.add_render_target(2, precision=32, type=GLLIB_RGBA) self.set_loop(*self.loop) #Shaders ## print "Compiling Update Shader" self.update_shader = glLibShader() self.update_shader.use_prebuilt(GLLIB_CLOTH_UPDATE) ## print "Compiling Collision Shader" self.collision_shader = glLibShader() self.collision_shader.use_prebuilt(GLLIB_CLOTH_COLLIDE) ## print "Compiling Normal Shader" self.normal_shader = glLibShader() self.normal_shader.use_prebuilt(GLLIB_CLOTH_NORMAL) ## print "Compiling Draw Shader" self.draw_shader = glLibShader() self.draw_shader.use_prebuilt(GLLIB_CLOTH_DRAW) ## print "Compiling Distance Shader" self.dist_shader = glLibShader() self.dist_shader.use_prebuilt(GLLIB_CLOTH_DISTANCE) ## self.update_shader.save_vertex() #Get Target Distances self.glLibInternal_push() self.dist_angle_framebuffer.enable([1, 2]) self.glLibInternal_use_dist_shader() self.dist_shader.pass_float("stretched", stretched) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() self.view_2d.set_view() self.particles.draw() glLibUseShader(None) self.dist_angle_framebuffer.disable() self.glLibInternal_pop() self.dist_edges_tex = self.dist_angle_framebuffer.get_texture(1) self.dist_corners_tex = self.dist_angle_framebuffer.get_texture(2) #Initialize Position self.glLibInternal_initialize_position()
def __init__(self, size, pos_data, rip_texture=None, stretched=1.0): # TODO: Make kernel size work! # Angle limiting forces # Size if type(size) in [type([]), type(())]: self.size = list(size) else: self.size = [size, size] # Misc. self.view_2d = glLibView2D((0, 0, self.size[0], self.size[1])) # Physics self.forces = [0.0, 0.0, 0.0] # Cloth Parameters self.scale = 1.0 self.trans = [0.0, 0.0, 0.0] self.dampening = 0.98 self.tensor = 1.0 self.angle_tensor = 0.0 # 1.0 self.max_jitter_length = 1.0 self.gravity = [0.0, 0.0, 0.0] self.kernel_size = 1 self.steps = 1 self.normal_flip = False self.loop = [False, False] self.time_step = 1.0 # Collision Objects self.num_obstacles = 0 self.collidable = {} self.is_garment = False # Geometry self.particles = glLibGrid2D(self.size) self.particles_mesh = glLibGrid2DMesh(self.size) # Textures self.pos_restrained_tex = glLibTexture2D(pos_data, (0, 0, self.size[0], self.size[1]), GL_RGBA, precision=32) ## self. self.original_pos_restrained_tex = self.pos_restrained_tex self.velocity_tex = glLibTexture2D(None, (0, 0, self.size[0], self.size[1]), GL_RGB, precision=32) self.vec_tex = None self.normal_tex = None self.dist_edges_tex = None self.dist_corners_tex = None self.diffuse_texture = None self.obstacles_tex = None self.obstacles_aux_param_tex = None self.texture_repeat = [1.0, 1.0] # FBOs self.update_framebuffer = glLibFBO(self.size) self.update_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.update_framebuffer.add_render_target(2, precision=32) self.update_framebuffer.add_render_target(3, precision=8) self.collision_framebuffer = glLibFBO(self.size) self.collision_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.collision_framebuffer.add_render_target(2, precision=32) self.collision_framebuffer.add_render_target(3, precision=8) self.normal_framebuffer = glLibFBO(self.size) self.normal_framebuffer.add_render_target(1) self.dist_angle_framebuffer = glLibFBO(self.size) self.dist_angle_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.dist_angle_framebuffer.add_render_target(2, precision=32, type=GLLIB_RGBA) self.set_loop(*self.loop) # Shaders ## print "Compiling Update Shader" self.update_shader = glLibShader() self.update_shader.use_prebuilt(GLLIB_CLOTH_UPDATE) ## print "Compiling Collision Shader" self.collision_shader = glLibShader() self.collision_shader.use_prebuilt(GLLIB_CLOTH_COLLIDE) ## print "Compiling Normal Shader" self.normal_shader = glLibShader() self.normal_shader.use_prebuilt(GLLIB_CLOTH_NORMAL) ## print "Compiling Draw Shader" self.draw_shader = glLibShader() self.draw_shader.use_prebuilt(GLLIB_CLOTH_DRAW) ## print "Compiling Distance Shader" self.dist_shader = glLibShader() self.dist_shader.use_prebuilt(GLLIB_CLOTH_DISTANCE) ## self.update_shader.save_vertex() # Get Target Distances self.glLibInternal_push() self.dist_angle_framebuffer.enable([1, 2]) self.glLibInternal_use_dist_shader() self.dist_shader.pass_float("stretched", stretched) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() self.view_2d.set_view() self.particles.draw() glLibUseShader(None) self.dist_angle_framebuffer.disable() self.glLibInternal_pop() self.dist_edges_tex = self.dist_angle_framebuffer.get_texture(1) self.dist_corners_tex = self.dist_angle_framebuffer.get_texture(2) # Initialize Position self.glLibInternal_initialize_position()
def __init__(self, res): #heavily based on http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html self.res = list(res) self.dimensions = len(self.res) self.grid_delta = vec_div([1.0] * self.dimensions, self.res) self.diff = 0.0 self.visc = 0.0 self.new_forces = [] self.new_densities = [] self.view2D = glLibView2D((0, 0, self.res[0], self.res[1])) self.precis = 32 self.texture_captions = {} self.font = pygame.font.SysFont("Times New Roman", 10) if self.dimensions == 3: glEnable(GL_TEXTURE_3D) self.gas_fbo1 = glLibFBO(self.res) self.gas_fbo2 = glLibFBO(self.res) self.prs_fbo1 = glLibFBO(self.res) self.prs_fbo2 = glLibFBO(self.res) self.vel_fbo1 = glLibFBO(self.res) self.vel_fbo2 = glLibFBO(self.res) self.div_fbo1 = glLibFBO(self.res) self.div_fbo2 = glLibFBO(self.res) for fbo in [ self.gas_fbo1, self.gas_fbo2, self.prs_fbo1, self.prs_fbo2, self.vel_fbo1, self.vel_fbo2, self.div_fbo1, self.div_fbo2 ]: fbo.add_render_target(1, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) fbo.textures[1].edge(GLLIB_CLAMP) self.gas_ping_pong = 1 self.prs_ping_pong = 1 self.vel_ping_pong = 1 self.div_ping_pong = 1 self.zero_value = np.empty(tuple(self.res) + (3, )) self.zero_value.fill(0.5) self.reset() if self.dimensions == 3: glDisable(GL_TEXTURE_3D) self.advection_shader = glLibShader() if self.dimensions == 2: self.advection_shader.user_variables(""" uniform float dt; const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.advection_shader.render_equation(""" //follow the velocity field "back in time" vec2 pos = uv - dt*griddelta*(texture2D(tex2D_1,uv).rg-vec2(0.5)); //sample the data texture there, and write to the current fragment color = texture2D(tex2D_2,pos);""") elif self.dimensions == 3: self.advection_shader.user_variables(""" uniform float dt; const vec3 gridsize = vec3(""" + str(self.res[0]) + "," + str(self.res[1]) + "," + str(self.res[2]) + """); const vec3 griddelta = 1.0/gridsize;""") self.advection_shader.render_equation(""" //follow the velocity field "back in time" vec3 pos = uvw - dt*griddelta*(texture3D(tex3D_1,uvw).rgb-vec3(0.5)); //sample the data texture there, and write to the current fragment color = texture3D(tex3D_2,pos);""") self.advection_shader.max_textures_3D(2) print("Advection Shader:") errors = self.advection_shader.compile() if errors != "": print(errors) self.vec_zero_shader = glLibShader() self.vec_zero_shader.render_equation(""" color.rgb = vec3(0.5);""") print("Vector Zero Shader:") errors = self.vec_zero_shader.compile() if errors != "": print(errors) self.add_shader = glLibShader() self.add_shader.user_variables("uniform vec3 quantity;") if self.dimensions == 2: self.add_shader.render_equation(""" //tex2D_1 contains the obstacles. tex2D_2 contains the data field. color.rgb = texture2D(tex2D_2,uv).rgb; if (texture2D(tex2D_1,uv).r==0.0) { color.rgb += quantity; }""") elif self.dimensions == 3: self.add_shader.render_equation(""" //tex3D_1 contains the obstacles. tex3D_2 contains the data field. color.rgb = texture3D(tex3D_2,uvw).rgb; if (texture3D(tex3D_1,uvw).r==0.0) { color.rgb += quantity; }""") self.add_shader.max_textures_3D(2) print("Add Shader:") errors = self.add_shader.compile() if errors != "": print(errors) self.diffuse_shader = glLibShader() self.diffuse_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.diffuse_shader.render_equation(""" //tex2D_1 contains the obstacles texture. tex2D_2 contains the data texture vec3 q01 = texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).rgb; vec3 q21 = texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).rgb; vec3 q10 = texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).rgb; vec3 q12 = texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).rgb; vec3 q11 = texture2D(tex2D_2,uv ).rgb; color.rgb = q11; float total = 1.0; if (texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).r==0.0) { color.rgb += q01; total += 1.0; } if (texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).r==0.0) { color.rgb += q21; total += 1.0; } if (texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).r==0.0) { color.rgb += q10; total += 1.0; } if (texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).r==0.0) { color.rgb += q12; total += 1.0; } color.rgb /= total; //color.rgb = vec3(0.5) + -4.0*(q11-vec3(0.5)) + q01+q21 + q10+q12 - 4.0*vec3(0.5);""" ) print("Diffuse Shader:") errors = self.diffuse_shader.compile() if errors != "": print(errors) self.div_shader = glLibShader() if self.dimensions == 2: self.div_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.div_shader.render_equation(""" //tex2D_1 contains velocity. tex2D_2 contains the obstacles texture vec3 wL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).rgb; vec3 wR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).rgb; vec3 wB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).rgb; vec3 wT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).rgb; if (texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).r==1.0) { wL = vec3(0.5); } if (texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).r==1.0) { wR = vec3(0.5); } if (texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).r==1.0) { wB = vec3(0.5); } if (texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).r==1.0) { wT = vec3(0.5); } color.r = 0.5 + 0.5 * ((wR.x-wL.x)+(wT.y-wB.y));""") elif self.dimensions == 3: self.div_shader.user_variables(""" const vec3 gridsize = vec3(""" + str(self.res[0]) + "," + str(self.res[1]) + "," + str(self.res[2]) + """); const vec3 griddelta = 1.0/gridsize;""") self.div_shader.render_equation(""" //tex3D_1 contains velocity. tex3D_2 contains the obstacles texture vec3 wxL = texture3D(tex3D_1,uvw-vec3(griddelta.x,0.0,0.0)).rgb; vec3 wxR = texture3D(tex3D_1,uvw+vec3(griddelta.x,0.0,0.0)).rgb; vec3 wyB = texture3D(tex3D_1,uvw-vec3(0.0,griddelta.y,0.0)).rgb; vec3 wyT = texture3D(tex3D_1,uvw+vec3(0.0,griddelta.y,0.0)).rgb; vec3 wzB = texture3D(tex3D_1,uvw-vec3(0.0,0.0,griddelta.z)).rgb; vec3 wzF = texture3D(tex3D_1,uvw+vec3(0.0,0.0,griddelta.z)).rgb; if (texture3D(tex3D_2,uvw-vec3(griddelta.x,0.0,0.0)).r==1.0) { wxL = vec3(0.5); } if (texture3D(tex3D_2,uvw+vec3(griddelta.x,0.0,0.0)).r==1.0) { wxR = vec3(0.5); } if (texture3D(tex3D_2,uvw-vec3(0.0,griddelta.y,0.0)).r==1.0) { wyB = vec3(0.5); } if (texture3D(tex3D_2,uvw+vec3(0.0,griddelta.y,0.0)).r==1.0) { wyT = vec3(0.5); } if (texture3D(tex3D_2,uvw-vec3(0.0,0.0,griddelta.z)).r==1.0) { wzB = vec3(0.5); } if (texture3D(tex3D_2,uvw+vec3(0.0,0.0,griddelta.z)).r==1.0) { wzF = vec3(0.5); } color.r = 0.5 + 0.5 * ((wxR.x-wxL.x)+(wyT.y-wyB.y)+(wzF.z-wzB.z));""" ) self.div_shader.max_textures_3D(2) print("Divergence Shader:") errors = self.div_shader.compile() if errors != "": print(errors) self.prs_jacobi_shader = glLibShader() if self.dimensions == 2: self.prs_jacobi_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize; const float alpha = 1.0;//-pow(griddelta.x,2.0); const float beta = 4.0;""") self.prs_jacobi_shader.render_equation(""" //tex2D_1 contains x, the pressure. tex2D_2 contains b, the divergence. tex2D_3 contains the obstacles. float xC = texture2D(tex2D_1,uv ).r - 0.5; float xL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).r - 0.5; float xR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).r - 0.5; float xB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).r - 0.5; float xT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).r - 0.5; float bC = texture2D(tex2D_2,uv ).r - 0.5; if (texture2D(tex2D_3,uv-vec2(griddelta.x,0.0)).r==1.0) { xL = xC; } if (texture2D(tex2D_3,uv+vec2(griddelta.x,0.0)).r==1.0) { xR = xC; } if (texture2D(tex2D_3,uv-vec2(0.0,griddelta.y)).r==1.0) { xB = xC; } if (texture2D(tex2D_3,uv+vec2(0.0,griddelta.y)).r==1.0) { xT = xC; } //color.r = 0.5 + ((xL+xR+xB+xT+(alpha*bC))/beta); color.r = 0.5 + ((xL+xR+xB+xT-bC)/4.0);""") elif self.dimensions == 3: self.prs_jacobi_shader.user_variables(""" const vec3 gridsize = vec3(""" + str(self.res[0]) + "," + str(self.res[1]) + "," + str(self.res[2]) + """); const vec3 griddelta = 1.0/gridsize; const float alpha = 1.0; const float beta = 6.0;""") self.prs_jacobi_shader.render_equation(""" //tex3D_1 contains x, the pressure. tex3D_2 contains b, the divergence. tex3D_3 contains the obstacles. float xC = texture3D(tex3D_1,uvw ).r - 0.5; float xxL = texture3D(tex3D_1,uvw-vec3(griddelta.x,0.0,0.0)).r - 0.5; float xxR = texture3D(tex3D_1,uvw+vec3(griddelta.x,0.0,0.0)).r - 0.5; float xyB = texture3D(tex3D_1,uvw-vec3(0.0,griddelta.y,0.0)).r - 0.5; float xyT = texture3D(tex3D_1,uvw+vec3(0.0,griddelta.y,0.0)).r - 0.5; float xzB = texture3D(tex3D_1,uvw-vec3(0.0,0.0,griddelta.y)).r - 0.5; float xzF = texture3D(tex3D_1,uvw+vec3(0.0,0.0,griddelta.y)).r - 0.5; float bC = texture3D(tex3D_2,uvw ).r - 0.5; if (texture3D(tex3D_3,uvw-vec3(griddelta.x,0.0,0.0)).r==1.0) { xxL = xC; } if (texture3D(tex3D_3,uvw+vec3(griddelta.x,0.0,0.0)).r==1.0) { xxR = xC; } if (texture3D(tex3D_3,uvw-vec3(0.0,griddelta.y,0.0)).r==1.0) { xyB = xC; } if (texture3D(tex3D_3,uvw+vec3(0.0,griddelta.y,0.0)).r==1.0) { xyT = xC; } if (texture3D(tex3D_3,uvw-vec3(0.0,0.0,griddelta.z)).r==1.0) { xzB = xC; } if (texture3D(tex3D_3,uvw+vec3(0.0,0.0,griddelta.z)).r==1.0) { xzF = xC; } color.r = 0.5 + ((xxL+xxR+xyB+xyT+xzB+xzF-bC)/6.0);""") self.prs_jacobi_shader.max_textures_3D(3) print("Pressure Jacobi Shader:") errors = self.prs_jacobi_shader.compile() if errors != "": print(errors) self.velprs_proj_shader = glLibShader() if self.dimensions == 2: self.velprs_proj_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.velprs_proj_shader.render_equation(""" //tex2D_1 contains the velocities. tex2D_2 contains the pressure. tex2D_3 contains the obstacles. float pC = texture2D(tex2D_2,uv ).r; float pL = texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).r; float pR = texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).r; float pB = texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).r; float pT = texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).r; if (texture2D(tex2D_3,uv-vec2(griddelta.x,0.0)).r==1.0) { pL = pC; } if (texture2D(tex2D_3,uv+vec2(griddelta.x,0.0)).r==1.0) { pR = pC; } if (texture2D(tex2D_3,uv-vec2(0.0,griddelta.y)).r==1.0) { pB = pC; } if (texture2D(tex2D_3,uv+vec2(0.0,griddelta.y)).r==1.0) { pT = pC; } color.xyz = texture2D(tex2D_1,uv).xyz; //subtract the gradient of the pressure from the velocity color.xy -= 0.5*vec2(pR-pL,pT-pB);""") elif self.dimensions == 3: self.velprs_proj_shader.user_variables(""" const vec3 gridsize = vec3(""" + str(self.res[0]) + "," + str(self.res[1]) + "," + str(self.res[2]) + """); const vec3 griddelta = 1.0/gridsize;""") self.velprs_proj_shader.render_equation(""" //tex3D_1 contains the velocities. tex3D_2 contains the pressure. tex3D_3 contains the obstacles. float pC = texture3D(tex3D_2,uvw ).r; float pxL = texture3D(tex3D_2,uvw-vec3(griddelta.x,0.0,0.0)).r; float pxR = texture3D(tex3D_2,uvw+vec3(griddelta.x,0.0,0.0)).r; float pyB = texture3D(tex3D_2,uvw-vec3(0.0,griddelta.y,0.0)).r; float pyT = texture3D(tex3D_2,uvw+vec3(0.0,griddelta.y,0.0)).r; float pzB = texture3D(tex3D_2,uvw-vec3(0.0,0.0,griddelta.z)).r; float pzF = texture3D(tex3D_2,uvw+vec3(0.0,0.0,griddelta.z)).r; if (texture3D(tex3D_3,uvw-vec3(griddelta.x,0.0,0.0)).r==1.0) { pxL = pC; } if (texture3D(tex3D_3,uvw+vec3(griddelta.x,0.0,0.0)).r==1.0) { pxR = pC; } if (texture3D(tex3D_3,uvw-vec3(0.0,griddelta.y,0.0)).r==1.0) { pyB = pC; } if (texture3D(tex3D_3,uvw+vec3(0.0,griddelta.y,0.0)).r==1.0) { pyT = pC; } if (texture3D(tex3D_3,uvw-vec3(0.0,0.0,griddelta.z)).r==1.0) { pzB = pC; } if (texture3D(tex3D_3,uvw+vec3(0.0,0.0,griddelta.z)).r==1.0) { pzF = pC; } color.xyz = texture3D(tex3D_1,uvw).xyz; //subtract the gradient of the pressure from the velocity color.xyz -= 0.5*vec3(pxR-pxL,pyT-pyB,pzF-pzB);""") self.velprs_proj_shader.max_textures_3D(3) print("Velocity-Pressure Projection Shader:") errors = self.velprs_proj_shader.compile() if errors != "": print(errors) if self.dimensions == 3: ## self.draw_shader = glLibShader() ## self.draw_shader.user_variables("uniform float point_size;") ## self.draw_shader.post_vertex(""" ## gl_PointSize = point_size/length(gl_Position);""") ## self.draw_shader.render_equation(""" ## vec2 v_rot = normalize(vertex.zw); ## vec4 l_uv = vec4(0.0,0.0,gl_PointCoord.xy); ## l_uv.zw-=vec2(0.5,0.5);l_uv.x=l_uv.z*v_rot.x;l_uv.y=l_uv.w*v_rot.x;l_uv.x-=l_uv.w*v_rot.y;l_uv.y+=l_uv.z*v_rot.y; ## //color.rgb = texture3D(tex3D_1,uvw).rgb; ## color.rgb = vec3(1.0); ## //color *= texture2D(tex2D_2,l_uv.xy+vec2(0.5,0.5));""") ## self.draw_shader.max_textures_3D(1) ## print "Draw Shader:" ## errors = self.draw_shader.compile() ## if errors != "": print errors ## ## self.point_texture = glLibTexture2D("glLib/causticpoint.png",(0,0,83,83),GLLIB_RGBA) ## self.point_texture.edge(GLLIB_CLAMP) self.volume_obj = glLibVolume(self.res)
def __init__(self,pos_length_surf,grow_surf,length_scale,max_length,density): #Size self.size = list(pos_length_surf.get_size()) #Misc. self.view_2d = glLibView2D((0,0,self.size[0],self.size[1])) self.update_pingpong = 1 #Hair Parameters self.scale = 1.0 self.trans = [0.0,0.0,0.0] self.dampening = 0.98 self.tensor = 1.0 self.gravity = [0.0,0.0,0.0] self.steps = 1 self.density = density self.max_length = max_length self.length_scale = length_scale self.time_step = 1.0 #Physics self.forces = [0.0,0.0,0.0] #Geometry self.particles = glLibGrid2D(self.size) ## self.particles_mesh = glLibGrid2DMesh(self.size) self.particles_mesh = glLibDoubleGrid3DMesh([self.density*self.size[0],self.density*self.size[1],self.max_length]) ## self.particles_mesh = glLibDoubleGrid3DMesh([3,4,5]) self.draw_particles = glLibGrid2D(sc_vec(self.density,self.size)) #Textures self.position_length_textures = [glLibTexture2D(pos_length_surf,(0,0,self.size[0],self.size[1]),GL_RGBA,filtering=GLLIB_FILTER,precision=32)] self.grow_tex = glLibTexture2D(grow_surf,(0,0,self.size[0],self.size[1]),GL_RGB,precision=32) #FBOs self.update_framebuffers1 = [] self.update_framebuffers2 = [] self.grow_framebuffers = [] for hair_segment in xrange(self.max_length): update_framebuffer1 = glLibFBO(self.size) update_framebuffer1.add_render_target(1,precision=32,filter=GLLIB_FILTER,type=GLLIB_RGBA) update_framebuffer1.add_render_target(2,precision=32,filter=GLLIB_FILTER) self.update_framebuffers1.append(update_framebuffer1) update_framebuffer2 = glLibFBO(self.size) update_framebuffer2.add_render_target(1,precision=32,filter=GLLIB_FILTER,type=GLLIB_RGBA) update_framebuffer2.add_render_target(2,precision=32,filter=GLLIB_FILTER) self.update_framebuffers2.append(update_framebuffer2) grow_framebuffer = glLibFBO(self.size) grow_framebuffer.add_render_target(1,precision=32,type=GLLIB_RGBA) self.grow_framebuffers.append(grow_framebuffer) #Shaders self.grow_shader = glLibShader() self.grow_shader.use_prebuilt(GLLIB_HAIR_GROW) self.update_shader = glLibShader() self.update_shader.use_prebuilt(GLLIB_HAIR_UPDATE) self.draw_shader = glLibShader() self.draw_shader.use_prebuilt(GLLIB_HAIR_DRAW) #Grow Hair self.glLibInternal_grow() #Initialize Position self.glLibInternal_initialize_position()
def __init__(self, res): #heavily based on http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html self.res = list(res) self.diff = 0.0 self.visc = 0.0 self.new_forces = [] self.new_densities = [] self.view2D = glLibView2D((0, 0, self.res[0], self.res[1])) self.particles = glLibGrid3D([self.res[0], self.res[1], 4]) ## self.particles = glLibGrid3D([self.res[0]/4,self.res[1]/4,4]) ## print glLibGrid3D([2,2,4]).vertex_vbo.data self.precis = 32 self.texture_captions = {} self.font = pygame.font.SysFont("Times New Roman", 10) self.gas_fbo1 = glLibFBO((self.res[0], self.res[1])) self.gas_fbo2 = glLibFBO((self.res[0], self.res[1])) self.gas_fbo1.add_render_target(1, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) self.gas_fbo2.add_render_target(1, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) self.gas_fbo1.textures[1].edge(GLLIB_CLAMP) self.gas_fbo2.textures[1].edge(GLLIB_CLAMP) self.prs_fbo1 = glLibFBO((self.res[0], self.res[1])) self.prs_fbo2 = glLibFBO((self.res[0], self.res[1])) self.prs_fbo1.add_render_target(1, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) self.prs_fbo2.add_render_target(1, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) self.prs_fbo1.textures[1].edge(GLLIB_CLAMP) self.prs_fbo2.textures[1].edge(GLLIB_CLAMP) self.vel_fbo1 = glLibFBO((self.res[0], self.res[1])) self.vel_fbo2 = glLibFBO((self.res[0], self.res[1])) self.vel_fbo1.add_render_target(1, GLLIB_RGB, precision=self.precis) self.vel_fbo2.add_render_target(1, GLLIB_RGB, precision=self.precis) self.vel_fbo1.textures[1].edge(GLLIB_CLAMP) self.vel_fbo2.textures[1].edge(GLLIB_CLAMP) self.div_fbo1 = glLibFBO((self.res[0], self.res[1])) self.div_fbo2 = glLibFBO((self.res[0], self.res[1])) self.div_fbo1.add_render_target(1, GLLIB_RGB, precision=self.precis) self.div_fbo2.add_render_target(1, GLLIB_RGB, precision=self.precis) self.div_fbo1.textures[1].edge(GLLIB_CLAMP) self.div_fbo2.textures[1].edge(GLLIB_CLAMP) self.gas_ping_pong = 1 self.prs_ping_pong = 1 self.vel_ping_pong = 1 self.div_ping_pong = 1 zero_value = np.empty((self.res[0], self.res[1], 3)) zero_value.fill(0.5) self.vel_tex = glLibTexture2D(zero_value, GLLIB_ALL, GLLIB_RGB, precision=self.precis) self.gas_tex = glLibTexture2D(pygame.Surface(self.res), GLLIB_ALL, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) self.prs_tex = glLibTexture2D(zero_value, GLLIB_ALL, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) self.advection_shader = glLibShader() self.advection_shader.user_variables(""" //tex2D_1 contains the velocities; tex2D_2 contains the quantity to be advected uniform float dt; uniform float pos_neg; varying vec3 sc; const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.advection_shader.vertex_extension_functions(""" vec2 refl(float component, float low, float high) { if (component>high) { return vec2(2.0*high-component,-1.0); } if (component<low) { return vec2(2.0*low-component,-1.0); } return vec2(component,1.0); }""") self.advection_shader.vertex_transform(""" vertex.xy *= vec2(1.0) - griddelta; vertex.xy += 0.5 * griddelta; gl_TexCoord[0].st = vertex.xy; vertex.xy *= vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); vec2 delta = dt * vec3(texture2D(tex2D_1,gl_TexCoord[0].st).rgb-vec3(0.5)).rg; vec2 bottom = floor(delta); vec2 top = bottom + vec2(1.0); vec2 part = delta - bottom; sc = vec3(0.0); if (vertex.z==0.0) { sc=vec3((1.0-part.x)*(1.0-part.y)); vertex.x+=bottom.x; vertex.y+=bottom.y; } //vertex.z == 0.0 else if (vertex.z==1.0) { sc=vec3( part.x *(1.0-part.y)); vertex.x+= top.x; vertex.y+=bottom.y; } //vertex.z == 1.0 else if (vertex.z <0.5) { sc=vec3((1.0-part.x)* part.y ); vertex.x+=bottom.x; vertex.y+= top.y; } //vertex.z == 1/3 else if (vertex.z >0.5) { sc=vec3( part.x * part.y ); vertex.x+= top.x; vertex.y+= top.y; } //vertex.z == 2/3 //vec2 x_refl = refl(vertex.x,0.0,""" + str(float(self.res[0])) + """); //vec2 y_refl = refl(vertex.y,0.0,""" + str(float(self.res[1])) + """); //vec2 z_refl = refl(vertex.z,0.0,""" + str(1.0) + """); //vertex.xyz = vec3(x_refl.x,y_refl.x,z_refl.x); //sc *= vec3(x_refl.y,y_refl.y,z_refl.y);""") self.advection_shader.render_equation(""" color.rgb = texture2D(tex2D_2,uv).rgb; if (pos_neg!=0.0) { color.rgb = pos_neg * (color.rgb-vec3(0.5)); } color.rgb *= sc;""") print "Advection Shader:" errors = self.advection_shader.compile() if errors != "": print errors self.vec_zero_shader = glLibShader() self.vec_zero_shader.render_equation(""" color.rgb = vec3(0.5);""") print "Vector Zero Shader:" errors = self.vec_zero_shader.compile() if errors != "": print errors self.add_shader = glLibShader() self.add_shader.user_variables("uniform vec3 quantity;") self.add_shader.render_equation(""" color.rgb = texture2D(tex2D_1,uv).rgb + quantity;""") print "Add Shader:" errors = self.add_shader.compile() if errors != "": print errors self.diffuse_shader = glLibShader() self.diffuse_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.diffuse_shader.render_equation(""" vec3 q01 = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).rgb; vec3 q21 = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).rgb; vec3 q10 = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).rgb; vec3 q12 = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).rgb; vec3 q11 = texture2D(tex2D_1,uv ).rgb; color.rgb = q11 + q01+q21 + q10+q12; color.rgb /= 5.0; //color.rgb = -4.0*q11 + q01+q21 + q10+q12;""") print "Diffuse Shader:" errors = self.diffuse_shader.compile() if errors != "": print errors self.div_shader = glLibShader() self.div_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize; const float halfrdx = 1.0;//0.5 * griddelta.x;""") self.div_shader.render_equation(""" vec3 wL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).rgb; vec3 wR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).rgb; vec3 wB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).rgb; vec3 wT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).rgb; color.rgb = vec3( 0.5 + halfrdx * ((wR.x-wL.x)+(wT.y-wB.y)) ); //color.rgb = vec3( (wR.x-wL.x), (wT.y-wB.y), 0.0 );""") print "Divergence Shader:" errors = self.div_shader.compile() if errors != "": print errors self.prs_jacobi_shader = glLibShader() self.prs_jacobi_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize; const float alpha = 1.0;//-pow(griddelta.x,2.0); const float beta = 4.0;""") self.prs_jacobi_shader.render_equation(""" //tex2D_1 contains x, the pressure. tex2D_2 contains b, the divergence float xL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).r - 0.5; float xR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).r - 0.5; float xB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).r - 0.5; float xT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).r - 0.5; float bC = texture2D(tex2D_2,uv ).r - 0.5; //Evaluate Jacobi iteration color.rgb = vec3( 0.5 + ((xL+xR+xB+xT+(alpha*bC))/beta) );""") print "Pressure Jacobi Shader:" errors = self.prs_jacobi_shader.compile() if errors != "": print errors self.velprs_proj_shader = glLibShader() self.velprs_proj_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.velprs_proj_shader.render_equation(""" //tex2D_1 contains the velocities. tex2D_2 contains the pressure float pL = texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).x; float pR = texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).x; float pB = texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).x; float pT = texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).x; color.xyz = texture2D(tex2D_1,uv).xyz; color.xy += 0.5*vec2(pR-pL,pT-pB);""") print "Velocity-Pressure Projection Shader:" errors = self.velprs_proj_shader.compile() if errors != "": print errors self.boundary_condition_shader = glLibShader() self.boundary_condition_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize; uniform vec3 offset; uniform float scale;""") self.boundary_condition_shader.render_equation(""" //tex2D_1 is the state field (the field to set boundary conditions on) color.rgb = vec3(0.5) + scale*(texture2D(tex2D_1,uv+offset.xy*griddelta).rgb-vec3(0.5));""" ) print "Boundary Condition Shader:" errors = self.boundary_condition_shader.compile() if errors != "": print errors
def __init__(self, pos_length_surf, grow_surf, length_scale, max_length, density): #Size self.size = list(pos_length_surf.get_size()) #Misc. self.view_2d = glLibView2D((0, 0, self.size[0], self.size[1])) self.update_pingpong = 1 #Hair Parameters self.scale = 1.0 self.trans = [0.0, 0.0, 0.0] self.dampening = 0.98 self.tensor = 1.0 self.gravity = [0.0, 0.0, 0.0] self.steps = 1 self.density = density self.max_length = max_length self.length_scale = length_scale self.time_step = 1.0 #Physics self.forces = [0.0, 0.0, 0.0] #Geometry self.particles = glLibGrid2D(self.size) ## self.particles_mesh = glLibGrid2DMesh(self.size) self.particles_mesh = glLibDoubleGrid3DMesh([ self.density * self.size[0], self.density * self.size[1], self.max_length ]) ## self.particles_mesh = glLibDoubleGrid3DMesh([3,4,5]) self.draw_particles = glLibGrid2D(sc_vec(self.density, self.size)) #Textures self.position_length_textures = [ glLibTexture2D(pos_length_surf, (0, 0, self.size[0], self.size[1]), GL_RGBA, filtering=GLLIB_FILTER, precision=32) ] self.grow_tex = glLibTexture2D(grow_surf, (0, 0, self.size[0], self.size[1]), GL_RGB, precision=32) #FBOs self.update_framebuffers1 = [] self.update_framebuffers2 = [] self.grow_framebuffers = [] for hair_segment in xrange(self.max_length): update_framebuffer1 = glLibFBO(self.size) update_framebuffer1.add_render_target(1, precision=32, filter=GLLIB_FILTER, type=GLLIB_RGBA) update_framebuffer1.add_render_target(2, precision=32, filter=GLLIB_FILTER) self.update_framebuffers1.append(update_framebuffer1) update_framebuffer2 = glLibFBO(self.size) update_framebuffer2.add_render_target(1, precision=32, filter=GLLIB_FILTER, type=GLLIB_RGBA) update_framebuffer2.add_render_target(2, precision=32, filter=GLLIB_FILTER) self.update_framebuffers2.append(update_framebuffer2) grow_framebuffer = glLibFBO(self.size) grow_framebuffer.add_render_target(1, precision=32, type=GLLIB_RGBA) self.grow_framebuffers.append(grow_framebuffer) #Shaders self.grow_shader = glLibShader() self.grow_shader.use_prebuilt(GLLIB_HAIR_GROW) self.update_shader = glLibShader() self.update_shader.use_prebuilt(GLLIB_HAIR_UPDATE) self.draw_shader = glLibShader() self.draw_shader.use_prebuilt(GLLIB_HAIR_DRAW) #Grow Hair self.glLibInternal_grow() #Initialize Position self.glLibInternal_initialize_position()
def __init__(self, meshes): self.gamma = 1.0 self.iteration = 0 self.vertices = {} patches_count = 0 for mesh_data in meshes: obj = mesh_data[0] for sublist in range(obj.number_of_lists): for index in range(0, len(obj.vertices[sublist]), 4): patches_count += 1 self.original_patches = np.empty( (patches_count), [("number", np.int16), ("polygon", np.float32, (4, 3)), ("center", np.float32, (3)), ("tangent", np.float32, (3)), ("norm", np.float32, (3)), ("area", np.float32), ("accumulated radiance", np.float32, (3)), ("residual radiance", np.float32, (3)), ("residual power", np.float32), ("color", np.float32, (3)), ("reflectance", np.float32, (3))]) polynum = 0 vertex_number = 0 for mesh_data in meshes: obj = mesh_data[0] emission = mesh_data[2] if emission == GLLIB_NONE: emission = [0.0, 0.0, 0.0] reflectance = mesh_data[3] for sublist in range(obj.number_of_lists): color = mesh_data[1] if color == GLLIB_MATERIAL_AMBIENT: color = obj.materials[sublist]["Ka"][:3] elif color == GLLIB_MATERIAL_DIFFUSE: color = obj.materials[sublist]["Kd"][:3] elif color == GLLIB_MATERIAL_SPECULAR: color = obj.materials[sublist]["Ks"][:3] for index in range(0, len(obj.vertices[sublist]), 4): v1 = obj.vertices[sublist][index] v2 = obj.vertices[sublist][index + 1] v3 = obj.vertices[sublist][index + 2] v4 = obj.vertices[sublist][index + 3] n1 = obj.normals[sublist][index] n2 = obj.normals[sublist][index + 1] n3 = obj.normals[sublist][index + 2] n4 = obj.normals[sublist][index + 3] self.vertices[tuple(v1)] = glLibInternal_vertex(v1, n1) self.vertices[tuple(v2)] = glLibInternal_vertex(v2, n2) self.vertices[tuple(v3)] = glLibInternal_vertex(v3, n3) self.vertices[tuple(v4)] = glLibInternal_vertex(v4, n4) area = polygon_area([v1, v2, v3, v4]) self.original_patches[polynum]["number"] = polynum self.original_patches[polynum]["polygon"][0][:] = np.array( v1) self.original_patches[polynum]["polygon"][1][:] = np.array( v2) self.original_patches[polynum]["polygon"][2][:] = np.array( v3) self.original_patches[polynum]["polygon"][3][:] = np.array( v4) self.original_patches[polynum]["center"][:] = np.array( sc_vec(0.25, vec_add(vec_add(v1, v2), vec_add(v3, v4)))) self.original_patches[polynum]["tangent"][:] = np.array( normalize(vec_add(vec_subt(v1, v2), vec_subt(v3, v4)))) self.original_patches[polynum]["norm"][:] = np.array( normalize(vec_add(vec_add(n1, n2), vec_add(n3, n4)))) self.original_patches[polynum]["area"] = area self.original_patches[polynum]["color"][:] = np.array( color) self.original_patches[polynum][ "accumulated radiance"][:] = np.array(emission) self.original_patches[polynum][ "residual radiance"][:] = np.array(emission) self.original_patches[polynum]["residual power"] = sum( emission) * area self.original_patches[polynum][ "reflectance"][:] = reflectance polynum += 1 self.reset() self.visibility_shader = glLibShader() self.visibility_shader.user_variables(""" uniform vec3 patch_center; uniform vec3 current_patch_center; uniform vec3 patch_normal; uniform vec3 indices; varying float depth; varying vec3 vertex_vector;""") self.visibility_shader.post_vertex(""" vec3 axis_vector = normalize( cross( patch_normal, vec3(0.0,0.0,-1.0) ) ); float angle = acos( dot( patch_normal, vec3(0.0,0.0,-1.0) ) ); mat3 rot_matrix = rotation_matrix_arbitrary(axis_vector,-angle); vertex_vector = vertex.xyz - patch_center; vertex_vector = rot_matrix*vertex_vector; depth = length(vertex_vector)/1000.0; vertex_vector = normalize(vertex_vector); //http://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection float z_term = pow( 2.0/(1.0-vertex_vector.z), 0.5 ); // in range (-2,2) //however, we discard vertex_vector.z>=-0.01, to get a hemisphere so in range (-sqrt(2),sqrt(2)) vec2 coord = z_term*vertex_vector.xy; coord = coord/pow(2.0,0.5); //in range (-1,1) vertex.xy = coord; vertex.z = 0.0; vertex.w = 1.0; gl_Position = vertex;""") self.visibility_shader.render_equation(""" if (patch_center==current_patch_center) { discard; } if (vertex_vector.z>=-0.01) { discard; } color.rgb = indices; gl_FragDepth = depth;""") errors = self.visibility_shader.compile() print(errors) self.index_list = glGenLists(1) glNewList(self.index_list, GL_COMPILE) color = [0.0, 0.0, 1.0] for polynum in range(len(self.patches)): c_index = vec_div(color, [255.0] * 3) self.visibility_shader.pass_vec3("indices", c_index) self.visibility_shader.pass_vec3("current_patch_center", self.patches[polynum]["center"]) glNormal3f(*self.patches[polynum]["norm"]) glColor3f(*c_index) glBegin(GL_QUADS) for vert in self.patches[polynum]["polygon"]: glVertex3f(*vert) glEnd() color[2] += 1.0 if color[2] == 256.0: color[2] = 1.0 color[1] += 1.0 if color[1] == 256.0: color[1] = 0.0 color[0] += 1.0 glEndList()
def __init__(self,res): #heavily based on http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html self.res = list(res) self.diff = 0.0 self.visc = 0.0 self.new_forces = [] self.new_densities = [] self.view2D = glLibView2D((0,0,self.res[0],self.res[1])) self.precis = 32 self.advection_fbo1 = glLibFBO((self.res[0],self.res[1])) self.advection_fbo2 = glLibFBO((self.res[0],self.res[1])) self.advection_fbo1.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.advection_fbo2.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.diffusion_jacobi_fbo1 = glLibFBO((self.res[0],self.res[1])) self.diffusion_jacobi_fbo2 = glLibFBO((self.res[0],self.res[1])) self.diffusion_jacobi_fbo1.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.diffusion_jacobi_fbo2.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.add_fbo1 = glLibFBO((self.res[0],self.res[1])) self.add_fbo2 = glLibFBO((self.res[0],self.res[1])) self.add_fbo1.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.add_fbo2.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.pressure_fbo = glLibFBO((self.res[0],self.res[1])) self.pressure_fbo.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.pressure_jacobi_fbo1 = glLibFBO((self.res[0],self.res[1])) self.pressure_jacobi_fbo2 = glLibFBO((self.res[0],self.res[1])) self.pressure_jacobi_fbo1.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.pressure_jacobi_fbo2.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.spressure_fbo = glLibFBO((self.res[0],self.res[1])) self.spressure_fbo.add_render_target(1,GLLIB_RGB,GLLIB_FILTER,precision=self.precis) self.advection_ping_pong = 1 self.add_ping_pong = 1 self.diffusion_jacobi_ping_pong = 1 self.pressure_jacobi_ping_pong = 1 zero_value = np.empty((self.res[0],self.res[1],3)) zero_value.fill(127.5) zero_value = pygame.surfarray.make_surface(zero_value) self.velocity_tex = glLibTexture2D(zero_value,GLLIB_ALL,GLLIB_RGB,GLLIB_FILTER,precision=32) self.gas_tex = glLibTexture2D(pygame.Surface(self.res),GLLIB_ALL,GLLIB_RGB,GLLIB_FILTER,precision=32) self.advection_shader = glLibShader() self.advection_shader.user_variables(""" uniform float dt; const vec2 gridsize = vec2("""+str(self.res[0])+","+str(self.res[1])+"""); const vec2 griddelta = 1.0/gridsize;""") self.advection_shader.render_equation(""" //follow the velocity field "back in time", then interpolate and write to the output fragment //tex2D_1 contains the velocities; tex2D_2 contains the quantity to be advected vec2 pos = uv - dt * griddelta * vec3(texture2D(tex2D_1,uv).rgb-vec3(0.5)).rg; color.rgb = texture2D(tex2D_2,pos).rgb;""") print "Advection Shader" print self.advection_shader.compile() self.jacobi_shader = glLibShader() self.jacobi_shader.user_variables(""" uniform float iterations; uniform float dt; const vec2 gridsize = vec2("""+str(self.res[0])+","+str(self.res[1])+"""); const vec2 griddelta = 1.0/gridsize; float alpha = griddelta.x*griddelta.y/(iterations*dt); float rBeta = 1.0/(4.0+alpha);""") self.jacobi_shader.render_equation(""" //Ax = b; tex2D_1 contains the x vector; tex2D_2 contains the b vector //left, right, bottom, and top x samples vec4 xL = texture2D(tex2D_1,uv-vec2(griddelta.x,0)); vec4 xR = texture2D(tex2D_1,uv+vec2(griddelta.x,0)); vec4 xB = texture2D(tex2D_1,uv-vec2(0,griddelta.y)); vec4 xT = texture2D(tex2D_1,uv+vec2(0,griddelta.y)); //b sample, from center vec4 bC = texture2D(tex2D_2,uv); // evaluate Jacobi iteration color = (xL + xR + xB + xT + alpha * bC) * rBeta;""") print "Jacobi Shader" print self.jacobi_shader.compile() self.divergence_shader = glLibShader() self.divergence_shader.user_variables(""" uniform float iterations; uniform float dt; const vec2 gridsize = vec2("""+str(self.res[0])+","+str(self.res[1])+"""); const vec2 griddelta = 1.0/gridsize; const float halfrdx = 0.5*griddelta.x;""") self.divergence_shader.render_equation(""" //tex2D_1 contains the w vector field vec4 wL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)); vec4 wR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)); vec4 wB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)); vec4 wT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)); color.rgb = vec3( halfrdx * ((wR.x-wL.x)+(wT.y-wB.y)) ); color.rgb += 0.5;""") print "Divergence Shader" print self.divergence_shader.compile() self.gradient_subtract_shader = glLibShader() self.gradient_subtract_shader.user_variables(""" const vec2 gridsize = vec2("""+str(self.res[0])+","+str(self.res[1])+"""); const vec2 griddelta = 1.0/gridsize; const float halfrdx = 0.5*griddelta.x;""") self.gradient_subtract_shader.render_equation(""" //tex2D_1 contains the pressure; tex2D_2 contains the velocity float pL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).r; float pR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).r; float pB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).r; float pT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).r; color.rgb = texture2D(tex2D_2,uv).rgb; color.rg -= halfrdx * vec2(pR-pL,pT-pB);""") print "Gradient Subtract Shader" print self.gradient_subtract_shader.compile() self.add_shader = glLibShader() self.add_shader.user_variables("uniform vec3 quantity;") self.add_shader.render_equation(""" color.rgb = texture2D(tex2D_1,uv).rgb + quantity;""") print "Add Shader" print self.add_shader.compile()
def __init__(self, res): #heavily based on http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html self.res = list(res) self.diff = 0.0 self.visc = 0.0 self.new_forces = [] self.new_densities = [] self.view2D = glLibView2D((0, 0, self.res[0], self.res[1])) self.precis = 32 self.texture_captions = {} self.font = pygame.font.SysFont("Times New Roman", 10) self.gas_fbo1 = glLibFBO((self.res[0], self.res[1])) self.gas_fbo2 = glLibFBO((self.res[0], self.res[1])) self.prs_fbo1 = glLibFBO((self.res[0], self.res[1])) self.prs_fbo2 = glLibFBO((self.res[0], self.res[1])) self.vel_fbo1 = glLibFBO((self.res[0], self.res[1])) self.vel_fbo2 = glLibFBO((self.res[0], self.res[1])) self.div_fbo1 = glLibFBO((self.res[0], self.res[1])) self.div_fbo2 = glLibFBO((self.res[0], self.res[1])) for fbo in [ self.gas_fbo1, self.gas_fbo2, self.prs_fbo1, self.prs_fbo2, self.vel_fbo1, self.vel_fbo2, self.div_fbo1, self.div_fbo2 ]: fbo.add_render_target(1, GLLIB_RGB, filtering=GLLIB_FILTER, precision=self.precis) fbo.textures[1].edge(GLLIB_CLAMP) self.gas_ping_pong = 1 self.prs_ping_pong = 1 self.vel_ping_pong = 1 self.div_ping_pong = 1 self.zero_value = np.empty((self.res[0], self.res[1], 3)) self.zero_value.fill(0.5) self.reset() self.advection_shader = glLibShader() self.advection_shader.user_variables(""" uniform float dt; const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.advection_shader.render_equation(""" //follow the velocity field "back in time" vec2 pos = uv - dt*griddelta*(texture2D(tex2D_1,uv).rg-vec2(0.5)); //sample the data texture there, and write to the current fragment color = texture2D(tex2D_2,pos);""") print "Advection Shader:" errors = self.advection_shader.compile() if errors != "": print errors self.vec_zero_shader = glLibShader() self.vec_zero_shader.render_equation(""" color.rgb = vec3(0.5);""") print "Vector Zero Shader:" errors = self.vec_zero_shader.compile() if errors != "": print errors self.add_shader = glLibShader() self.add_shader.user_variables("uniform vec3 quantity;") self.add_shader.render_equation(""" //tex2D_1 contains the obstacles. tex2D_2 contains the data field. color.rgb = texture2D(tex2D_2,uv).rgb; if (texture2D(tex2D_1,uv).r==0.0) { color.rgb += quantity; }""") print "Add Shader:" errors = self.add_shader.compile() if errors != "": print errors self.diffuse_shader = glLibShader() self.diffuse_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.diffuse_shader.render_equation(""" //tex2D_1 contains the obstacles texture. tex2D_2 contains the data texture vec3 q01 = texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).rgb; vec3 q21 = texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).rgb; vec3 q10 = texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).rgb; vec3 q12 = texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).rgb; vec3 q11 = texture2D(tex2D_2,uv ).rgb; color.rgb = q11; float total = 1.0; if (texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).r==0.0) { color.rgb += q01; total += 1.0; } if (texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).r==0.0) { color.rgb += q21; total += 1.0; } if (texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).r==0.0) { color.rgb += q10; total += 1.0; } if (texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).r==0.0) { color.rgb += q12; total += 1.0; } color.rgb /= total; //color.rgb = vec3(0.5) + -4.0*(q11-vec3(0.5)) + q01+q21 + q10+q12 - 4.0*vec3(0.5);""" ) print "Diffuse Shader:" errors = self.diffuse_shader.compile() if errors != "": print errors self.div_shader = glLibShader() self.div_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.div_shader.render_equation(""" //tex2D_1 contains velocity. tex2D_2 contains the obstacles texture vec3 wL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).rgb; vec3 wR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).rgb; vec3 wB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).rgb; vec3 wT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).rgb; if (texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).r==1.0) { wL = vec3(0.5); } if (texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).r==1.0) { wR = vec3(0.5); } if (texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).r==1.0) { wB = vec3(0.5); } if (texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).r==1.0) { wT = vec3(0.5); } color.r = 0.5 + 0.5 * ((wR.x-wL.x)+(wT.y-wB.y));""") print "Divergence Shader:" errors = self.div_shader.compile() if errors != "": print errors self.prs_jacobi_shader = glLibShader() self.prs_jacobi_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize; const float alpha = 1.0;//-pow(griddelta.x,2.0); const float beta = 4.0;""") self.prs_jacobi_shader.render_equation(""" //tex2D_1 contains x, the pressure. tex2D_2 contains b, the divergence. tex2D_3 contains the obstacles. float xC = texture2D(tex2D_1,uv ).r - 0.5; float xL = texture2D(tex2D_1,uv-vec2(griddelta.x,0.0)).r - 0.5; float xR = texture2D(tex2D_1,uv+vec2(griddelta.x,0.0)).r - 0.5; float xB = texture2D(tex2D_1,uv-vec2(0.0,griddelta.y)).r - 0.5; float xT = texture2D(tex2D_1,uv+vec2(0.0,griddelta.y)).r - 0.5; float bC = texture2D(tex2D_2,uv ).r - 0.5; if (texture2D(tex2D_3,uv-vec2(griddelta.x,0.0)).r==1.0) { xL = xC; } if (texture2D(tex2D_3,uv+vec2(griddelta.x,0.0)).r==1.0) { xR = xC; } if (texture2D(tex2D_3,uv-vec2(0.0,griddelta.y)).r==1.0) { xB = xC; } if (texture2D(tex2D_3,uv+vec2(0.0,griddelta.y)).r==1.0) { xT = xC; } //color.r = 0.5 + ((xL+xR+xB+xT+(alpha*bC))/beta); color.r = 0.5 + ((xL+xR+xB+xT-bC)/4.0);""") print "Pressure Jacobi Shader:" errors = self.prs_jacobi_shader.compile() if errors != "": print errors self.velprs_proj_shader = glLibShader() self.velprs_proj_shader.user_variables(""" const vec2 gridsize = vec2(""" + str(self.res[0]) + "," + str(self.res[1]) + """); const vec2 griddelta = 1.0/gridsize;""") self.velprs_proj_shader.render_equation(""" //tex2D_1 contains the velocities. tex2D_2 contains the pressure. tex2D_3 contains the obstacles. float pC = texture2D(tex2D_2,uv ).r; float pL = texture2D(tex2D_2,uv-vec2(griddelta.x,0.0)).r; float pR = texture2D(tex2D_2,uv+vec2(griddelta.x,0.0)).r; float pB = texture2D(tex2D_2,uv-vec2(0.0,griddelta.y)).r; float pT = texture2D(tex2D_2,uv+vec2(0.0,griddelta.y)).r; if (texture2D(tex2D_3,uv-vec2(griddelta.x,0.0)).r==1.0) { pL = pC; } if (texture2D(tex2D_3,uv+vec2(griddelta.x,0.0)).r==1.0) { pR = pC; } if (texture2D(tex2D_3,uv-vec2(0.0,griddelta.y)).r==1.0) { pB = pC; } if (texture2D(tex2D_3,uv+vec2(0.0,griddelta.y)).r==1.0) { pT = pC; } color.xyz = texture2D(tex2D_1,uv).xyz; //subtract the gradient of the pressure from the velocity color.xy -= 0.5*vec2(pR-pL,pT-pB);""") print "Velocity-Pressure Projection Shader:" errors = self.velprs_proj_shader.compile() if errors != "": print errors