0
$\begingroup$

I'm working on a blender plugins which pre render probes and pack data in cubemap sheets. Is is here : https://github.com/gillesboisson/blender-probes-export

Is render probes equi panorama using cycle engine and compute / pack data using blender GPU API. I have some issue with hdr / open exr packing as I don't proper result in pack phase.

I tried using Half float as color depth (same as rendered HDR), Commented code illustrate the SDR version (work but seems to have color curve issue).

It would be a great help if someone has an example on working solution, all example I found was for a RGBA8 Uint image export

Here is how I do it

 export_directory = context.scene.probes_export.export_directory_path

    if prob_object == None:
        prob_object = context.object

    data = load_probe_json_render_data(export_directory, global_probe_render_name)

    if data == None:
        return None

    cubemap_size = 128
    nb_maps = 1
    max_texture_size = cubemap_size * 3
    nb_face_x = 3
    nb_face_y = 2

    (
        texture_width,
        texture_height,
        nb_cluster_x,
        nb_cluster_y,
        cluster_width,
        cluster_height,
    ) = get_cubemap_pack_layout(
        cubemap_size, nb_maps, max_texture_size, nb_face_x, nb_face_y
    )

    shader = cubemap_shader
    offscreen = GPUOffScreen(
        width=texture_width, height=texture_height, format="RGBA16F"
        # texture_width, texture_height
    )

    cached_probe_file = global_pano_file(
        context.scene.probes_export.export_directory_path
    )

    with offscreen.bind():
        fb = gpu.state.active_framebuffer_get()
        fb.clear(color=(0.0, 0.0, 0.0, 0.0))

        uvs = get_cubemap_pack_uvs(
            cubemap_size, 0, nb_maps, max_texture_size, nb_face_x, nb_face_y
        )
        map_normals = generate_cubemap_pack_normals(nb_maps)
        map_indices = generate_cubemap_quad_indices()

        map_image = bpy.data.images.load(cached_probe_file)
        texture = gpu.texture.from_image(map_image)
        shader.uniform_sampler("panorama", texture)

        map_uvs = uvs[0]
        batch: GPUBatch = batch_for_shader(
            shader,
            "TRIS",
            {"position": map_uvs, "normal": map_normals},
            indices=map_indices,
        )

        batch.draw(shader)

        bpy.data.images.remove(map_image)

        buffer = fb.read_color(0, 0, texture_width, texture_height, 4, 0, "FLOAT")
        # buffer = fb.read_color(0,0,texture_width,texture_height,4,0,'UBYTE')



    offscreen.free()
    # context.scene.render.image_settings.file_format = 'PNG'
    context.scene.render.image_settings.file_format = 'OPEN_EXR'
    image_name = global_probe_render_name

    if image_name in bpy.data.images:
        bpy.data.images.remove(bpy.data.images[image_name])
    
    bpy.data.images.new(image_name, texture_width, texture_height, alpha=False, float_buffer=True)

    
    image = bpy.data.images[image_name]
    image.file_format = 'OPEN_EXR'
    image.scale(texture_width, texture_height)
    buffer.dimensions = texture_width * texture_height * 4
    image.pixels = buffer
    # image.pixels = [v / 255 for v in buffer]
    
    output_file_path = export_directory + "/" + image_name + ".exr"
    # output_file_path = export_directory + "/" + image_name + ".png"
    image.save_render(output_file_path)

Here is simple version of fragment shader in case it helps

// Shader

"void main()"
        "{"
        "  vec3 normal = normalize(v_normal);"
        "  vec2 uv = sampleSphericalMap(normal);"
        "  vec4 color = texture(panorama, uv);"
        "  FragColor = color;"
        "};",

Regards

$\endgroup$

0

You must log in to answer this question.

Browse other questions tagged .