def bind_and_filter(tex, bindcode, image=None, imageNum=None): bgl.glActiveTexture(tex) bgl.glBindTexture(bgl.GL_TEXTURE_2D, bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) if image!=None and imageNum!=None: shader.uniform_int(image, imageNum)
def bind_and_filter(tex, bindcode, image=None, imageNum=None): bgl.glActiveTexture(tex) bgl.glBindTexture(bgl.GL_TEXTURE_2D, bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) # Turn on GL_CLAMP_TO_BORDER and delete paint black codes in fragment shader # would give a transparent background #bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_BORDER) #bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_BORDER) # Really dont know how to change the border color #bgl.glTexParameterfv(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_BORDER_COLOR, color)#??? if image != None and imageNum != None: shader.uniform_int(image, imageNum)
def init_texture(width, height, texname, texture, internalFormat, format): bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, texname) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) # bgl.GL_CLAMP bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) # bgl.GL_CLAMP bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexImage2D( bgl.GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, bgl.GL_UNSIGNED_BYTE, texture )
def init_texture(width, height, texname, texture, clr): # function to init the texture bgl.glPixelStorei(bgl.GL_UNPACK_ALIGNMENT, 1) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, texname) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, clr, width, height, 0, clr, bgl.GL_FLOAT, texture)
def init_texture(self, width, height): clr = bgl.GL_RGBA texname = self.texture_dict['texture'] data = self.texture_dict['texture_data'] texture = bgl.Buffer(bgl.GL_FLOAT, data.size, data.tolist()) bgl.glPixelStorei(bgl.GL_UNPACK_ALIGNMENT, 1) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, texname) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, clr, width, height, 0, clr, bgl.GL_FLOAT, texture)
def init_texture(width, height, texname, texture, clr): # function to init the texture bgl.glPixelStorei(bgl.GL_UNPACK_ALIGNMENT, 1) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, texname) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexImage2D( bgl.GL_TEXTURE_2D, 0, clr, width, height, 0, clr, bgl.GL_FLOAT, texture )
def init_texture(self, width, height): texname = self.texture_dict['texture'] data = self.texture_dict['texture_data'] clr = bgl.GL_RGBA if not 'texture_buffer' in self.texture_dict: #print('initializing texture longform') texture = bgl.Buffer(bgl.GL_FLOAT, data.size, data.tolist()) self.texture_dict['texture_buffer'] = texture else: #print("reusing") texture = self.texture_dict['texture_buffer'] bgl.glPixelStorei(bgl.GL_UNPACK_ALIGNMENT, 1) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, texname) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, clr, width, height, 0, clr, bgl.GL_FLOAT, texture)
def render_lens_flare(context, props: MasterProperties) -> (bgl.Buffer, int): """ Renders lens flare effect to buffer :returns buffer with effect """ max_x = props.resolution.resolution_x max_y = props.resolution.resolution_y # render kinda circles blades = props.camera.blades if blades == 0: blades = 256 shaders = Shaders() offscreen = gpu.types.GPUOffScreen(max_x, max_y) ghost_fb = gpu.types.GPUOffScreen(max_x, max_y) ghost_batch = batch_from_blades(blades, shaders.ghost) quad_batch = batch_quad(shaders.flare) draw_count = 0 noise_tex = NoiseTexture() # clear framebuffer with offscreen.bind(): # black background bgl.glClearColor(0.0, 0.0, 0.0, 1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE) for position in props.positions: pos = Vector((position.manual_x, position.manual_y)) # set position from object if position.variant == 'auto' and position.auto_object is not None: world_pos = position.auto_object.matrix_world.to_translation() pos = bpy_extras.object_utils.world_to_camera_view( context.scene, context.scene.camera, world_pos) flare_vector = pos.xy - Vector((0.5, 0.5)) flare_vector.normalize() # first render ghosts one by one for ghost in props.ghosts: # calculate position ghost_x = ((pos.x - 0.5) * 2.0) * ghost.offset ghost_y = ((pos.y - 0.5) * 2.0) * ghost.offset # add perpendicular offset ghost_x += flare_vector.y * ghost.perpendicular_offset ghost_y += -flare_vector.x * ghost.perpendicular_offset with ghost_fb.bind(): render_ghost(props, ghost, shaders.ghost, ghost_batch, flare_vector, pos) draw_count += 1 with offscreen.bind(): # now copy to final buffer bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, ghost_fb.color_texture) # disable wrapping bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_BORDER) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_BORDER) border_color = bgl.Buffer(bgl.GL_FLOAT, 4, [0.0, 0.0, 0.0, 1.0]) bgl.glTexParameterfv(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_BORDER_COLOR, border_color) bgl.glActiveTexture(bgl.GL_TEXTURE2) bgl.glBindTexture(bgl.GL_TEXTURE_2D, props.spectrum_image.bindcode) bgl.glActiveTexture(bgl.GL_TEXTURE1) bgl.glBindTexture(bgl.GL_TEXTURE_2D, noise_tex.gl_code) copy_ghost(shaders.copy, quad_batch, ghost, props, Vector((ghost_x, ghost_y))) draw_count += 1 # finally render flare on top with offscreen.bind(): bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, noise_tex.gl_code) render_flare(props, pos.xy, shaders.flare, quad_batch) draw_count += 1 with offscreen.bind(): # copy rendered image to RAM buffer = bgl.Buffer(bgl.GL_FLOAT, max_x * max_y * 4) bgl.glReadBuffer(bgl.GL_BACK) bgl.glReadPixels(0, 0, max_x, max_y, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) offscreen.free() ghost_fb.free() noise_tex.free() return buffer, draw_count
def image_to_KK(image, lut_name): width = image.size[0] height = image.size[1] # Some Sauce vertex_default = ''' in vec2 a_position; in vec2 a_texcoord; void main() { gl_Position = vec4(a_position, 0.0, 1.0); } ''' # The Secret Sauce current_code = ''' uniform sampler2D tex0; uniform sampler2D lut; uniform vec2 u_resolution; vec3 to_srgb(vec3 c){ c.rgb = max( 1.055 * pow( c.rgb, vec3(0.416666667,0.416666667,0.416666667) ) - 0.055, 0 ); return c; } vec3 apply_lut(vec3 color) { const vec3 coord_scale = vec3(0.0302734375, 0.96875, 31.0); const vec3 coord_offset = vec3( 0.5/1024, 0.5/32, 0.0); const vec2 texel_height_X0 = vec2( 0.03125, 0.0 ); vec3 coord = color * coord_scale + coord_offset; vec3 coord_frac = fract( coord ); vec3 coord_floor = coord - coord_frac; vec2 coord_bot = coord.xy + coord_floor.zz * texel_height_X0; vec2 coord_top = coord_bot + texel_height_X0; vec3 lutcol_bot = texture2D( lut, coord_bot ).rgb; vec3 lutcol_top = texture2D( lut, coord_top ).rgb; vec3 lutColor = mix(lutcol_bot, lutcol_top, coord_frac.z); return lutColor; } void main() { vec4 texRGBA = texture2D(tex0, gl_FragCoord.xy / u_resolution); vec3 texColor = to_srgb(texRGBA.rgb); vec3 newColor = apply_lut(texColor); newColor = to_srgb(newColor); gl_FragColor = vec4(newColor.rgb, texRGBA.a); } ''' # This object gives access to off screen buffers. offscreen = gpu.types.GPUOffScreen(width, height) # Context manager to ensure balanced bind calls, even in the case of an error. # Only run if valid with offscreen.bind(): # Clear buffers to preset values bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) # Initialize the shader # GPUShader combines multiple GLSL shaders into a program used for drawing. # It must contain a vertex and fragment shaders, with an optional geometry shader. shader = gpu.types.GPUShader(vertex_default, current_code) # Initialize the shader batch # It makes sure that all the vertex attributes necessary for a specific shader are provided. batch = batch_for_shader( shader, 'TRI_FAN', {'a_position': ((-1, -1), (1, -1), (1, 1), (-1, 1))}, ) # Bind the shader object. Required to be able to change uniforms of this shader. shader.bind() bgl.glUniform1i(bgl.glGetUniformLocation(shader.program, "tex0"), 0) bgl.glUniform1i(bgl.glGetUniformLocation(shader.program, "lut"), 1) try: # Make sure image has a bindcode if image.bindcode == 0: for i in range(0, 20): image.gl_load() if image.bindcode != 0: break # https://docs.blender.org/api/current/bgl.html bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) # Specify the value of a uniform variable for the current program object. # In this case, an image. shader.uniform_int("tex0", 0) except ValueError: pass try: lut_image = bpy.data.images[lut_name] # Make sure image has a bindcode if lut_image.bindcode == 0: for i in range(0, 20): lut_image.gl_load() if lut_image.bindcode != 0: break # https://docs.blender.org/api/current/bgl.html bgl.glActiveTexture(bgl.GL_TEXTURE1) bgl.glBindTexture(bgl.GL_TEXTURE_2D, lut_image.bindcode) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) # Specify the value of a uniform variable for the current program object. # In this case, an image. shader.uniform_int("lut", 1) except ValueError: pass try: shader.uniform_float('u_resolution', (width, height)) except ValueError: pass # Run the drawing program with the parameters assigned to the batch. batch.draw(shader) # The Buffer object is simply a block of memory that is delineated and initialized by the user. buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4) # Select a color buffer source for pixels. bgl.glReadBuffer(bgl.GL_BACK) # Read a block of pixels from the frame buffer. bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer) # Free the offscreen object. The framebuffer, texture and render objects will no longer be accessible. offscreen.free() # Return the final buffer-pixels pixels = [v / 255 for v in buffer] return pixels, width, height
def color_to_KK(color, lut_name): width = 1 height = 1 # Some Sauce vertex_default = ''' in vec2 a_position; void main() { gl_Position = vec4(a_position, 0.0, 1.0); } ''' # The Secret Sauce current_code = ''' uniform vec3 inputColor; uniform sampler2D lut; vec3 to_srgb(vec3 c){ c.rgb = max( 1.055 * pow( c.rgb, vec3(0.416666667,0.416666667,0.416666667) ) - 0.055, 0 ); return c; } void main() { vec3 color = inputColor / 255; const vec3 coord_scale = vec3(0.0302734375, 0.96875, 31.0); const vec3 coord_offset = vec3( 0.5/1024, 0.5/32, 0.0); const vec2 texel_height_X0 = vec2( 0.03125, 0.0 ); vec3 coord = color * coord_scale + coord_offset; vec3 coord_frac = fract( coord ); vec3 coord_floor = coord - coord_frac; vec2 coord_bot = coord.xy + coord_floor.zz * texel_height_X0; vec2 coord_top = coord_bot + texel_height_X0; vec3 lutcol_bot = texture( lut, coord_bot ).rgb; vec3 lutcol_top = texture( lut, coord_top ).rgb; vec3 lutColor = mix(lutcol_bot, lutcol_top, coord_frac.z); vec3 shaderColor = lutColor; gl_FragColor = vec4(shaderColor.rgb, 1); } ''' # This object gives access to off screen buffers. offscreen = gpu.types.GPUOffScreen(width, height) # Context manager to ensure balanced bind calls, even in the case of an error. # Only run if valid with offscreen.bind(): # Clear buffers to preset values bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) # Initialize the shader # GPUShader combines multiple GLSL shaders into a program used for drawing. # It must contain a vertex and fragment shaders, with an optional geometry shader. shader = gpu.types.GPUShader(vertex_default, current_code) # Initialize the shader batch # It makes sure that all the vertex attributes necessary for a specific shader are provided. batch = batch_for_shader( shader, 'TRI_FAN', {'a_position': ((-1, -1), (1, -1), (1, 1), (-1, 1))}, ) # Bind the shader object. Required to be able to change uniforms of this shader. shader.bind() try: # Specify the value of a uniform variable for the current program object. # In this case, a color tuple. shader.uniform_float('inputColor', color) except ValueError: pass try: lut_image = bpy.data.images[lut_name] # Make sure image has a bindcode if lut_image.bindcode == 0: for i in range(0, 20): lut_image.gl_load() if lut_image.bindcode != 0: break # https://docs.blender.org/api/current/bgl.html bgl.glBindTexture(bgl.GL_TEXTURE_2D, lut_image.bindcode) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) # Specify the value of a uniform variable for the current program object. # In this case, an image. shader.uniform_int("lut", 0) except ValueError: pass # Run the drawing program with the parameters assigned to the batch. batch.draw(shader) # The Buffer object is simply a block of memory that is delineated and initialized by the user. buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 3) # Select a color buffer source for pixels. bgl.glReadBuffer(bgl.GL_BACK) # Read a block of pixels from the frame buffer. bgl.glReadPixels(0, 0, width, height, bgl.GL_RGB, bgl.GL_UNSIGNED_BYTE, buffer) # Free the offscreen object. The framebuffer, texture and render objects will no longer be accessible. offscreen.free() # Get and return the pixels from the final buffer final_color = [v for v in buffer] final_color = np.array(final_color).reshape(width, height, -1) return final_color[0][0] # RGBA (1, 1, 1, 1) to RGB as int (255, 255, 255) def RGBA_to_RGB_int(rgba): rgba = np.round(rgba * 255).astype('int') rgba = np.delete(rgba, 3) return rgba # Make sure not to select a transparent pixel def filter_pixel(index_list, image): for i in index_list: if image[i][3] == 1: index = i break return index ########## SETUP ########## exposure = np.array([exposure[0], exposure[1], exposure[2], 1]) # Init MC Texture mc_mask_data = np.array(mc_mask.pixels).reshape(-1, 4) mc_mask_data = mc_mask_data * exposure mc_mask_data = np.clip(mc_mask_data, 0, 1) # Init Main Texture bpy.data.images[texture.name].scale(mc_mask.size[0], mc_mask.size[1]) texture_data = np.array(texture.pixels).reshape(-1, 4) # Init MC Color indexes red_index = -1 green_index = -1 blue_index = -1 # Init MainTex Colors red_color = -1 green_color = -1 blue_color = -1 # Init converted colors (light) red_converted_color_light = np.array([255, 0, 0, 255]) green_converted_color_light = np.array([0, 255, 0, 255]) blue_converted_color_light = np.array([0, 0, 255, 255]) ########## FIND MC INDEXES ########## r, g, b = mc_mask_data[:, 0], mc_mask_data[:, 1], mc_mask_data[:, 2] r = r.max() g = g.max() b = b.max() # Red pixel_list = np.where(np.all(mc_mask_data == (r, 0, 0, 1), axis=-1))[0] if len(pixel_list) > 0: red_index = filter_pixel(pixel_list, texture_data) # Green pixel_list = np.where(np.all(mc_mask_data >= (0, g, 0, 1), axis=-1))[0] if len(pixel_list) > 0: green_index = filter_pixel(pixel_list, texture_data) else: # Green (Yellow) pixel_list = np.where(np.all(mc_mask_data == (r, g, 0, 1), axis=-1))[0] if len(pixel_list) > 0: green_index = filter_pixel(pixel_list, texture_data) # Blue pixel_list = np.where(np.all(mc_mask_data == (0, 0, b, 1), axis=-1))[0] if len(pixel_list) > 0: blue_index = filter_pixel(pixel_list, texture_data) else: # Blue (Cyan) pixel_list = np.where(np.all(mc_mask_data == (0, g, b, 1), axis=-1))[0] if len(pixel_list) > 0: blue_index = filter_pixel(pixel_list, texture_data) else: # Blue (Magenta) pixel_list = np.where(np.all(mc_mask_data == (r, 0, b, 1), axis=-1))[0] if len(pixel_list) > 0: blue_index = filter_pixel(pixel_list, texture_data) else: # Blue (White) pixel_list = np.where( np.all(mc_mask_data == (r, g, b, 1), axis=-1))[0] if len(pixel_list) > 0: blue_index = filter_pixel(pixel_list, texture_data) ########## SCALE INDEXES ########## # mc_w, mc_h = mc_mask.size # tex_w, tex_h = texture.size # scale = int((tex_w * tex_h) / (mc_w * mc_h)) # red_index = red_index * scale # green_index = green_index * scale # blue_index = blue_index * scale ########## GET AND CONVERT COLORS FROM MAIN TEXTURE ########## if red_index >= 0: red_color = texture_data[red_index] red_color = RGBA_to_RGB_int(red_color) red_converted_color_light = color_to_KK(red_color, lut) if green_index >= 0: green_color = texture_data[green_index] green_color = RGBA_to_RGB_int(green_color) green_converted_color_light = color_to_KK(green_color, lut) if blue_index >= 0: blue_color = texture_data[blue_index] blue_color = RGBA_to_RGB_int(blue_color) blue_converted_color_light = color_to_KK(blue_color, lut) # print(red_index) # print(green_index) # print(blue_index) # print(red_converted_color_light) # print(green_converted_color_light) # print(blue_converted_color_light) return red_converted_color_light / 255, green_converted_color_light / 255, blue_converted_color_light / 255
def cubemap_to_equirectangular(self, imageList, outputName): # Define the vertex shader vertex_shader = ''' in vec3 aVertexPosition; in vec2 aVertexTextureCoord; out vec2 vTexCoord; void main() { vTexCoord = aVertexTextureCoord; gl_Position = vec4(aVertexPosition, 1); } ''' # Define the fragment shader for the 360 degree conversion fragment_shader_360 = ''' #define PI 3.1415926535897932384626 // Input cubemap textures uniform sampler2D cubeLeftImage; uniform sampler2D cubeRightImage; uniform sampler2D cubeBottomImage; uniform sampler2D cubeTopImage; uniform sampler2D cubeBackImage; uniform sampler2D cubeFrontImage; in vec2 vTexCoord; out vec4 fragColor; void main() { // Calculate the pointing angle float azimuth = vTexCoord.x * PI; float elevation = vTexCoord.y * PI / 2.0; // Calculate the pointing vector vec3 pt; pt.x = cos(elevation) * sin(azimuth); pt.y = sin(elevation); pt.z = cos(elevation) * cos(azimuth); // Select the correct pixel if ((abs(pt.x) >= abs(pt.y)) && (abs(pt.x) >= abs(pt.z))) { if (pt.x <= 0.0) { fragColor = texture(cubeLeftImage, vec2(((-pt.z/pt.x)+1.0)/2.0,((-pt.y/pt.x)+1.0)/2.0)); } else { fragColor = texture(cubeRightImage, vec2(((-pt.z/pt.x)+1.0)/2.0,((pt.y/pt.x)+1.0)/2.0)); } } else if (abs(pt.y) >= abs(pt.z)) { if (pt.y <= 0.0) { fragColor = texture(cubeBottomImage, vec2(((-pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/2.0)); } else { fragColor = texture(cubeTopImage, vec2(((pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/2.0)); } } else { if (pt.z <= 0.0) { fragColor = texture(cubeBackImage, vec2(((pt.x/pt.z)+1.0)/2.0,((-pt.y/pt.z)+1.0)/2.0)); } else { fragColor = texture(cubeFrontImage, vec2(((pt.x/pt.z)+1.0)/2.0,((pt.y/pt.z)+1.0)/2.0)); } } } ''' # Define the fragment shader for the 180 degree conversion fragment_shader_180 = ''' #define PI 3.1415926535897932384626 // Input cubemap textures uniform sampler2D cubeLeftImage; uniform sampler2D cubeRightImage; uniform sampler2D cubeBottomImage; uniform sampler2D cubeTopImage; uniform sampler2D cubeFrontImage; in vec2 vTexCoord; out vec4 fragColor; void main() {{ // Calculate the pointing angle float fovd = {0}; float fovfrac = fovd/360.0; float sidefrac = (fovd-90.0)/180; float azimuth = vTexCoord.x * PI * fovfrac; float elevation = vTexCoord.y * PI / 2.0; // Calculate the pointing vector vec3 pt; pt.x = cos(elevation) * sin(azimuth); pt.y = sin(elevation); pt.z = cos(elevation) * cos(azimuth); // Select the correct pixel if ((abs(pt.x) >= abs(pt.y)) && (abs(pt.x) >= abs(pt.z))) {{ if (pt.x <= 0.0) {{ fragColor = texture(cubeLeftImage, vec2((((-pt.z/pt.x))+(2.0*sidefrac-1.0))/(2.0*sidefrac),((-pt.y/pt.x)+1.0)/2.0)); }} else {{ fragColor = texture(cubeRightImage, vec2(((-pt.z/pt.x)+1.0)/(2.0*sidefrac),((pt.y/pt.x)+1.0)/2.0)); }} }} else if (abs(pt.y) >= abs(pt.z)) {{ if (pt.y <= 0.0) {{ fragColor = texture(cubeBottomImage, vec2(((-pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+(2.0*sidefrac-1.0))/(2.0*sidefrac))); }} else {{ fragColor = texture(cubeTopImage, vec2(((pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/(2.0*sidefrac))); }} }} else {{ fragColor = texture(cubeFrontImage, vec2(((pt.x/pt.z)+1.0)/2.0,((pt.y/pt.z)+1.0)/2.0)); }} }} '''.format(self.FOV) # Define the fragment shader for the dome conversion fragment_shader_dome = ''' #define PI 3.1415926535897932384626 // Input cubemap textures uniform sampler2D cubeLeftImage; uniform sampler2D cubeRightImage; uniform sampler2D cubeBottomImage; uniform sampler2D cubeTopImage; uniform sampler2D cubeFrontImage; uniform sampler2D cubeBackImage; in vec2 vTexCoord; out vec4 fragColor; void main() {{ float fovd = {0}; float fovfrac = fovd/360.0; float sidefrac = (fovd-90.0)/180; float hfov = fovfrac*PI; vec2 d = vTexCoord.xy; float r = length( d ); if( r > 1.0 ) {{ fragColor = vec4(0.0, 0.0, 0.0, 1.0); return; }} vec2 dunit = normalize( d ); float phi = r * hfov; vec3 pt = vec3( 1.0, 1.0, 1.0 ); pt.xy = dunit * sin( phi ); pt.z = cos( phi ); // Select the correct pixel // Select the correct pixel if ((abs(pt.x) >= abs(pt.y)) && (abs(pt.x) >= abs(pt.z))) {{ if (pt.x <= 0.0) {{ fragColor = texture(cubeLeftImage, vec2((((-pt.z/pt.x))+(2.0*sidefrac-1.0))/(2.0*sidefrac),((-pt.y/pt.x)+1.0)/2.0)); }} else {{ fragColor = texture(cubeRightImage, vec2(((-pt.z/pt.x)+1.0)/(2.0*sidefrac),((pt.y/pt.x)+1.0)/2.0)); }} }} else if (abs(pt.y) >= abs(pt.z)) {{ if (pt.y <= 0.0) {{ fragColor = texture(cubeBottomImage, vec2(((-pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+(2.0*sidefrac-1.0))/(2.0*sidefrac))); }} else {{ fragColor = texture(cubeTopImage, vec2(((pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/(2.0*sidefrac))); }} }} else {{ if (pt.z <= 0.0) {{ fragColor = texture(cubeBackImage, vec2(((pt.x/pt.z)+1.0)/2.0,((-pt.y/pt.z)+1.0)/2.0)); }} else {{ fragColor = texture(cubeFrontImage, vec2(((pt.x/pt.z)+1.0)/2.0,((pt.y/pt.z)+1.0)/2.0)); }} }} }} '''.format(self.FOV) # Generate the OpenGL shader pos = [ (-1.0, -1.0, -1.0), # left, bottom, back (-1.0, 1.0, -1.0), # left, top, back (1.0, -1.0, -1.0), # right, bottom, back (1.0, 1.0, -1.0) ] # right, top, back coords = [ (-1.0, -1.0), # left, bottom (-1.0, 1.0), # left, top (1.0, -1.0), # right, bottom (1.0, 1.0) ] # right, top vertexIndices = [(0, 3, 1), (3, 0, 2)] if self.is_dome: shader = gpu.types.GPUShader(vertex_shader, fragment_shader_dome) else: if self.no_back_image: shader = gpu.types.GPUShader(vertex_shader, fragment_shader_180) else: shader = gpu.types.GPUShader(vertex_shader, fragment_shader_360) batch = batch_for_shader(shader, 'TRIS', {"aVertexPosition": pos,\ "aVertexTextureCoord": coords},\ indices=vertexIndices) # Change the color space of all of the images to Linear # and load them into OpenGL textures imageLeft = imageList[0] imageLeft.colorspace_settings.name = 'Linear' imageLeft.gl_load() imageRight = imageList[1] imageRight.colorspace_settings.name = 'Linear' imageRight.gl_load() imageBottom = imageList[2] imageBottom.colorspace_settings.name = 'Linear' imageBottom.gl_load() imageTop = imageList[3] imageTop.colorspace_settings.name = 'Linear' imageTop.gl_load() imageFront = imageList[4] imageFront.colorspace_settings.name = 'Linear' imageFront.gl_load() if not self.no_back_image: imageBack = imageList[5] imageBack.colorspace_settings.name = 'Linear' imageBack.gl_load() # set the size of the final image width = self.image_size[0] height = self.image_size[1] # Create an offscreen render buffer and texture offscreen = gpu.types.GPUOffScreen(width, height) with offscreen.bind(): bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) shader.bind() # Bind all of the cubemap textures and enable correct filtering and wrapping # to prevent seams bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageLeft.bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) shader.uniform_int("cubeLeftImage", 0) bgl.glActiveTexture(bgl.GL_TEXTURE1) bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageRight.bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) shader.uniform_int("cubeRightImage", 1) bgl.glActiveTexture(bgl.GL_TEXTURE2) bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageBottom.bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) shader.uniform_int("cubeBottomImage", 2) bgl.glActiveTexture(bgl.GL_TEXTURE3) bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageTop.bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) shader.uniform_int("cubeTopImage", 3) bgl.glActiveTexture(bgl.GL_TEXTURE4) bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageFront.bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) shader.uniform_int("cubeFrontImage", 4) if not self.no_back_image: bgl.glActiveTexture(bgl.GL_TEXTURE5) bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageBack.bindcode) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) shader.uniform_int("cubeBackImage", 5) # Bind the resulting texture bgl.glActiveTexture(bgl.GL_TEXTURE6) bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) # Render the image batch.draw(shader) # Unload the textures imageLeft.gl_free() imageRight.gl_free() imageBottom.gl_free() imageTop.gl_free() imageFront.gl_free() if not self.no_back_image: imageBack.gl_free() # Read the resulting pixels into a buffer buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4) bgl.glGetTexImage(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # Unload the offscreen texture offscreen.free() # Remove the cubemap textures: for image in imageList: bpy.data.images.remove(image) # Copy the pixels from the buffer to an image object if not outputName in bpy.data.images.keys(): bpy.data.images.new(outputName, width, height) imageRes = bpy.data.images[outputName] imageRes.scale(width, height) imageRes.pixels = buffer return imageRes