def grid(projection, view): size = 10 # create geometry # --------------- logging.debug("create grid geometry") positions = [] offset = int(size)/2 for x in range(0, int(size)+1): positions.append((x-offset, 0, size/2)) positions.append((x-offset, 0, -size/2)) for y in range(0, int(size)+1): positions.append((size/2, 0, y-offset)) positions.append((-size/2, 0, y-offset)) positions = np.array(positions, dtype=np.float32) # create buffers logging.debug("create grid buffers") vbo = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, positions.nbytes, positions, GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, vbo) vao = glGenVertexArrays(1) # create program logging.debug("create grid program") prog = program.create( """#version 330 core layout (location=0) in vec3 position; uniform mat4 projection; uniform mat4 view; void main(){ gl_Position = projection * view * vec4(position, 1.0); } """, """#version 330 core out vec4 FragColor; void main(){ FragColor = vec4(0.5,0.5,0.5,1); } """) # draw with program.use(prog): program.set_uniform(prog, "projection", projection) program.set_uniform(prog, "view", view) glBindVertexArray(vao) loc = glGetAttribLocation(prog, "position") glVertexAttribPointer(loc, 3, GL_FLOAT, False, 0, None) glEnableVertexAttribArray(loc) glDrawArrays(GL_LINES, 0, positions.size) glBindVertexArray(0)
def draw(self): GLFWViewer.poll_events() glViewport(0, 0, self.width, self.height) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) with program.use(self.prog) as prog: program.set_uniform(prog, 'projectionMatrix', self.window.projection_matrix) program.set_uniform(prog, 'viewMatrix', self.window.view_matrix) program.set_uniform(prog, 'modelMatrix', np.eye(4)) glBindTexture(GL_TEXTURE_2D, self.matcap_tex) program.set_uniform(prog, 'matCap', 0) imdraw.torusknot(prog) self.window.swap_buffers()
def draw_scene_for_shadows(self, prog): for child in self.scene.children: # set uniforms program.set_uniform(prog, 'model', child.transform) # set attributes vao, ebo, pos_vbo, uv_vbo, normal_vbo, count = self.get_geometry_buffer( child) glBindVertexArray(vao) position_location = glGetAttribLocation(prog, 'position') glBindBuffer(GL_ARRAY_BUFFER, pos_vbo) glVertexAttribPointer(position_location, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(position_location) # draw geometry glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, None) # cleanup bindings glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0)
def draw_scene_for_geometry(self, prog): import ctypes for child in self.scene.children: # set uniforms program.set_uniform(prog, 'model', child.transform) program.set_uniform(prog, 'albedo', child.material.albedo) program.set_uniform(prog, 'roughness', child.material.roughness) program.set_uniform(prog, 'metallic', child.material.metallic) # set attributes vao, ebo, pos_vbo, uv_vbo, normal_vbo, count = self.get_geometry_buffer( child) glBindVertexArray(vao) position_location = glGetAttribLocation(prog, 'position') glBindBuffer(GL_ARRAY_BUFFER, pos_vbo) glVertexAttribPointer(position_location, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(position_location) uv_location = glGetAttribLocation(prog, 'uv') if uv_location is not -1: glBindBuffer(GL_ARRAY_BUFFER, uv_vbo) glVertexAttribPointer(uv_location, 2, GL_FLOAT, False, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(uv_location) normal_location = glGetAttribLocation(prog, 'normal') if normal_location is not -1: glBindBuffer(GL_ARRAY_BUFFER, normal_vbo) glVertexAttribPointer(normal_location, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(normal_location) # draw geometry glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, None) # cleanup bindings glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0)
level=logging.DEBUG, format='%(levelname)s:%(module)s.%(funcName)s: %(message)s') width, height = 1024, 768 model_matrix = np.identity(4) window = GLFWViewer(width, height, (0.6, 0.7, 0.7, 1.0)) with window: glEnable(GL_DEPTH_TEST) glEnable(GL_CULL_FACE) while not window.should_close(): glViewport(0, 0, window.width, window.height) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) with program.use(skybox_program): program.set_uniform(skybox_program, 'projection', window.projection_matrix) sky_view = glm.mat4(glm.mat3(window.view_matrix)) program.set_uniform(skybox_program, 'view', sky_view) camera_pos = glm.transpose( glm.transpose(glm.inverse(window.view_matrix)))[3].xyz program.set_uniform(skybox_program, 'cameraPos', camera_pos) program.set_uniform(skybox_program, 'skybox', 0) program.set_uniform(skybox_program, 'groundProjection', True) glActiveTexture(GL_TEXTURE0 + 0) glBindTexture(GL_TEXTURE_CUBE_MAP, env_cubemap) imdraw.cube(skybox_program, flip=True) glBindTexture(GL_TEXTURE_CUBE_MAP, 0) glDepthMask(GL_TRUE) # draw grid
for i in range(64): sample = glm.vec3(np.random.uniform((-1, -1, 0), (1, 1, 1), (3, ))) sample = glm.normalize(sample) sample *= np.random.uniform(0, 1) scale = i / 64 # scale samples s.t. they are more aligned to center of kernel scale = glm.mix(0.1, 1.0, scale * scale) sample *= scale ssaoKernel.append(sample) with program.use(ssao_program): for i, sample in enumerate(ssaoKernel): name = "samples[{}]".format(i) location = glGetUniformLocation(ssao_program, name) program.set_uniform(ssao_program, name, sample) noise_data = np.random.uniform((-1, -1, 0), (1, 1, 0), (4, 4, 3)) noise_texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, noise_texture) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, noise_data) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glBindTexture(GL_TEXTURE_2D, 0) # create ssao fbo # --------------- ssao_fbo = glGenFramebuffers(1)
def texture(tex, rect, shuffle=(0, 1, 2, -1)): # create shader program debug_quad_program = program.create( *glsl.read('debug_quad.vs', 'shuffle.fs')) # setup program uniforms with program.use(debug_quad_program): program.set_uniform(debug_quad_program, 'projectionMatrix', np.eye(4)) program.set_uniform(debug_quad_program, 'viewMatrix', np.eye(4)) program.set_uniform(debug_quad_program, 'modelMatrix', np.eye(4)) program.set_uniform(debug_quad_program, 'tex', 0) program.set_uniform(debug_quad_program, 'shuffle.red', shuffle[0]) program.set_uniform(debug_quad_program, 'shuffle.green', shuffle[1]) program.set_uniform(debug_quad_program, 'shuffle.blue', shuffle[2]) program.set_uniform(debug_quad_program, 'shuffle.alpha', shuffle[3]) # draw texture quad glViewport(*rect) with program.use(debug_quad_program): glActiveTexture(GL_TEXTURE0 + 0) glBindTexture(GL_TEXTURE_2D, tex) quad(debug_quad_program) glBindTexture(GL_TEXTURE_2D, 0)
def render(self): # Animate # ------- import math, time spotlight.position = glm.vec3(math.cos(time.time() * 3) * 4, 0.3, -4) spotlight.direction = -spotlight.position pointlight.position = glm.vec3( math.cos(time.time()) * 4, 4, math.sin(time.time()) * 4) self.camera.transform = glm.inverse(self.window.view_matrix) # Render passes # ------------- ## Geometry self.geometry_pass.camera = self.camera # window.projection_matrix, window.view_matrix self.geometry_pass.render() ## Shadowmaps dirlight.shadowpass.camera = dirlight.camera dirlight.shadowpass.render() spotlight.shadowpass.camera = spotlight.camera spotlight.shadowpass.render() pointlight.shadowpass.position = pointlight.position pointlight.shadowpass.render() ## Lighting self.lighting_pass.cameraPos = self.camera.position self.lighting_pass.gPosition = self.geometry_pass.gPosition self.lighting_pass.gNormal = self.geometry_pass.gNormal self.lighting_pass.gAlbedoSpecular = self.geometry_pass.gAlbedoSpecular self.lighting_pass.gRoughness = self.geometry_pass.gRoughness self.lighting_pass.gMetallic = self.geometry_pass.gMetallic self.lighting_pass.gEmissive = self.geometry_pass.gEmissive self.lighting_pass.render() ## Forward rendering # - Copy depth from geometry pass glBindFramebuffer(GL_READ_FRAMEBUFFER, self.geometry_pass.gBuffer) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, self.forward_fbo) # write to default framebuffer glBlitFramebuffer(0, 0, self.width, self.height, 0, 0, self.width, self.height, GL_DEPTH_BUFFER_BIT, GL_NEAREST) glBindFramebuffer(GL_READ_FRAMEBUFFER, self.lighting_pass.fbo) glBlitFramebuffer(0, 0, self.width, self.height, 0, 0, self.width, self.height, GL_COLOR_BUFFER_BIT, GL_NEAREST) glBindFramebuffer(GL_FRAMEBUFFER, 0) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glDepthMask(GL_FALSE) with fbo.bind(self.forward_fbo): # draw skybox glViewport(0, 0, self.width, self.height) with program.use(self.skybox_program) as prog: program.set_uniform(prog, 'projection', self.camera.projection) sky_view = glm.mat4(glm.mat3(self.camera.view)) program.set_uniform(prog, 'view', sky_view) program.set_uniform(prog, 'cameraPos', self.camera.position) program.set_uniform(prog, 'skybox', 0) program.set_uniform(prog, 'groundProjection', True) glActiveTexture(GL_TEXTURE0 + 0) glBindTexture(GL_TEXTURE_CUBE_MAP, self.environment_pass.cubemap) imdraw.cube(prog, flip=True) glBindTexture(GL_TEXTURE_CUBE_MAP, 0) glDepthMask(GL_TRUE) ## Tonemapping self.tonemapping_pass.hdrimage = self.lighting_pass.beauty self.tonemapping_pass.exposure = 0.0 self.tonemapping_pass.gamma = 2.2 self.tonemapping_pass.render() # Render to screen # ---------------- glViewport(0, 0, self.width, self.height) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glDisable(GL_DEPTH_TEST) # draw to screen imdraw.texture(self.tonemapping_pass.ldrimage, (0, 0, self.width, self.height)) # debug imdraw.texture(self.geometry_pass.gPosition, (0, 0, 90, 90)) imdraw.texture(self.geometry_pass.gNormal, (100, 0, 90, 90)) imdraw.texture(self.geometry_pass.gAlbedoSpecular, (200, 0, 90, 90), shuffle=(0, 1, 2, -1)) imdraw.texture(self.geometry_pass.gAlbedoSpecular, (300, 0, 90, 90), shuffle=(3, 3, 3, -1)) imdraw.texture(self.geometry_pass.gRoughness, (400, 0, 90, 90), shuffle=(0, 0, 0, -1)) imdraw.texture(self.geometry_pass.gMetallic, (500, 0, 90, 90), shuffle=(0, 0, 0, -1)) imdraw.texture(dirlight.shadowpass.texture, (0, 100, 90, 90), shuffle=(0, 0, 0, -1)) imdraw.texture(spotlight.shadowpass.texture, (100, 100, 90, 90), shuffle=(0, 0, 0, -1)) imdraw.cubemap(pointlight.shadowpass.cubemap, (200, 100, 90, 90), self.window.projection_matrix, self.window.view_matrix) imdraw.texture(self.environment_tex, (0, 200, 90, 90)) imdraw.cubemap(self.environment_pass.cubemap, (100, 200, 90, 90), self.window.projection_matrix, self.window.view_matrix) imdraw.cubemap(self.irradiance_pass.irradiance, (200, 200, 90, 90), self.window.projection_matrix, self.window.view_matrix) imdraw.cubemap(self.prefilter_pass.prefilter, (300, 200, 90, 90), self.window.projection_matrix, self.window.view_matrix) imdraw.texture(self.brdf_pass.brdflut, (400, 200, 90, 90)) imdraw.texture(self.lighting_pass.beauty, (0, 300, 90, 90)) # swap buffers # ------------ self.window.swap_buffers() GLFWViewer.poll_events()
def draw_scene(prog, projection_matrix, view_matrix): """Draw scen with a shader program""" program.set_uniform(prog, 'projectionMatrix', projection_matrix) program.set_uniform(prog, 'viewMatrix', view_matrix) camera_pos = glm.inverse(view_matrix)[3].xyz program.set_uniform(prog, 'cameraPos', camera_pos) model_matrix = glm.translate(glm.mat4(1), (-1, 0.5, 0)) normal_matrix = glm.mat3(glm.transpose(glm.inverse(model_matrix))) program.set_uniform(prog, 'modelMatrix', model_matrix) program.set_uniform(prog, 'normalMatrix', normal_matrix) imdraw.cube(prog) model_matrix = glm.translate(glm.mat4(1), (1, 0, 0)) normal_matrix = glm.mat3(glm.transpose(glm.inverse(model_matrix))) program.set_uniform(prog, 'modelMatrix', model_matrix) program.set_uniform(prog, 'normalMatrix', normal_matrix) imdraw.sphere(prog) model_matrix = glm.mat4(1) normal_matrix = glm.mat3(glm.transpose(glm.inverse(model_matrix))) program.set_uniform(prog, 'modelMatrix', model_matrix) program.set_uniform(prog, 'normalMatrix', normal_matrix) imdraw.plane(prog)
# create rbo capture_rbo = glGenRenderbuffers(1) glBindRenderbuffer(GL_RENDERBUFFER, capture_rbo) glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, env_width, env_height) glBindRenderbuffer(GL_RENDERBUFFER, 0) # create fbo capture_fbo = glGenFramebuffers(1) # draw environment map to skybox glViewport(0, 0, env_width, env_height) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, environment_tex) with program.use(equirectangular_to_cubemap_program): program.set_uniform(equirectangular_to_cubemap_program, "equirectangularMap", 0) program.set_uniform(equirectangular_to_cubemap_program, "projectionMatrix", capture_projection) with fbo.bind(capture_fbo): for i in range(6): glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, env_cubemap, 0) program.set_uniform(equirectangular_to_cubemap_program, "viewMatrix", capture_views[i]) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) imdraw.cube(equirectangular_to_cubemap_program, flip=True) # Image based lighting # --------------------
env_height) glBindRenderbuffer(GL_RENDERBUFFER, 0) # create cubemap fbo capture_fbo = glGenFramebuffers(1) # attach depth buffer with fbo.bind(capture_fbo): glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, capture_rbo) # draw environment map to each cubemap side glViewport(0, 0, env_width, env_height) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, environment_tex) with program.use(equirectangular_to_cubemap_program): program.set_uniform(equirectangular_to_cubemap_program, "equirectangularMap", 0) program.set_uniform(equirectangular_to_cubemap_program, "projectionMatrix", capture_projection) with fbo.bind(capture_fbo): for i in range(6): glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, env_cubemap, 0) program.set_uniform(equirectangular_to_cubemap_program, "viewMatrix", capture_views[i]) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) imdraw.cube(equirectangular_to_cubemap_program, flip=True) ## setup skybox drawing skybox_program = program.create(*glsl.read('skybox'))
def cubemap(tex, rect, projection, view, LOD=None, shuffle=(0, 1, 2, 3)): prog = create_program() glViewport(*rect) with program.use(prog): glActiveTexture(GL_TEXTURE0 + 0) glBindTexture(GL_TEXTURE_CUBE_MAP, tex) program.set_uniform(prog, "projectionMatrix", projection) program.set_uniform(prog, "viewMatrix", view) program.set_uniform(prog, "modelMatrix", glm.scale(glm.mat4(1), (1.1, 1.1, 1.1))) program.set_uniform(prog, "cubeMap", 0) program.set_uniform(prog, "useLOD", LOD is not None) program.set_uniform(prog, "LOD", LOD or 0.0) program.set_uniform(prog, 'shuffle.red', shuffle[0]) program.set_uniform(prog, 'shuffle.green', shuffle[1]) program.set_uniform(prog, 'shuffle.blue', shuffle[2]) program.set_uniform(prog, 'shuffle.alpha', shuffle[3]) cube(prog) glBindTexture(GL_TEXTURE_CUBE_MAP, 0)
#version 330 core uniform mat4 projection; uniform mat4 view; uniform mat4 model; layout (location = 0) in vec3 position; void main(){ gl_Position = projection * view * model * vec4(position, 1.0); } """, """ #version 330 core out vec4 FragColor; void main(){ FragColor = vec4(1,1,1,1); } """) while not window.should_close(): glViewport(0, 0, window.width, window.height) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) with program.use(prog): program.set_uniform(prog, 'projection', window.projection_matrix) program.set_uniform(prog, 'view', window.view_matrix) program.set_uniform(prog, 'model', np.eye(4)) imdraw.cube(prog) # draw grid window.swap_buffers() GLFWViewer.poll_events()
shadowTransforms.append( shadowProj * glm.lookAt(lightPos, lightPos + glm.vec3(0.0, 0.0, 1.0), glm.vec3(0.0, -1.0, 0.0))) shadowTransforms.append( shadowProj * glm.lookAt(lightPos, lightPos + glm.vec3(0.0, 0.0, -1.0), glm.vec3(0.0, -1.0, 0.0))) shadowTransforms = np.array([np.array(m) for m in shadowTransforms]) glViewport(0, 0, shadow_width, shadow_height) with fbo.bind(shadow_depth_fbo), program.use( point_shadow_program) as prog: glClear(GL_DEPTH_BUFFER_BIT) for i in range(6): program.set_uniform(prog, "shadowMatrices[{}]".format(i), shadowTransforms[i]) program.set_uniform(prog, 'farPlane', far_plane) program.set_uniform(prog, 'lightPos', lightPos) # draw scene program.set_uniform(prog, 'model', glm.translate(glm.mat4(1), (-1, 0.5, -1))) imdraw.cube(prog) program.set_uniform(prog, 'model', glm.translate(glm.mat4(1), (1, 0.5, -1))) imdraw.cube(prog) program.set_uniform(prog, 'model', glm.translate(glm.mat4(1), (1, 0.5, 1))) imdraw.sphere(prog) program.set_uniform(prog, 'model', glm.translate(glm.mat4(1), (-1, 0.5, 1)))