diff options
Diffstat (limited to 'source/blender/draw/modes')
28 files changed, 1255 insertions, 271 deletions
diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c index 3487ceba141..4deb4f86692 100644 --- a/source/blender/draw/modes/edit_armature_mode.c +++ b/source/blender/draw/modes/edit_armature_mode.c @@ -92,7 +92,9 @@ static void EDIT_ARMATURE_cache_init(void *vedata) { /* Non Meshes Pass (Camera, empties, lamps ...) */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE; + DRWState state = + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | + DRW_STATE_BLEND | DRW_STATE_WIRE; psl->relationship = DRW_pass_create("Bone Relationship Pass", state); /* Relationship Lines */ @@ -118,11 +120,16 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) static void EDIT_ARMATURE_draw_scene(void *vedata) { EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + + MULTISAMPLE_SYNC_ENABLE(dfbl) DRW_draw_pass(psl->bone_envelope); DRW_draw_pass(psl->bone_solid); DRW_draw_pass(psl->bone_wire); DRW_draw_pass(psl->relationship); + + MULTISAMPLE_SYNC_DISABLE(dfbl) } #if 0 @@ -145,5 +152,6 @@ DrawEngineType draw_engine_edit_armature_type = { &EDIT_ARMATURE_cache_populate, NULL, NULL, - &EDIT_ARMATURE_draw_scene + &EDIT_ARMATURE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index dc81725d19a..1d542fc8e7e 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -264,7 +264,9 @@ static void EDIT_CURVE_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - UNUSED_VARS(fbl, dfbl, dtxl); + UNUSED_VARS(fbl, dtxl); + + MULTISAMPLE_SYNC_ENABLE(dfbl) /* Show / hide entire passes, swap framebuffers ... whatever you fancy */ /* @@ -280,6 +282,8 @@ static void EDIT_CURVE_draw_scene(void *vedata) DRW_draw_pass(psl->overlay_edge_pass); DRW_draw_pass(psl->overlay_vert_pass); + MULTISAMPLE_SYNC_DISABLE(dfbl) + /* If you changed framebuffer, double check you rebind * the default one with its textures attached before finishing */ } @@ -325,5 +329,6 @@ DrawEngineType draw_engine_edit_curve_type = { &EDIT_CURVE_cache_populate, &EDIT_CURVE_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &EDIT_CURVE_draw_scene + &EDIT_CURVE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c index b3a20075f0e..675ea925a39 100644 --- a/source/blender/draw/modes/edit_lattice_mode.c +++ b/source/blender/draw/modes/edit_lattice_mode.c @@ -144,7 +144,7 @@ static void EDIT_LATTICE_engine_init(void *vedata) */ if (!e_data.wire_sh) { - e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); + e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR); } if (!e_data.overlay_vert_sh) { @@ -177,6 +177,8 @@ static void EDIT_LATTICE_cache_init(void *vedata) "Lattice Verts", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_POINT); stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->vert_pass); + + DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", globals_ubo); } } @@ -196,7 +198,7 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob) /* Get geometry cache */ struct Gwn_Batch *geom; - geom = DRW_cache_lattice_wire_get(ob); + geom = DRW_cache_lattice_wire_get(ob, true); DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); geom = DRW_cache_lattice_vert_overlay_get(ob); @@ -225,7 +227,9 @@ static void EDIT_LATTICE_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - UNUSED_VARS(fbl, dfbl, dtxl); + UNUSED_VARS(fbl, dtxl); + + MULTISAMPLE_SYNC_ENABLE(dfbl) /* Show / hide entire passes, swap framebuffers ... whatever you fancy */ /* @@ -240,6 +244,8 @@ static void EDIT_LATTICE_draw_scene(void *vedata) DRW_draw_pass(psl->wire_pass); DRW_draw_pass(psl->vert_pass); + MULTISAMPLE_SYNC_DISABLE(dfbl) + /* If you changed framebuffer, double check you rebind * the default one with its textures attached before finishing */ } @@ -286,5 +292,6 @@ DrawEngineType draw_engine_edit_lattice_type = { &EDIT_LATTICE_cache_populate, &EDIT_LATTICE_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &EDIT_LATTICE_draw_scene + &EDIT_LATTICE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index c06a2976ac7..08310d75a57 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -152,14 +152,19 @@ static void EDIT_MESH_engine_init(void *vedata) datatoc_edit_mesh_overlay_vert_glsl, datatoc_edit_mesh_overlay_geom_tri_glsl, datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, "#define EDGE_FIX\n"); + datatoc_common_globals_lib_glsl, + "#define EDGE_FIX\n" + "#define ANTI_ALIASING\n" + "#define VERTEX_FACING"); } if (!e_data.overlay_tri_fast_sh) { e_data.overlay_tri_fast_sh = DRW_shader_create_with_lib( datatoc_edit_mesh_overlay_vert_glsl, datatoc_edit_mesh_overlay_geom_tri_glsl, datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, NULL); + datatoc_common_globals_lib_glsl, + "#define ANTI_ALIASING\n" + "#define VERTEX_FACING\n"); } if (!e_data.overlay_tri_vcol_sh) { e_data.overlay_tri_vcol_sh = DRW_shader_create_with_lib( @@ -168,7 +173,9 @@ static void EDIT_MESH_engine_init(void *vedata) datatoc_edit_mesh_overlay_frag_glsl, datatoc_common_globals_lib_glsl, "#define EDGE_FIX\n" - "#define VERTEX_SELECTION\n"); + "#define VERTEX_SELECTION\n" + "#define ANTI_ALIASING\n" + "#define VERTEX_FACING\n"); } if (!e_data.overlay_tri_vcol_fast_sh) { e_data.overlay_tri_vcol_fast_sh = DRW_shader_create_with_lib( @@ -176,14 +183,18 @@ static void EDIT_MESH_engine_init(void *vedata) datatoc_edit_mesh_overlay_geom_tri_glsl, datatoc_edit_mesh_overlay_frag_glsl, datatoc_common_globals_lib_glsl, - "#define VERTEX_SELECTION\n"); + "#define VERTEX_SELECTION\n" + "#define ANTI_ALIASING\n" + "#define VERTEX_FACING\n"); } if (!e_data.overlay_edge_sh) { e_data.overlay_edge_sh = DRW_shader_create_with_lib( datatoc_edit_mesh_overlay_vert_glsl, datatoc_edit_mesh_overlay_geom_edge_glsl, datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, NULL); + datatoc_common_globals_lib_glsl, + "#define ANTI_ALIASING\n" + "#define VERTEX_FACING\n"); } if (!e_data.overlay_edge_vcol_sh) { e_data.overlay_edge_vcol_sh = DRW_shader_create_with_lib( @@ -191,7 +202,8 @@ static void EDIT_MESH_engine_init(void *vedata) datatoc_edit_mesh_overlay_geom_edge_glsl, datatoc_edit_mesh_overlay_frag_glsl, datatoc_common_globals_lib_glsl, - "#define VERTEX_SELECTION\n"); + "#define VERTEX_SELECTION\n" + "#define VERTEX_FACING\n"); } if (!e_data.overlay_vert_sh) { e_data.overlay_vert_sh = DRW_shader_create_with_lib( @@ -204,7 +216,8 @@ static void EDIT_MESH_engine_init(void *vedata) e_data.overlay_facedot_sh = DRW_shader_create_with_lib( datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL, datatoc_edit_mesh_overlay_facedot_frag_glsl, - datatoc_common_globals_lib_glsl, NULL); + datatoc_common_globals_lib_glsl, + "#define VERTEX_FACING\n"); } if (!e_data.overlay_mix_sh) { e_data.overlay_mix_sh = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL); @@ -580,5 +593,6 @@ DrawEngineType draw_engine_edit_mesh_type = { &EDIT_MESH_cache_populate, NULL, NULL, - &EDIT_MESH_draw_scene + &EDIT_MESH_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c index 4e9e1cb5b56..202e520193b 100644 --- a/source/blender/draw/modes/edit_metaball_mode.c +++ b/source/blender/draw/modes/edit_metaball_mode.c @@ -264,5 +264,6 @@ DrawEngineType draw_engine_edit_metaball_type = { &EDIT_METABALL_cache_populate, &EDIT_METABALL_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &EDIT_METABALL_draw_scene + &EDIT_METABALL_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c index c8dbbd90754..e99973144aa 100644 --- a/source/blender/draw/modes/edit_surface_mode.c +++ b/source/blender/draw/modes/edit_surface_mode.c @@ -264,5 +264,6 @@ DrawEngineType draw_engine_edit_surface_type = { &EDIT_SURFACE_cache_populate, &EDIT_SURFACE_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &EDIT_SURFACE_draw_scene + &EDIT_SURFACE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index 938ab2f3fbc..476a2ab9ac2 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -307,5 +307,6 @@ DrawEngineType draw_engine_edit_text_type = { &EDIT_TEXT_cache_populate, &EDIT_TEXT_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &EDIT_TEXT_draw_scene + &EDIT_TEXT_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index f6220a70f9c..db0ac5a1d11 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -43,12 +43,12 @@ #include "BKE_camera.h" #include "BKE_curve.h" #include "BKE_global.h" +#include "BKE_object.h" #include "BKE_particle.h" #include "BKE_image.h" #include "BKE_texture.h" #include "ED_view3d.h" -#include "ED_view3d.h" #include "GPU_shader.h" #include "GPU_texture.h" @@ -70,11 +70,15 @@ extern char datatoc_object_grid_frag_glsl[]; extern char datatoc_object_grid_vert_glsl[]; extern char datatoc_object_empty_image_frag_glsl[]; extern char datatoc_object_empty_image_vert_glsl[]; +extern char datatoc_object_lightprobe_grid_vert_glsl[]; extern char datatoc_object_particle_prim_vert_glsl[]; extern char datatoc_object_particle_prim_frag_glsl[]; extern char datatoc_object_particle_dot_vert_glsl[]; extern char datatoc_object_particle_dot_frag_glsl[]; extern char datatoc_common_globals_lib_glsl[]; +extern char datatoc_common_fxaa_lib_glsl[]; +extern char datatoc_gpu_shader_fullscreen_vert_glsl[]; +extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; /* *********** LISTS *********** */ typedef struct OBJECT_PassList { @@ -83,17 +87,14 @@ typedef struct OBJECT_PassList { struct DRWPass *outlines; struct DRWPass *outlines_search; struct DRWPass *outlines_expand; - struct DRWPass *outlines_fade1; - struct DRWPass *outlines_fade2; - struct DRWPass *outlines_fade3; - struct DRWPass *outlines_fade4; - struct DRWPass *outlines_fade5; + struct DRWPass *outlines_bleed; struct DRWPass *outlines_resolve; struct DRWPass *grid; struct DRWPass *bone_solid; struct DRWPass *bone_wire; struct DRWPass *bone_envelope; struct DRWPass *particle; + struct DRWPass *lightprobes; /* use for empty/background images */ struct DRWPass *reference_image; } OBJECT_PassList; @@ -117,7 +118,7 @@ typedef struct OBJECT_Data { /* *********** STATIC *********** */ -typedef struct OBJECT_PrivateData{ +typedef struct OBJECT_PrivateData { /* Empties */ DRWShadingGroup *plain_axes; DRWShadingGroup *cube; @@ -143,8 +144,10 @@ typedef struct OBJECT_PrivateData{ /* Speaker */ DRWShadingGroup *speaker; - /* Speaker */ - DRWShadingGroup *probe; + /* Probe */ + DRWShadingGroup *probe_cube; + DRWShadingGroup *probe_planar; + DRWShadingGroup *probe_grid; /* Lamps */ DRWShadingGroup *lamp_center; @@ -190,6 +193,10 @@ typedef struct OBJECT_PrivateData{ DRWShadingGroup *outlines_select_group; DRWShadingGroup *outlines_transform; + /* Lightprobes */ + DRWShadingGroup *lightprobes_cube; + DRWShadingGroup *lightprobes_planar; + /* Wire */ DRWShadingGroup *wire; DRWShadingGroup *wire_active; @@ -202,6 +209,7 @@ typedef struct OBJECT_PrivateData{ static struct { /* fullscreen shaders */ GPUShader *outline_resolve_sh; + GPUShader *outline_resolve_aa_sh; GPUShader *outline_detect_sh; GPUShader *outline_fade_sh; @@ -212,6 +220,7 @@ static struct { GPUShader *part_dot_sh; GPUShader *part_prim_sh; GPUShader *part_axis_sh; + GPUShader *lightprobe_grid_sh; float camera_pos[3]; float screenvecs[3][4]; float grid_settings[5]; @@ -223,6 +232,7 @@ static struct { int zneg_flag; float zplane_normal[3]; float zplane_axes[3]; + float inv_viewport_size[2]; bool draw_grid; /* Temp buffer textures */ struct GPUTexture *outlines_depth_tx; @@ -273,6 +283,15 @@ static void OBJECT_engine_init(void *vedata) e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL); } + if (!e_data.outline_resolve_aa_sh) { + e_data.outline_resolve_aa_sh = DRW_shader_create_with_lib( + datatoc_gpu_shader_fullscreen_vert_glsl, NULL, + datatoc_object_outline_resolve_frag_glsl, + datatoc_common_fxaa_lib_glsl, + "#define FXAA_ALPHA\n" + "#define USE_FXAA\n"); + } + if (!e_data.outline_detect_sh) { e_data.outline_detect_sh = DRW_shader_create_fullscreen(datatoc_object_outline_detect_frag_glsl, NULL); } @@ -304,15 +323,24 @@ static void OBJECT_engine_init(void *vedata) } if (!e_data.part_prim_sh) { - e_data.part_prim_sh = DRW_shader_create(datatoc_object_particle_prim_vert_glsl, NULL, datatoc_object_particle_prim_frag_glsl, NULL); + e_data.part_prim_sh = DRW_shader_create( + datatoc_object_particle_prim_vert_glsl, NULL, datatoc_object_particle_prim_frag_glsl, NULL); } if (!e_data.part_axis_sh) { - e_data.part_axis_sh = DRW_shader_create(datatoc_object_particle_prim_vert_glsl, NULL, datatoc_object_particle_prim_frag_glsl, "#define USE_AXIS\n"); + e_data.part_axis_sh = DRW_shader_create( + datatoc_object_particle_prim_vert_glsl, NULL, datatoc_object_particle_prim_frag_glsl, + "#define USE_AXIS\n"); } if (!e_data.part_dot_sh) { - e_data.part_dot_sh = DRW_shader_create(datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL); + e_data.part_dot_sh = DRW_shader_create( + datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL); + } + + if (!e_data.lightprobe_grid_sh) { + e_data.lightprobe_grid_sh = DRW_shader_create( + datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_uniform_color_frag_glsl, NULL); } { @@ -458,7 +486,8 @@ static void OBJECT_engine_init(void *vedata) /* Persp : If camera is below floor plane, we switch clipping * Ortho : If eye vector is looking up, we switch clipping */ if (((winmat[3][3] == 0.0f) && (e_data.camera_pos[2] > 0.0f)) || - ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) { + ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) + { e_data.zpos_flag |= CLIP_ZPOS; e_data.zneg_flag |= CLIP_ZNEG; } @@ -490,13 +519,17 @@ static void OBJECT_engine_init(void *vedata) e_data.grid_settings[1] = grid_res; /* gridResolution */ e_data.grid_settings[2] = grid_scale; /* gridScale */ e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */ - e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / log(v3d->gridsubdiv) : 0.0; /* 1/log(gridSubdiv) */ + e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / logf(v3d->gridsubdiv) : 0.0f; /* 1/log(gridSubdiv) */ } + + copy_v2_v2(e_data.inv_viewport_size, DRW_viewport_size_get()); + invert_v2(e_data.inv_viewport_size); } static void OBJECT_engine_free(void) { DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh); + DRW_SHADER_FREE_SAFE(e_data.outline_resolve_aa_sh); DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh); DRW_SHADER_FREE_SAFE(e_data.outline_fade_sh); DRW_SHADER_FREE_SAFE(e_data.object_empty_image_sh); @@ -505,6 +538,7 @@ static void OBJECT_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.part_prim_sh); DRW_SHADER_FREE_SAFE(e_data.part_axis_sh); DRW_SHADER_FREE_SAFE(e_data.part_dot_sh); + DRW_SHADER_FREE_SAFE(e_data.lightprobe_grid_sh); } static DRWShadingGroup *shgroup_outline(DRWPass *pass, const float col[4], GPUShader *sh) @@ -690,7 +724,7 @@ static void OBJECT_cache_init(void *vedata) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE; - psl->outlines = DRW_pass_create("Outlines Pass", state); + psl->outlines = DRW_pass_create("Outlines Depth Pass", state); GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); @@ -707,19 +741,24 @@ static void OBJECT_cache_init(void *vedata) } { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; + psl->lightprobes = DRW_pass_create("Object Probe Pass", state); + + /* Cubemap */ + stl->g_data->lightprobes_cube = shgroup_instance(psl->lightprobes, DRW_cache_sphere_get()); + + /* Planar */ + stl->g_data->lightprobes_planar = shgroup_instance(psl->lightprobes, DRW_cache_quad_get()); + } + + { DRWState state = DRW_STATE_WRITE_COLOR; struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); static float alphaOcclu = 0.35f; - static float one = 1.0f; - static float alpha1 = 5.0f / 6.0f; - static float alpha2 = 4.0f / 5.0f; - static float alpha3 = 3.0f / 4.0f; - static float alpha4 = 2.0f / 3.0f; - static float alpha5 = 1.0f / 2.0f; static bool bTrue = true; static bool bFalse = false; - psl->outlines_search = DRW_pass_create("Outlines Expand Pass", state); + psl->outlines_search = DRW_pass_create("Outlines Detect Pass", state); DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_detect_sh, psl->outlines_search); DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx); @@ -732,53 +771,13 @@ static void OBJECT_cache_init(void *vedata) grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_expand); DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_blur_tx); - DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx); - DRW_shgroup_uniform_float(grp, "alpha", &one, 1); DRW_shgroup_uniform_bool(grp, "doExpand", &bTrue, 1); DRW_shgroup_call_add(grp, quad, NULL); - psl->outlines_fade1 = DRW_pass_create("Outlines Fade 1 Pass", state); + psl->outlines_bleed = DRW_pass_create("Outlines Bleed Pass", state); - grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade1); + grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_bleed); DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx); - DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx); - DRW_shgroup_uniform_float(grp, "alpha", &alpha1, 1); - DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1); - DRW_shgroup_call_add(grp, quad, NULL); - - psl->outlines_fade2 = DRW_pass_create("Outlines Fade 2 Pass", state); - - grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade2); - DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_blur_tx); - DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx); - DRW_shgroup_uniform_float(grp, "alpha", &alpha2, 1); - DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1); - DRW_shgroup_call_add(grp, quad, NULL); - - psl->outlines_fade3 = DRW_pass_create("Outlines Fade 3 Pass", state); - - grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade3); - DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx); - DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx); - DRW_shgroup_uniform_float(grp, "alpha", &alpha3, 1); - DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1); - DRW_shgroup_call_add(grp, quad, NULL); - - psl->outlines_fade4 = DRW_pass_create("Outlines Fade 4 Pass", state); - - grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade4); - DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_blur_tx); - DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx); - DRW_shgroup_uniform_float(grp, "alpha", &alpha4, 1); - DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1); - DRW_shgroup_call_add(grp, quad, NULL); - - psl->outlines_fade5 = DRW_pass_create("Outlines Fade 5 Pass", state); - - grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade5); - DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx); - DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx); - DRW_shgroup_uniform_float(grp, "alpha", &alpha5, 1); DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1); DRW_shgroup_call_add(grp, quad, NULL); } @@ -789,8 +788,9 @@ static void OBJECT_cache_init(void *vedata) struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); - DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_sh, psl->outlines_resolve); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_aa_sh, psl->outlines_resolve); DRW_shgroup_uniform_buffer(grp, "outlineBluredColor", &e_data.outlines_blur_tx); + DRW_shgroup_uniform_vec2(grp, "rcpDimensions", e_data.inv_viewport_size, 1); DRW_shgroup_call_add(grp, quad, NULL); } @@ -821,12 +821,14 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1); DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.grid_normal, 1); DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.grid_axes, 1); + DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); DRW_shgroup_call_add(grp, quad, mat); grp = DRW_shgroup_create(e_data.grid_sh, psl->grid); DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1); DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.zplane_normal, 1); DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1); + DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); DRW_shgroup_call_add(grp, quad, mat); } @@ -907,9 +909,16 @@ static void OBJECT_cache_init(void *vedata) stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom); /* Probe */ - static float probeSize = 10.0f; - geom = DRW_cache_lightprobe_get(); - stl->g_data->probe = shgroup_instance_screenspace(psl->non_meshes, geom, &probeSize); + static float probeSize = 14.0f; + geom = DRW_cache_lightprobe_cube_get(); + stl->g_data->probe_cube = shgroup_instance_screenspace(psl->non_meshes, geom, &probeSize); + + geom = DRW_cache_lightprobe_grid_get(); + stl->g_data->probe_grid = shgroup_instance_screenspace(psl->non_meshes, geom, &probeSize); + + static float probePlanarSize = 20.0f; + geom = DRW_cache_lightprobe_planar_get(); + stl->g_data->probe_planar = shgroup_instance_screenspace(psl->non_meshes, geom, &probePlanarSize); /* Camera */ geom = DRW_cache_camera_get(); @@ -1063,7 +1072,10 @@ static void OBJECT_cache_init(void *vedata) { /* Particle Pass */ - psl->particle = DRW_pass_create("Particle Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_POINT | DRW_STATE_BLEND); + psl->particle = DRW_pass_create( + "Particle Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | + DRW_STATE_POINT | DRW_STATE_BLEND); } { @@ -1131,7 +1143,7 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl size[0] = size[1] = blend; size[2] = 1.0f; size_to_mat4(sizemat, size); translate_m4(sizemat, 0.0f, 0.0f, -1.0f); - rotate_m4(sizemat, 'X', M_PI / 2.0f); + rotate_m4(sizemat, 'X', (float)(M_PI / 2)); mul_m4_m4m4(spotblendmat, shapemat, sizemat); if (la->mode & LA_SQUARE) { @@ -1408,31 +1420,117 @@ static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, SceneLayer DRW_shgroup_call_dynamic_add(stl->g_data->speaker, color, &one, ob->obmat); } -static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl) +typedef struct OBJECT_LightProbeEngineData { + float prb_mats[6][4][4]; + float probe_cube_mat[4][4]; + float draw_size; + float increment_x[3]; + float increment_y[3]; + float increment_z[3]; + float corner[3]; +} OBJECT_LightProbeEngineData; + +static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, SceneLayer *sl) { float *color; static float one = 1.0f; LightProbe *prb = (LightProbe *)ob->data; + bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0); DRW_object_wire_theme_get(ob, sl, &color); - DRW_shgroup_call_dynamic_add(stl->g_data->probe, ob->obmat[3], color); + OBJECT_LightProbeEngineData *prb_data; + OBJECT_LightProbeEngineData **prb_data_pt = (OBJECT_LightProbeEngineData **)DRW_object_engine_data_get(ob, &draw_engine_object_type, NULL); + if (*prb_data_pt == NULL) { + *prb_data_pt = MEM_mallocN(sizeof(OBJECT_LightProbeEngineData), "Probe Clip distances Matrices"); + } - float **prb_mats = (float **)DRW_object_engine_data_get(ob, &draw_engine_object_type, NULL); - if (*prb_mats == NULL) { - /* we need 6 matrices */ - *prb_mats = MEM_mallocN(sizeof(float) * 16 * 6, "Probe Clip distances Matrices"); + prb_data = *prb_data_pt; + + if ((DRW_state_is_select() || do_outlines) && ((prb->flag & LIGHTPROBE_FLAG_SHOW_DATA) != 0)) { + + if (prb->type == LIGHTPROBE_TYPE_GRID) { + /* Update transforms */ + float cell_dim[3], half_cell_dim[3]; + cell_dim[0] = 2.0f / (float)(prb->grid_resolution_x); + cell_dim[1] = 2.0f / (float)(prb->grid_resolution_y); + cell_dim[2] = 2.0f / (float)(prb->grid_resolution_z); + + mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f); + + /* First cell. */ + copy_v3_fl(prb_data->corner, -1.0f); + add_v3_v3(prb_data->corner, half_cell_dim); + mul_m4_v3(ob->obmat, prb_data->corner); + + /* Opposite neighbor cell. */ + copy_v3_fl3(prb_data->increment_x, cell_dim[0], 0.0f, 0.0f); + add_v3_v3(prb_data->increment_x, half_cell_dim); + add_v3_fl(prb_data->increment_x, -1.0f); + mul_m4_v3(ob->obmat, prb_data->increment_x); + sub_v3_v3(prb_data->increment_x, prb_data->corner); + + copy_v3_fl3(prb_data->increment_y, 0.0f, cell_dim[1], 0.0f); + add_v3_v3(prb_data->increment_y, half_cell_dim); + add_v3_fl(prb_data->increment_y, -1.0f); + mul_m4_v3(ob->obmat, prb_data->increment_y); + sub_v3_v3(prb_data->increment_y, prb_data->corner); + + copy_v3_fl3(prb_data->increment_z, 0.0f, 0.0f, cell_dim[2]); + add_v3_v3(prb_data->increment_z, half_cell_dim); + add_v3_fl(prb_data->increment_z, -1.0f); + mul_m4_v3(ob->obmat, prb_data->increment_z); + sub_v3_v3(prb_data->increment_z, prb_data->corner); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.lightprobe_grid_sh, psl->lightprobes, DRW_cache_sphere_get()); + /* Dummy call just to save select ID */ + DRW_shgroup_call_dynamic_add_empty(grp); + /* Then overide the instance count */ + DRW_shgroup_set_instance_count(grp, prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z); + DRW_shgroup_uniform_vec4(grp, "color", color, 1); + DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1); + DRW_shgroup_uniform_vec3(grp, "increment_x", prb_data->increment_x, 1); + DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1); + DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1); + DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1); + DRW_shgroup_uniform_float(grp, "sphere_size", &prb->data_draw_size, 1); + } + else if (prb->type == LIGHTPROBE_TYPE_CUBE) { + prb_data->draw_size = prb->data_draw_size * 0.1f; + unit_m4(prb_data->probe_cube_mat); + copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); + DRW_shgroup_call_dynamic_add(stl->g_data->lightprobes_cube, color, &prb_data->draw_size, prb_data->probe_cube_mat); + } + else { + prb_data->draw_size = 1.0f; + DRW_shgroup_call_dynamic_add(stl->g_data->lightprobes_planar, color, &prb_data->draw_size, ob->obmat); + } } + switch (prb->type) { + case LIGHTPROBE_TYPE_PLANAR: + DRW_shgroup_call_dynamic_add(stl->g_data->probe_planar, ob->obmat[3], color); + break; + case LIGHTPROBE_TYPE_GRID: + DRW_shgroup_call_dynamic_add(stl->g_data->probe_grid, ob->obmat[3], color); + break; + case LIGHTPROBE_TYPE_CUBE: + default: + DRW_shgroup_call_dynamic_add(stl->g_data->probe_cube, ob->obmat[3], color); + break; + } + + + if (prb->type == LIGHTPROBE_TYPE_PLANAR) { float (*mat)[4]; - mat = (float (*)[4])(*prb_mats); + mat = (float (*)[4])(prb_data->prb_mats[0]); copy_m4_m4(mat, ob->obmat); normalize_m4(mat); DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow, color, &ob->empty_drawsize, mat); DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow_line, color, &ob->empty_drawsize, mat); - mat = (float (*)[4])(*prb_mats + 16); + mat = (float (*)[4])(prb_data->prb_mats[1]); copy_m4_m4(mat, ob->obmat); zero_v3(mat[2]); @@ -1450,21 +1548,21 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, Object *ob, SceneLay } if (prb->type == LIGHTPROBE_TYPE_GRID || - prb->attenuation_type == LIGHTPROBE_SHAPE_BOX) + prb->attenuation_type == LIGHTPROBE_SHAPE_BOX) { DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &prb->distgridinf, ob->obmat); DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &prb->distfalloff, ob->obmat); } else if (prb->type == LIGHTPROBE_TYPE_PLANAR) { float (*rangemat)[4]; - rangemat = (float (*)[4])(*prb_mats + 32); + rangemat = (float (*)[4])(prb_data->prb_mats[2]); copy_m4_m4(rangemat, ob->obmat); normalize_v3(rangemat[2]); mul_v3_fl(rangemat[2], prb->distinf); DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, rangemat); - rangemat = (float (*)[4])(*prb_mats + 64); + rangemat = (float (*)[4])(prb_data->prb_mats[3]); copy_m4_m4(rangemat, ob->obmat); normalize_v3(rangemat[2]); mul_v3_fl(rangemat[2], prb->distfalloff); @@ -1492,10 +1590,10 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, Object *ob, SceneLay } if (prb->parallax_type == LIGHTPROBE_SHAPE_BOX) { - DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &dist, obmat); + DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, dist, obmat); } else { - DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &dist, obmat); + DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, dist, obmat); } } } @@ -1513,7 +1611,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, Object *ob, SceneLay for (int i = 0; i < 6; ++i) { float (*clipmat)[4]; - clipmat = (float (*)[4])(*prb_mats + 16 * i); + clipmat = (float (*)[4])(prb_data->prb_mats[i]); normalize_m4_m4(clipmat, ob->obmat); mul_m4_m4m4(clipmat, clipmat, cubefacemat[i]); @@ -1523,7 +1621,6 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, Object *ob, SceneLay } } } - DRW_shgroup_call_dynamic_add(stl->g_data->lamp_center_group, ob->obmat[3]); /* Line and point going to the ground */ if (prb->type == LIGHTPROBE_TYPE_CUBE) { @@ -1534,7 +1631,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, Object *ob, SceneLay static void DRW_shgroup_relationship_lines(OBJECT_StorageList *stl, Object *ob) { - if (ob->parent && ((ob->parent->base_flag & BASE_VISIBLED) != 0)) { + if (ob->parent && BKE_object_is_visible(ob->parent)) { DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->obmat[3]); DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->parent->obmat[3]); } @@ -1545,7 +1642,7 @@ static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob, Scene const bool is_library = ob->id.us > 1 || ID_IS_LINKED_DATABLOCK(ob); DRWShadingGroup *shgroup; - if (ob == OBACT_NEW) { + if (ob == OBACT_NEW(sl)) { shgroup = stl->g_data->center_active; } else if (ob->base_flag & BASE_SELECTED) { @@ -1606,19 +1703,22 @@ static void OBJECT_cache_populate_particles(Object *ob, DRW_shgroup_call_add(shgrp, geom, mat); break; case PART_DRAW_CROSS: - shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS)); + shgrp = DRW_shgroup_instance_create( + e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS)); DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp); DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1); DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1); break; case PART_DRAW_CIRC: - shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC)); + shgrp = DRW_shgroup_instance_create( + e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC)); DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp); DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1); DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[1], 1); break; case PART_DRAW_AXIS: - shgrp = DRW_shgroup_instance_create(e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS)); + shgrp = DRW_shgroup_instance_create( + e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS)); DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1); break; default: @@ -1642,10 +1742,14 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; - SceneLayer *sl = draw_ctx->sl; + SceneLayer *sl = draw_ctx->scene_layer; View3D *v3d = draw_ctx->v3d; int theme_id = TH_UNDEFINED; + if (!BKE_object_is_visible(ob)) { + return; + } + //CollectionEngineSettings *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, ""); //bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire"); @@ -1693,7 +1797,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) { Object *obedit = scene->obedit; if (ob != obedit) { - struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob); + struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, sl, NULL); } @@ -1730,7 +1834,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) DRW_shgroup_speaker(stl, ob, sl); break; case OB_LIGHTPROBE: - DRW_shgroup_lightprobe(stl, ob, sl); + DRW_shgroup_lightprobe(stl, psl, ob, sl); break; case OB_ARMATURE: { @@ -1776,23 +1880,17 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) } } -static void OBJECT_cache_finish(void *vedata) -{ - OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; - if (stl->g_data->image_plane_map) { - BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN); - } -} - static void OBJECT_draw_scene(void *vedata) { OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl; + OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; if (DRW_state_is_fbo()) { + DRW_stats_group_start("Outlines"); /* attach temp textures */ DRW_framebuffer_texture_attach(fbl->outlines, e_data.outlines_depth_tx, 0, 0); DRW_framebuffer_texture_attach(fbl->outlines, e_data.outlines_color_tx, 0, 0); @@ -1802,6 +1900,7 @@ static void OBJECT_draw_scene(void *vedata) DRW_framebuffer_bind(fbl->outlines); DRW_framebuffer_clear(true, true, false, clearcol, 1.0f); DRW_draw_pass(psl->outlines); + DRW_draw_pass(psl->lightprobes); /* detach textures */ DRW_framebuffer_texture_detach(e_data.outlines_depth_tx); @@ -1810,24 +1909,13 @@ static void OBJECT_draw_scene(void *vedata) DRW_framebuffer_bind(fbl->blur); DRW_draw_pass(psl->outlines_search); - /* Expand and fade gradually */ + /* Expand outline to form a 3px wide line */ DRW_framebuffer_bind(fbl->outlines); DRW_draw_pass(psl->outlines_expand); + /* Bleed color so the AA can do it's stuff */ DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_fade1); - - DRW_framebuffer_bind(fbl->outlines); - DRW_draw_pass(psl->outlines_fade2); - - DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_fade3); - - DRW_framebuffer_bind(fbl->outlines); - DRW_draw_pass(psl->outlines_fade4); - - DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_fade5); + DRW_draw_pass(psl->outlines_bleed); /* detach temp textures */ DRW_framebuffer_texture_detach(e_data.outlines_color_tx); @@ -1835,17 +1923,27 @@ static void OBJECT_draw_scene(void *vedata) /* restore main framebuffer */ DRW_framebuffer_bind(dfbl->default_fb); + DRW_stats_group_end(); + } + else if (DRW_state_is_select()) { + /* Render probes spheres/planes so we can select them. */ + DRW_draw_pass(psl->lightprobes); } + MULTISAMPLE_SYNC_ENABLE(dfbl) + /* This needs to be drawn after the oultine */ // DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */ DRW_draw_pass(psl->bone_wire); DRW_draw_pass(psl->bone_solid); DRW_draw_pass(psl->non_meshes); - DRW_draw_pass(psl->ob_center); DRW_draw_pass(psl->particle); DRW_draw_pass(psl->reference_image); + MULTISAMPLE_SYNC_DISABLE(dfbl) + + DRW_draw_pass(psl->ob_center); + if (!DRW_state_is_select()) { if (e_data.draw_grid) { DRW_draw_pass(psl->grid); @@ -1854,6 +1952,11 @@ static void OBJECT_draw_scene(void *vedata) /* Combine with scene buffer last */ DRW_draw_pass(psl->outlines_resolve); } + + /* This has to be freed only after drawing empties! */ + if (stl->g_data->image_plane_map) { + BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN); + } } void OBJECT_collection_settings_create(IDProperty *props) @@ -1875,7 +1978,8 @@ DrawEngineType draw_engine_object_type = { &OBJECT_engine_free, &OBJECT_cache_init, &OBJECT_cache_populate, - &OBJECT_cache_finish, NULL, - &OBJECT_draw_scene + NULL, + &OBJECT_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 795b0bae02b..f898770acef 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -178,8 +178,7 @@ static void PAINT_TEXTURE_engine_init(void *vedata) e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); } } -#include "BKE_global.h" -#include "BKE_main.h" + /* Here init all passes and shading groups * Assume that all Passes are NULL */ static void PAINT_TEXTURE_cache_init(void *vedata) @@ -199,12 +198,6 @@ static void PAINT_TEXTURE_cache_init(void *vedata) DRW_STATE_BLEND | DRW_STATE_WIRE; psl->image_faces = DRW_pass_create("Image Color Pass", state); - /* Create a shadingGroup using a function in draw_common.c or custom one */ - /* - * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire); - * -- or -- - * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass); - */ stl->g_data->shgroup_fallback = DRW_shgroup_create(e_data.fallback_sh, psl->image_faces); /* Uniforms need a pointer to it's value so be sure it's accessible at @@ -218,7 +211,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) Object *ob = draw_ctx->obact; if (ob && ob->type == OB_MESH) { Scene *scene = draw_ctx->scene; - bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL); + const bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL); const Mesh *me = ob->data; stl->g_data->shgroup_image_array = MEM_mallocN( @@ -292,41 +285,44 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) /* Get geometry cache */ const Mesh *me = ob->data; Scene *scene = draw_ctx->scene; - bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL); + const bool use_surface = DRW_object_is_mode_shade(ob) == true; + const bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL); bool ok = false; - if (me->mloopuv != NULL) { - if (use_material_slots) { - struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; - if ((me->totcol == 0) || (geom_array == NULL)) { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); - DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); - ok = true; + if (use_surface) { + if (me->mloopuv != NULL) { + if (use_material_slots) { + struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; + if ((me->totcol == 0) || (geom_array == NULL)) { + struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); + ok = true; + } + else { + for (int i = 0; i < me->totcol; i++) { + if (stl->g_data->shgroup_image_array[i]) { + DRW_shgroup_call_add(stl->g_data->shgroup_image_array[i], geom_array[i], ob->obmat); + } + else { + DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom_array[i], ob->obmat); + } + ok = true; + } + } } else { - for (int i = 0; i < me->totcol; i++) { - if (stl->g_data->shgroup_image_array[i]) { - DRW_shgroup_call_add(stl->g_data->shgroup_image_array[i], geom_array[i], ob->obmat); - } - else { - DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom_array[i], ob->obmat); - } + struct Gwn_Batch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob); + if (geom && stl->g_data->shgroup_image_array[0]) { + DRW_shgroup_call_add(stl->g_data->shgroup_image_array[0], geom, ob->obmat); ok = true; } } } - else { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob); - if (geom && stl->g_data->shgroup_image_array[0]) { - DRW_shgroup_call_add(stl->g_data->shgroup_image_array[0], geom, ob->obmat); - ok = true; - } - } - } - if (!ok) { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); - DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); + if (!ok) { + struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); + } } /* Face Mask */ @@ -416,5 +412,6 @@ DrawEngineType draw_engine_paint_texture_type = { &PAINT_TEXTURE_cache_populate, &PAINT_TEXTURE_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &PAINT_TEXTURE_draw_scene + &PAINT_TEXTURE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c index ac3b82e9418..e430fca5742 100644 --- a/source/blender/draw/modes/paint_vertex_mode.c +++ b/source/blender/draw/modes/paint_vertex_mode.c @@ -110,7 +110,9 @@ static void PAINT_VERTEX_cache_init(void *vedata) { /* Create a pass */ - psl->vcolor_faces = DRW_pass_create("Vert Color Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + psl->vcolor_faces = DRW_pass_create( + "Vert Color Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); stl->g_data->fvcolor_shgrp = DRW_shgroup_create(e_data.vcolor_face_shader, psl->vcolor_faces); @@ -122,13 +124,17 @@ static void PAINT_VERTEX_cache_init(void *vedata) } { - psl->wire_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + psl->wire_overlay = DRW_pass_create( + "Wire Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); } { - psl->face_overlay = DRW_pass_create("Face Mask Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND); + psl->face_overlay = DRW_pass_create( + "Face Mask Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND); stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay); @@ -144,15 +150,18 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob) if ((ob->type == OB_MESH) && (ob == draw_ctx->obact)) { IDProperty *ces_mode_pw = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_PAINT_VERTEX, ""); - bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire"); const Mesh *me = ob->data; + const bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire"); + const bool use_surface = DRW_object_is_mode_shade(ob) == true; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; struct Gwn_Batch *geom; world_light = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_shading") ? 0.5f : 1.0f; - geom = DRW_cache_mesh_surface_vert_colors_get(ob); - DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat); + if (use_surface) { + geom = DRW_cache_mesh_surface_vert_colors_get(ob); + DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat); + } if (use_face_sel || use_wire) { geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel); @@ -202,5 +211,6 @@ DrawEngineType draw_engine_paint_vertex_type = { &PAINT_VERTEX_cache_populate, NULL, NULL, - &PAINT_VERTEX_draw_scene + &PAINT_VERTEX_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index 270566b6cc6..e139b4af97f 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -92,7 +92,7 @@ static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata)) if (e_data.actdef != draw_ctx->obact->actdef) { e_data.actdef = draw_ctx->obact->actdef; - BKE_mesh_batch_cache_dirty(draw_ctx->obact->data, BKE_MESH_BATCH_DIRTY_PAINT); + BKE_mesh_batch_cache_dirty(draw_ctx->obact->data, BKE_MESH_BATCH_DIRTY_ALL); } if (!e_data.weight_face_shader) { @@ -180,16 +180,19 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob) if ((ob->type == OB_MESH) && (ob == draw_ctx->obact)) { IDProperty *ces_mode_pw = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_PAINT_WEIGHT, ""); - bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire"); const Mesh *me = ob->data; + const bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire"); + const bool use_surface = DRW_object_is_mode_shade(ob) == true; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; struct Gwn_Batch *geom; world_light = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_shading") ? 0.5f : 1.0f; - geom = DRW_cache_mesh_surface_weights_get(ob); - DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat); + if (use_surface) { + geom = DRW_cache_mesh_surface_weights_get(ob); + DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat); + } if (use_face_sel || use_wire) { geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel); @@ -246,5 +249,6 @@ DrawEngineType draw_engine_paint_weight_type = { &PAINT_WEIGHT_cache_populate, NULL, NULL, - &PAINT_WEIGHT_draw_scene + &PAINT_WEIGHT_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index dd22a5c6d8f..be076815f4c 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -259,5 +259,6 @@ DrawEngineType draw_engine_particle_type = { &PARTICLE_cache_populate, &PARTICLE_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &PARTICLE_draw_scene + &PARTICLE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index d3233d713a1..1c2acd56085 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -101,7 +101,9 @@ static void POSE_cache_init(void *vedata) { /* Non Meshes Pass (Camera, empties, lamps ...) */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE; + DRWState state = + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | + DRW_STATE_BLEND | DRW_STATE_WIRE; psl->relationship = DRW_pass_create("Bone Relationship Pass", state); /* Relationship Lines */ @@ -191,5 +193,6 @@ DrawEngineType draw_engine_pose_type = { &POSE_cache_populate, NULL, NULL, - &POSE_draw_scene + &POSE_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c index a3f29b5bb8f..f38e6565065 100644 --- a/source/blender/draw/modes/sculpt_mode.c +++ b/source/blender/draw/modes/sculpt_mode.c @@ -33,6 +33,8 @@ #include "BKE_pbvh.h" #include "BKE_paint.h" +#include "DEG_depsgraph.h" + /* If builtin shaders are needed */ #include "GPU_shader.h" #include "GPU_matrix.h" @@ -191,6 +193,9 @@ static void SCULPT_cache_populate(void *vedata, Object *ob) if (ob->type == OB_MESH) { const DRWContextState *draw_ctx = DRW_context_state_get(); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(draw_ctx->evil_C, &eval_ctx); if (ob->sculpt && (ob == draw_ctx->obact)) { @@ -201,7 +206,7 @@ static void SCULPT_cache_populate(void *vedata, Object *ob) * but this avoids waiting on first stroke) */ Scene *scene = draw_ctx->scene; - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, scene->toolsettings->sculpt, ob, false, false); } PBVH *pbvh = ob->sculpt->pbvh; @@ -295,5 +300,6 @@ DrawEngineType draw_engine_sculpt_type = { &SCULPT_cache_populate, &SCULPT_cache_finish, NULL, /* draw_background but not needed by mode engines */ - &SCULPT_draw_scene + &SCULPT_draw_scene, + NULL, }; diff --git a/source/blender/draw/modes/shaders/common_fxaa_lib.glsl b/source/blender/draw/modes/shaders/common_fxaa_lib.glsl new file mode 100644 index 00000000000..8158437b943 --- /dev/null +++ b/source/blender/draw/modes/shaders/common_fxaa_lib.glsl @@ -0,0 +1,678 @@ +//---------------------------------------------------------------------------------- +// File: es3-kepler\FXAA/FXAA3_11.h +// SDK Version: v3.00 +// Email: gameworks@nvidia.com +// Site: http://developer.nvidia.com/ +// +// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//---------------------------------------------------------------------------------- + +/* BLENDER MODIFICATIONS: + * + * - (#B1#) Compute luma on the fly using BT. 709 luma function + * - (#B2#) main function instead of #include, due to lack of + * ARB_shading_language_include in 3.3 + * - (#B3#) version and extension directives + * - removed "FXAA Console" algorithm support and shader parameters + * - removed HLSL support shims + * - (#B4#) change luma sampling to compute, not use A channel + * (this also removes GATHER4_ALPHA support) + * - removed all the console shaders (only remaining algorithm is "FXAA PC + * Quality") + * + * Note that this file doesn't follow the coding style guidelines. + */ + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +#define FxaaSat(x) clamp(x, 0.0, 1.0) + +#ifdef FXAA_ALPHA + +#define FxaaTexTop(t, p) textureLod(t, p, 0.0).aaaa +#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o).aaaa +#define FxaaLuma(rgba) rgba.a + +#else + +#define FxaaTexTop(t, p) textureLod(t, p, 0.0) +#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + +/* (#B1#) */ +float FxaaLuma(vec4 rgba) { + // note: sqrt because the sampled colors are in a linear colorspace! + // this approximates a perceptual conversion, which is good enough for the + // algorithm + return sqrt(dot(rgba.rgb, vec3(0.2126, 0.7152, 0.0722))); +} + +#endif + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +/*--------------------------------------------------------------------------*/ +vec4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + vec2 pos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + sampler2D tex, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + vec2 fxaaQualityRcpFrame, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + float fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + float fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + float fxaaQualityEdgeThresholdMin +) { +/*--------------------------------------------------------------------------*/ + vec2 posM; + posM.x = pos.x; + posM.y = pos.y; + vec4 rgbyM = FxaaTexTop(tex, posM); + float lumaM = FxaaLuma(rgbyM); // (#B4#) + float lumaS = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 0, 1), fxaaQualityRcpFrame.xy)); + float lumaE = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 1, 0), fxaaQualityRcpFrame.xy)); + float lumaN = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 0,-1), fxaaQualityRcpFrame.xy)); + float lumaW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1, 0), fxaaQualityRcpFrame.xy)); +/*--------------------------------------------------------------------------*/ + float maxSM = max(lumaS, lumaM); + float minSM = min(lumaS, lumaM); + float maxESM = max(lumaE, maxSM); + float minESM = min(lumaE, minSM); + float maxWN = max(lumaN, lumaW); + float minWN = min(lumaN, lumaW); + float rangeMax = max(maxWN, maxESM); + float rangeMin = min(minWN, minESM); + float rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + float range = rangeMax - rangeMin; + float rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + bool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) { + return rgbyM; + } +/*--------------------------------------------------------------------------*/ + float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1,-1), fxaaQualityRcpFrame.xy)); + float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 1, 1), fxaaQualityRcpFrame.xy)); + float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 1,-1), fxaaQualityRcpFrame.xy)); + float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1, 1), fxaaQualityRcpFrame.xy)); +/*--------------------------------------------------------------------------*/ + float lumaNS = lumaN + lumaS; + float lumaWE = lumaW + lumaE; + float subpixRcpRange = 1.0/range; + float subpixNSWE = lumaNS + lumaWE; + float edgeHorz1 = (-2.0 * lumaM) + lumaNS; + float edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + float lumaNESE = lumaNE + lumaSE; + float lumaNWNE = lumaNW + lumaNE; + float edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + float edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + float lumaNWSW = lumaNW + lumaSW; + float lumaSWSE = lumaSW + lumaSE; + float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + float edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + float edgeHorz = abs(edgeHorz3) + edgeHorz4; + float edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + float subpixNWSWNESE = lumaNWSW + lumaNESE; + float lengthSign = fxaaQualityRcpFrame.x; + bool horzSpan = edgeHorz >= edgeVert; + float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + float subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + float gradientN = lumaN - lumaM; + float gradientS = lumaS - lumaM; + float lumaNN = lumaN + lumaM; + float lumaSS = lumaS + lumaM; + bool pairN = abs(gradientN) >= abs(gradientS); + float gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + float subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + vec2 posB; + posB.x = posM.x; + posB.y = posM.y; + vec2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + vec2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + vec2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + float subpixD = ((-2.0)*subpixC) + 3.0; + float lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + float subpixE = subpixC * subpixC; + float lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + float gradientScaled = gradient * 1.0/4.0; + float lumaMM = lumaM - lumaNN * 0.5; + float subpixF = subpixD * subpixE; + bool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + bool doneN = abs(lumaEndN) >= gradientScaled; + bool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + bool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + float dstN = posM.x - posN.x; + float dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + float spanLength = (dstP + dstN); + bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + float spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + bool directionN = dstN < dstP; + float dst = min(dstN, dstP); + bool goodSpan = directionN ? goodSpanN : goodSpanP; + float subpixG = subpixF * subpixF; + float pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + float subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + float pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + float pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + return vec4(FxaaTexTop(tex, posM).xyz, lumaM); +} +/*==========================================================================*/ + diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl index 9b3fe6286e8..07b36079884 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl @@ -1,5 +1,8 @@ flat in int isSelected; +#ifdef VERTEX_FACING +flat in float facing; +#endif out vec4 FragColor; @@ -9,4 +12,8 @@ void main() FragColor = colorFaceDot; else FragColor = colorWireEdit; + +#ifdef VERTEX_FACING + FragColor.a *= 1.0 - abs(facing) * 0.4; +#endif } diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl index 2e541fa75e6..fa3934c4b77 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl @@ -6,9 +6,26 @@ in vec4 norAndFlag; flat out int isSelected; +#ifdef VERTEX_FACING +uniform mat4 ProjectionMatrix; +uniform mat4 ModelViewMatrix; +uniform mat3 NormalMatrix; + +flat out float facing; +#endif + void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + /* Bias Facedot Z position in clipspace. */ + gl_Position.z -= 0.0002; gl_PointSize = sizeFaceDot; isSelected = int(norAndFlag.w); +#ifdef VERTEX_FACING + vec3 view_normal = normalize(NormalMatrix * norAndFlag.xyz); + vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) + ? normalize((ModelViewMatrix * vec4(pos, 1.0)).xyz) + : vec3(0.0, 0.0, 1.0); + facing = dot(view_vec, view_normal); +#endif } diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl index a8f74ac3e0f..ed7421c1b1d 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl @@ -15,6 +15,9 @@ flat in int clipCase; #ifdef VERTEX_SELECTION in vec3 vertexColor; #endif +#ifdef VERTEX_FACING +in float facing; +#endif /* We use a vec4[2] interface to pass edge data * (without fragmenting memory accesses) @@ -88,6 +91,15 @@ float distToEdge(vec2 o, vec2 dir) return sqrt(abs(dot(af, af) - daf * daf)); } +#ifdef ANTI_ALIASING +void colorDistEdge(vec4 color, float dist) +{ + FragColor = mix(color, FragColor, clamp(dist, 0.0, 1.0)); +} +#else +#define colorDistEdge colorDist +#endif + void main() { vec3 e, p; @@ -143,27 +155,33 @@ void main() /* Edges */ for (int v = 0; v < 3; ++v) { if ((flag[v] & EDGE_EXISTS) != 0) { - float largeEdge = e[v] - sizeEdge * 2.0; + /* Outer large edge */ + float largeEdge = e[v] - sizeEdge * 3.0; + + vec4 large_edge_color = vec4(0.0); + large_edge_color = ((flag[v] & EDGE_SHARP) != 0) ? colorEdgeSharp : large_edge_color; + large_edge_color = (edgesCrease[v] > 0.0) ? vec4(colorEdgeCrease.rgb, edgesCrease[v]) : large_edge_color; + large_edge_color = (edgesBweight[v] > 0.0) ? vec4(colorEdgeBWeight.rgb, edgesBweight[v]) : large_edge_color; + large_edge_color = ((flag[v] & EDGE_SEAM) != 0) ? colorEdgeSeam : large_edge_color; + + if (large_edge_color.a != 0.0) { + colorDistEdge(large_edge_color, largeEdge); + } + + /* Inner thin edge */ float innerEdge = e[v] - sizeEdge; +#ifdef ANTI_ALIASING + innerEdge += 0.125; +#endif - if ((flag[v] & EDGE_SEAM) != 0) - colorDist(colorEdgeSeam, largeEdge); - else if (edgesBweight[v] > 0.0) - colorDist(vec4(colorEdgeBWeight.rgb, edgesBweight[v]), largeEdge); - else if (edgesCrease[v] > 0.0) - colorDist(vec4(colorEdgeCrease.rgb, edgesCrease[v]), largeEdge); - else if ((flag[v] & EDGE_SHARP) != 0) - colorDist(colorEdgeSharp, largeEdge); -#ifndef VERTEX_SELECTION - else - colorDist(colorWireEdit, innerEdge); - - if ((flag[v] & EDGE_ACTIVE) != 0) - colorDist(vec4(colorEditMeshActive.xyz, 1.0), innerEdge); - else if ((flag[v] & EDGE_SELECTED) != 0) - colorDist(colorEdgeSelect, innerEdge); +#ifdef VERTEX_SELECTION + colorDistEdge(vec4(vertexColor, 1.0), innerEdge); #else - colorDist(vec4(vertexColor, 1.0), innerEdge); + vec4 inner_edge_color = colorWireEdit; + inner_edge_color = ((flag[v] & EDGE_SELECTED) != 0) ? colorEdgeSelect : inner_edge_color; + inner_edge_color = ((flag[v] & EDGE_ACTIVE) != 0) ? vec4(colorEditMeshActive.xyz, 1.0) : inner_edge_color; + + colorDistEdge(inner_edge_color, innerEdge); #endif } } @@ -173,15 +191,18 @@ void main() for (int v = 0; v < 3; ++v) { float size = p[v] - sizeVertex; - if ((flag[v] & VERTEX_ACTIVE) != 0) - colorDist(vec4(colorEditMeshActive.xyz, 1.0), size); - else if ((flag[v] & VERTEX_SELECTED) != 0) - colorDist(colorVertexSelect, size); - else - colorDist(colorVertex, size); + vec4 point_color = colorVertex; + point_color = ((flag[v] & VERTEX_SELECTED) != 0) ? colorVertexSelect : point_color; + point_color = ((flag[v] & VERTEX_ACTIVE) != 0) ? vec4(colorEditMeshActive.xyz, 1.0) : point_color; + + colorDist(point_color, size); } #endif +#ifdef VERTEX_FACING + FragColor.a *= 1.0 - abs(facing) * 0.4; +#endif + /* don't write depth if not opaque */ - if (FragColor.a == 0.0) discard; + if (FragColor.a == 0.0) discard; } diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl index 5e3ecd59cb4..7d71e1540d5 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl @@ -14,6 +14,9 @@ uniform vec2 viewportSize; in vec4 vPos[]; in vec4 pPos[]; in ivec4 vData[]; +#ifdef VERTEX_FACING +in float vFacing[]; +#endif /* these are the same for all vertices * and does not need interpolation */ @@ -25,6 +28,9 @@ flat out int clipCase; #ifdef VERTEX_SELECTION out vec3 vertexColor; #endif +#ifdef VERTEX_FACING +out float facing; +#endif /* See fragment shader */ noperspective out vec4 eData1; @@ -79,6 +85,10 @@ void doVertex(int v, vec4 pos) vertexColor = getVertexColor(v); #endif +#ifdef VERTEX_FACING + facing = vFacing[v]; +#endif + gl_Position = pos; EmitVertex(); diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl index 64809a37d11..f83402e3869 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl @@ -29,6 +29,9 @@ uniform vec2 viewportSize; in vec4 vPos[]; in vec4 pPos[]; in ivec4 vData[]; +#ifdef VERTEX_FACING +in float vFacing[]; +#endif /* these are the same for all vertices * and does not need interpolation */ @@ -40,6 +43,9 @@ flat out int clipCase; #ifdef VERTEX_SELECTION out vec3 vertexColor; #endif +#ifdef VERTEX_FACING +out float facing; +#endif /* See fragment shader */ noperspective out vec4 eData1; @@ -103,11 +109,21 @@ void doVertex(int v, vec4 pos) vertexColor = getVertexColor(v); #endif +#ifdef VERTEX_FACING + facing = vFacing[v]; +#endif + gl_Position = pos; EmitVertex(); } +#ifdef ANTI_ALIASING +#define Z_OFFSET 0.008 +#else +#define Z_OFFSET 0.0 +#endif + void main() { /* First we detect which case we are in */ @@ -214,7 +230,7 @@ void main() } /* to not let face color bleed */ - faceColor = vec4(0.0); + faceColor.a = 0.0; /* we don't want other edges : make them far */ eData1 = vec4(1e10); @@ -231,7 +247,7 @@ void main() eData1.zw = pos[vbe]; doVertex(v, pPos[v]); - doVertex(v, pPos[v] + vec4(fixvec[v], 0.0, 0.0)); + doVertex(v, pPos[v] + vec4(fixvec[v], Z_OFFSET, 0.0)); /* Now one triangle only shade one edge * so we use the edge distance calculated @@ -247,19 +263,19 @@ void main() edgesBweight[2] = ebweight[vbe]; doVertex(vaf, pPos[vaf]); - doVertex(vaf, pPos[vaf] + vec4(fixvecaf[v], 0.0, 0.0)); + doVertex(vaf, pPos[vaf] + vec4(fixvecaf[v], Z_OFFSET, 0.0)); /* corner vertices should not draw edges but draw point only */ flag[2] = (vData[vbe].x << 8); #ifdef VERTEX_SELECTION doVertex(vaf, pPos[vaf]); - doVertex(vaf, pPos[vaf] + vec4(cornervec[vaf], 0.0, 0.0)); + doVertex(vaf, pPos[vaf] + vec4(cornervec[vaf], Z_OFFSET, 0.0)); #endif } /* finish the loop strip */ doVertex(2, pPos[2]); - doVertex(2, pPos[2] + vec4(fixvec[2], 0.0, 0.0)); + doVertex(2, pPos[2] + vec4(fixvec[2], Z_OFFSET, 0.0)); #endif } /* Harder case : compute visible edges vectors */ diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl index f567a3a5cbd..8f94a105332 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl @@ -15,10 +15,8 @@ void main() FragColor = wire_color; - /* this works because not rendered depth is 1.0 and the - * following test is always true even when no wires */ - if ((wire_depth > scene_depth) && (wire_color.a > 0)) { - /* Note : Using wire_color.a * alpha produce unwanted result */ - FragColor.a = alpha; + /* Modulate alpha if occluded */ + if (wire_depth > scene_depth) { + FragColor.a *= alpha; } } diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl index 5bc9a8bef85..8ebfa4376f0 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl @@ -15,9 +15,24 @@ out vec4 vPos; out vec4 pPos; out ivec4 vData; +#ifdef VERTEX_FACING +uniform mat4 ProjectionMatrix; +uniform mat3 NormalMatrix; + +in vec3 vnor; +out float vFacing; +#endif + void main() { vPos = ModelViewMatrix * vec4(pos, 1.0); pPos = ModelViewProjectionMatrix * vec4(pos, 1.0); vData = data; +#ifdef VERTEX_FACING + vec3 view_normal = normalize(NormalMatrix * vnor); + vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) + ? normalize(vPos.xyz) + : vec3(0.0, 0.0, 1.0); + vFacing = dot(view_vec, view_normal); +#endif } diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl index 0196b1a6f98..61bd4d58a4a 100644 --- a/source/blender/draw/modes/shaders/object_grid_frag.glsl +++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl @@ -75,7 +75,11 @@ vec3 get_floor_pos(vec2 uv, out vec3 wPos) camera_vec = normalize(eye); } - float p = -dot(planeNormal, camera_pos) / dot(planeNormal, camera_vec); + float plane_normal_dot_camera_vec = dot(planeNormal, camera_vec); + float p = -dot(planeNormal, camera_pos); + if (plane_normal_dot_camera_vec != 0) { + p /= plane_normal_dot_camera_vec; + } vec3 plane = camera_pos + camera_vec * p; /* fix residual imprecision */ diff --git a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl new file mode 100644 index 00000000000..b47b3ee1cf4 --- /dev/null +++ b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl @@ -0,0 +1,28 @@ + +in vec3 pos; +in vec3 nor; + +uniform mat4 ViewProjectionMatrix; + +uniform float sphere_size; +uniform ivec3 grid_resolution; +uniform vec3 corner; +uniform vec3 increment_x; +uniform vec3 increment_y; +uniform vec3 increment_z; + +void main() +{ + vec3 ls_cell_location; + /* Keep in sync with update_irradiance_probe */ + ls_cell_location.z = float(gl_InstanceID % grid_resolution.z); + ls_cell_location.y = float((gl_InstanceID / grid_resolution.z) % grid_resolution.y); + ls_cell_location.x = float(gl_InstanceID / (grid_resolution.z * grid_resolution.y)); + + vec3 ws_cell_location = corner + + (increment_x * ls_cell_location.x + + increment_y * ls_cell_location.y + + increment_z * ls_cell_location.z); + + gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0); +}
\ No newline at end of file diff --git a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl index 5565a0f1e09..dc0ea938436 100644 --- a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl +++ b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl @@ -32,30 +32,48 @@ void search_outline(ivec2 uv, vec4 ref_col, inout bool ref_occlu, inout bool out void main() { ivec2 uv = ivec2(gl_FragCoord.xy); + + vec4 color[4]; + /* Idea : Use a 16bit ID to identify the color + * and store the colors in a UBO. And fetch all ids + * for discontinuity check with one textureGather \o/ */ vec4 ref_col = texelFetch(outlineColor, uv, 0).rgba; + color[0] = texelFetchOffset(outlineColor, uv, 0, ivec2( 1, 0)).rgba; + color[1] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, 1)).rgba; + color[2] = texelFetchOffset(outlineColor, uv, 0, ivec2(-1, 0)).rgba; + color[3] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, -1)).rgba; + /* TODO GATHER */ + vec4 depths; float depth = texelFetch(outlineDepth, uv, 0).r; - /* Modulate color if occluded */ + depths.x = texelFetchOffset(outlineDepth, uv, 0, ivec2( 1, 0)).r; + depths.y = texelFetchOffset(outlineDepth, uv, 0, ivec2( 0, 1)).r; + depths.z = texelFetchOffset(outlineDepth, uv, 0, ivec2(-1, 0)).r; + depths.w = texelFetchOffset(outlineDepth, uv, 0, ivec2( 0, -1)).r; + + vec4 scene_depths; float scene_depth = texelFetch(sceneDepth, uv, 0).r; + scene_depths.x = texelFetchOffset(sceneDepth, uv, 0, ivec2( 1, 0)).r; + scene_depths.y = texelFetchOffset(sceneDepth, uv, 0, ivec2( 0, 1)).r; + scene_depths.z = texelFetchOffset(sceneDepth, uv, 0, ivec2(-1, 0)).r; + scene_depths.w = texelFetchOffset(sceneDepth, uv, 0, ivec2( 0, -1)).r; bool ref_occlu = (depth > scene_depth); - bool outline = false; +#if 1 + bvec4 occlu = (!ref_occlu) ? notEqual(greaterThan(depths, scene_depths), bvec4(ref_occlu)) : bvec4(false); + outline = (!outline) ? (color[0] != ref_col) || occlu.x : true; + outline = (!outline) ? (color[1] != ref_col) || occlu.y : true; + outline = (!outline) ? (color[2] != ref_col) || occlu.z : true; + outline = (!outline) ? (color[3] != ref_col) || occlu.w : true; +#else search_outline(uv + ivec2( 1, 0), ref_col, ref_occlu, outline); search_outline(uv + ivec2( 0, 1), ref_col, ref_occlu, outline); search_outline(uv + ivec2(-1, 0), ref_col, ref_occlu, outline); search_outline(uv + ivec2( 0, -1), ref_col, ref_occlu, outline); +#endif FragColor = ref_col; - - /* We Hit something ! */ - if (outline) { - if (ref_occlu) { - FragColor.a *= alphaOcclu; - } - } - else { - FragColor.a = 0.0; - } + FragColor.a *= (outline) ? (ref_occlu) ? alphaOcclu : 1.0 : 0.0; } diff --git a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl index e0568d1157a..7e288cde236 100644 --- a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl +++ b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl @@ -4,42 +4,34 @@ in vec4 uvcoordsvar; out vec4 FragColor; uniform sampler2D outlineColor; -uniform sampler2D outlineDepth; uniform float alpha; uniform bool doExpand; -void search_outline(ivec2 uv, inout bool found_edge) -{ - if (!found_edge) { - vec4 color = texelFetch(outlineColor, uv, 0).rgba; - if (color.a != 0.0) { - if (doExpand || color.a != 1.0) { - FragColor = color; - found_edge = true; - } - } - } -} - void main() { ivec2 uv = ivec2(gl_FragCoord.xy); FragColor = texelFetch(outlineColor, uv, 0).rgba; - float depth = texelFetch(outlineDepth, uv, 0).r; - if (FragColor.a != 0.0 || (depth == 1.0 && !doExpand)) - return; + vec4 color[4]; + color[0] = texelFetchOffset(outlineColor, uv, 0, ivec2( 1, 0)).rgba; + color[1] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, 1)).rgba; + color[2] = texelFetchOffset(outlineColor, uv, 0, ivec2(-1, 0)).rgba; + color[3] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, -1)).rgba; - bool found_edge = false; - search_outline(uv + ivec2( 1, 0), found_edge); - search_outline(uv + ivec2( 0, 1), found_edge); - search_outline(uv + ivec2(-1, 0), found_edge); - search_outline(uv + ivec2( 0, -1), found_edge); + vec4 values = vec4(color[0].a, color[1].a, color[2].a, color[3].a); - /* We Hit something ! */ - if (found_edge) { - /* only change alpha */ - FragColor.a *= alpha; + vec4 tests = step(vec4(1e-6), values); /* (color.a != 0.0) */ + bvec4 btests = equal(tests, vec4(1.0)); + + if (FragColor.a != 0.0) { + return; } + + FragColor = (btests.x) ? color[0] : FragColor; + FragColor = (btests.y) ? color[1] : FragColor; + FragColor = (btests.z) ? color[2] : FragColor; + FragColor = (btests.w) ? color[3] : FragColor; + + FragColor.a *= (!doExpand) ? 0.0 : 1.0; } diff --git a/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl b/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl index 3937828eca2..964ebe72e81 100644 --- a/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl +++ b/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl @@ -4,8 +4,24 @@ in vec4 uvcoordsvar; out vec4 FragColor; uniform sampler2D outlineBluredColor; +uniform vec2 rcpDimensions; void main() { - FragColor = texture(outlineBluredColor, uvcoordsvar.st).rgba; +#ifdef USE_FXAA + float aa_alpha = FxaaPixelShader( + uvcoordsvar.st, + outlineBluredColor, + rcpDimensions, + 1.0, + 0.166, + 0.0833 + ).r; +#endif + + FragColor = texture(outlineBluredColor, uvcoordsvar.st).rgba; + +#ifdef USE_FXAA + FragColor.a = aa_alpha; +#endif } diff --git a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl index a950a9b86ba..54ae319307a 100644 --- a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl +++ b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl @@ -39,16 +39,18 @@ void main() } #ifdef USE_AXIS - finalColor.rgb = vec3(0.0); - finalColor[axis] = 1.0; + if (axis == 0) + finalColor = vec4(1.0, 0.0, 0.0, 1.0); + else if (axis == 1) + finalColor = vec4(0.0, 1.0, 0.0, 1.0); + else + finalColor = vec4(0.0, 0.0, 1.0, 1.0); #else if (val < 0.0) { - finalColor.rgb = color; + finalColor = vec4(color, 1.0); } else { - finalColor.rgb = texture(ramp, val).rgb; + finalColor = vec4(texture(ramp, val).rgb, 1.0); } #endif - - finalColor.a = 1.0; } |