Commit: 5350015d519ec299b9a8937e4e035fe405001d8d Author: Julian Eisel Date: Wed Aug 7 11:52:30 2019 +0200 Branches: soc-2019-openxr https://developer.blender.org/rB5350015d519ec299b9a8937e4e035fe405001d8d
Fix dark VR rendering on Windows Mixed Reality by appyling SRGB OETF Discussed this in length with @sobotka, and it seems WMR has an utterly broken pixel color pipeline. So we apply a SRGB OETF for this specific runtime to compensate. =================================================================== M intern/ghost/GHOST_Types.h M intern/ghost/intern/GHOST_XrSession.cpp M source/blender/gpu/GPU_shader.h M source/blender/gpu/GPU_viewport.h M source/blender/gpu/intern/gpu_shader.c M source/blender/gpu/intern/gpu_viewport.c M source/blender/windowmanager/intern/wm_draw.c M source/blender/windowmanager/intern/wm_xr.c M source/blender/windowmanager/wm.h =================================================================== diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index b7ccb59a3a5..ede2de1f6da 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -615,6 +615,9 @@ typedef struct { float angle_left, angle_right; float angle_up, angle_down; } fov; + + /** Set if the buffer should be submitted with a srgb transfer applied. */ + char expects_srgb_buffer; } GHOST_XrDrawViewInfo; typedef struct { diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp index dee175632b5..f2f01a9b354 100644 --- a/intern/ghost/intern/GHOST_XrSession.cpp +++ b/intern/ghost/intern/GHOST_XrSession.cpp @@ -418,6 +418,13 @@ static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawVi r_info.fov.angle_down = view.fov.angleDown; } +bool ghost_xr_draw_view_expects_srgb_buffer(const GHOST_XrContext *context) +{ + /* WMR seems to be faulty and doesn't do OETF transform correctly. So expect a SRGB buffer to + * compensate. */ + return context->getOpenXRRuntimeID() == OPENXR_RUNTIME_WMR; +} + void GHOST_XrSession::drawView(XrSwapchain swapchain, XrCompositionLayerProjectionView &proj_layer_view, XrView &view, @@ -447,6 +454,7 @@ void GHOST_XrSession::drawView(XrSwapchain swapchain, swapchain_image = m_oxr->swapchain_images[swapchain][swapchain_idx]; + draw_view_info.expects_srgb_buffer = ghost_xr_draw_view_expects_srgb_buffer(m_context); draw_view_info.ofsx = proj_layer_view.subImage.imageRect.offset.x; draw_view_info.ofsy = proj_layer_view.subImage.imageRect.offset.y; draw_view_info.width = proj_layer_view.subImage.imageRect.extent.width; diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 124f1f1ff8a..01b679453a7 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -185,6 +185,7 @@ typedef enum eGPUBuiltinShader { GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR, /* basic image drawing */ GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB, + GPU_SHADER_2D_IMAGE_RECT_LINEAR_TO_SRGB, GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR, GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR, /** diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index e7600279d6f..00e6e018761 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -93,6 +93,7 @@ GPUViewport *GPU_viewport_create(void); void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect); void GPU_viewport_unbind(GPUViewport *viewport); void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect); +void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, const rcti *rect, bool to_srgb); void GPU_viewport_free(GPUViewport *viewport); GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 3e930d19696..35a479b05c0 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -1015,6 +1015,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { .vert = datatoc_gpu_shader_2D_image_vert_glsl, .frag = datatoc_gpu_shader_image_linear_frag_glsl, }, + [GPU_SHADER_2D_IMAGE_RECT_LINEAR_TO_SRGB] = + { + .vert = datatoc_gpu_shader_2D_image_rect_vert_glsl, + .frag = datatoc_gpu_shader_image_linear_frag_glsl, + }, [GPU_SHADER_2D_IMAGE] = { .vert = datatoc_gpu_shader_2D_image_vert_glsl, diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index e3c13b0ec14..9d87922aa3c 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -505,7 +505,7 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) } } -void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) +void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, const rcti *rect, bool to_srgb) { DefaultFramebufferList *dfbl = viewport->fbl; @@ -532,7 +532,8 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) float y1 = rect->ymin; float y2 = rect->ymin + h; - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); + GPUShader *shader = GPU_shader_get_builtin_shader( + to_srgb ? GPU_SHADER_2D_IMAGE_RECT_LINEAR_TO_SRGB : GPU_SHADER_2D_IMAGE_RECT_COLOR); GPU_shader_bind(shader); GPU_texture_bind(color, 0); @@ -550,6 +551,11 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) GPU_texture_unbind(color); } +void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) +{ + GPU_viewport_draw_to_screen_ex(viewport, rect, false); +} + void GPU_viewport_unbind(GPUViewport *UNUSED(viewport)) { GPU_framebuffer_restore(); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index b0b89fa074f..3951644ec81 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -748,13 +748,13 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view) } } -void wm_draw_upside_down(int sizex, int sizey) +void wm_draw_upside_down(int sizex, int sizey, bool to_srgb) { GPUVertFormat *format = immVertexFormat(); uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_IMAGE); + immBindBuiltinProgram(to_srgb ? GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB : GPU_SHADER_2D_IMAGE); /* wmOrtho for the screen has this same offset */ const float halfx = GLA_PIXEL_OFS / sizex; @@ -804,7 +804,7 @@ static void wm_draw_window_upside_down_onscreen(bContext *C, wmWindow *win) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); - wm_draw_upside_down(win->sizex, win->sizey); + wm_draw_upside_down(win->sizex, win->sizey, false); glBindTexture(GL_TEXTURE_2D, 0); diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c index 22e6fb7b3bf..82d17b6cd6e 100644 --- a/source/blender/windowmanager/intern/wm_xr.c +++ b/source/blender/windowmanager/intern/wm_xr.c @@ -337,11 +337,11 @@ static GHOST_ContextHandle wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view GPU_depth_test(false); wmViewport(&rect); - GPU_viewport_draw_to_screen(viewport, &rect); + GPU_viewport_draw_to_screen_ex(viewport, &rect, draw_view->expects_srgb_buffer); if (g_xr_surface->secondary_ghost_ctx && GHOST_isUpsideDownContext(g_xr_surface->secondary_ghost_ctx)) { GPU_texture_bind(texture, 0); - wm_draw_upside_down(draw_view->width, draw_view->height); + wm_draw_upside_down(draw_view->width, draw_view->height, draw_view->expects_srgb_buffer); GPU_texture_unbind(texture); } GPU_viewport_unbind(viewport); diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index f28552916f2..a98c47b11c2 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -98,7 +98,7 @@ void wm_open_init_use_scripts(wmOperator *op, bool use_prefs); /* wm_draw.c */ struct GPUOffScreen; void wm_draw_offscreen_texture_parameters(struct GPUOffScreen *offscreen); -void wm_draw_upside_down(int sizex, int sizey); +void wm_draw_upside_down(int sizex, int sizey, bool to_srgb); #ifdef WITH_OPENXR /* wm_xr.c */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs