diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-05-04 18:39:50 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-05-04 18:42:22 +0300 |
commit | 4ef0513aab26f4ac459600e0f1ef6bc731a2ba42 (patch) | |
tree | a5b267e43ec9c16de88c244aab3f5899687d06d0 /source/blender | |
parent | 5601a62179642f53ef9b04826c4c9ca5437c0097 (diff) |
Eevee: Draw background shader.
Also fixes some remaining errors caused by some matrices not updated.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_engine.c | 61 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_private.h | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/background_vert.glsl | 16 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 36 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 24 |
7 files changed, 135 insertions, 10 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 0f882f7320d..15c9da0d9b5 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -111,6 +111,7 @@ data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC) data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index bcb40c62fca..f5c07d55c20 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -45,6 +45,7 @@ static struct { struct GPUShader *default_lit; struct GPUShader *default_world; + struct GPUShader *default_background; struct GPUShader *depth_sh; struct GPUShader *tonemap; struct GPUShader *shadow_sh; @@ -76,6 +77,7 @@ extern char datatoc_probe_filter_frag_glsl[]; extern char datatoc_probe_sh_frag_glsl[]; extern char datatoc_probe_geom_glsl[]; extern char datatoc_probe_vert_glsl[]; +extern char datatoc_background_vert_glsl[]; extern Material defmaterial; extern GlobalsUboStorage ts; @@ -261,6 +263,10 @@ static void EEVEE_engine_init(void *ved) datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_default_world_frag_glsl, NULL); } + if (!e_data.default_background) { + e_data.default_background = DRW_shader_create_fullscreen(datatoc_default_world_frag_glsl, NULL); + } + if (!e_data.probe_filter_sh) { char *shader_str = NULL; @@ -283,7 +289,6 @@ static void EEVEE_engine_init(void *ved) e_data.probe_spherical_harmonic_sh = DRW_shader_create_fullscreen(datatoc_probe_sh_frag_glsl, NULL); } - if (!e_data.ltc_mat) { e_data.ltc_mat = DRW_texture_create_2D(64, 64, DRW_TEX_RGBA_16, DRW_TEX_FILTER, ltc_mat_ggx); } @@ -430,6 +435,52 @@ static void EEVEE_cache_init(void *vedata) } { + psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR); + + struct Batch *geom = DRW_cache_fullscreen_quad_get(); + DRWShadingGroup *grp = NULL; + + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + World *wo = scene->world; + + float *col = ts.colorBackground; + if (wo) { + col = &wo->horr; + } + + if (wo && wo->use_nodes && wo->nodetree) { + struct GPUMaterial *gpumat = GPU_material_from_nodetree( + scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type, 1, + datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib, + "#define WORLD_BACKGROUND\n" + "#define MAX_LIGHT 128\n" + "#define MAX_SHADOW_CUBE 42\n" + "#define MAX_SHADOW_MAP 64\n" + "#define MAX_SHADOW_CASCADE 8\n" + "#define MAX_CASCADE_NUM 4\n"); + + grp = DRW_shgroup_material_create(gpumat, psl->background_pass); + + if (grp) { + DRW_shgroup_call_add(grp, geom, NULL); + } + else { + /* Shader failed : pink background */ + static float pink[3] = {1.0f, 0.0f, 1.0f}; + col = pink; + } + } + + /* Fallback if shader fails or if not using nodetree. */ + if (grp == NULL) { + grp = DRW_shgroup_create(e_data.default_background, psl->background_pass); + DRW_shgroup_uniform_vec3(grp, "color", col, 1); + DRW_shgroup_call_add(grp, geom, NULL); + } + } + + { psl->probe_prefilter = DRW_pass_create("Probe Filtering", DRW_STATE_WRITE_COLOR); struct Batch *geom = DRW_cache_fullscreen_quad_get(); @@ -640,12 +691,7 @@ static void EEVEE_draw_scene(void *vedata) DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); DRW_framebuffer_bind(fbl->main); - /* Clear Depth */ - /* TODO do background */ - // float clearcol[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - // DRW_framebuffer_clear(true, true, false, clearcol, 1.0f); - DRW_draw_background(); - + DRW_draw_pass(psl->background_pass); DRW_draw_pass(psl->depth_pass); DRW_draw_pass(psl->depth_pass_cull); DRW_draw_pass(psl->default_pass); @@ -662,6 +708,7 @@ static void EEVEE_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.default_lit); DRW_SHADER_FREE_SAFE(e_data.shadow_sh); DRW_SHADER_FREE_SAFE(e_data.default_world); + DRW_SHADER_FREE_SAFE(e_data.default_background); DRW_SHADER_FREE_SAFE(e_data.probe_filter_sh); DRW_SHADER_FREE_SAFE(e_data.probe_spherical_harmonic_sh); DRW_TEXTURE_FREE_SAFE(e_data.ltc_mat); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index cacc412c224..4d25dab7343 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -51,6 +51,7 @@ typedef struct EEVEE_PassList { struct DRWPass *depth_pass_cull; struct DRWPass *default_pass; struct DRWPass *material_pass; + struct DRWPass *background_pass; } EEVEE_PassList; typedef struct EEVEE_FramebufferList { diff --git a/source/blender/draw/engines/eevee/shaders/background_vert.glsl b/source/blender/draw/engines/eevee/shaders/background_vert.glsl new file mode 100644 index 00000000000..ef94c775336 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/background_vert.glsl @@ -0,0 +1,16 @@ + +mat4 ViewProjectionMatrixInverse; + +in vec2 pos; + +out vec3 varposition; +out vec3 varnormal; +out vec3 viewPosition; +out vec3 worldPosition; + +void main() +{ + gl_Position = vec4(pos, 1.0, 1.0); + varposition = viewPosition = vec3(pos, -1.0); + varnormal = normalize(-varposition); +} diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index a96e087ad8b..d27e2430900 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -148,12 +148,16 @@ struct DRWInterface { int attribs_loc[16]; /* matrices locations */ int model; + int modelinverse; int modelview; + int modelviewinverse; int projection; + int projectioninverse; int view; int viewinverse; int modelviewprojection; int viewprojection; + int viewprojectioninverse; int normal; int worldnormal; int eye; @@ -512,11 +516,15 @@ static DRWInterface *DRW_interface_create(GPUShader *shader) DRWInterface *interface = MEM_mallocN(sizeof(DRWInterface), "DRWInterface"); interface->model = GPU_shader_get_uniform(shader, "ModelMatrix"); + interface->modelinverse = GPU_shader_get_uniform(shader, "ModelMatrixInverse"); interface->modelview = GPU_shader_get_uniform(shader, "ModelViewMatrix"); + interface->modelviewinverse = GPU_shader_get_uniform(shader, "ModelViewMatrixInverse"); interface->projection = GPU_shader_get_uniform(shader, "ProjectionMatrix"); + interface->projectioninverse = GPU_shader_get_uniform(shader, "ProjectionMatrixInverse"); interface->view = GPU_shader_get_uniform(shader, "ViewMatrix"); interface->viewinverse = GPU_shader_get_uniform(shader, "ViewMatrixInverse"); interface->viewprojection = GPU_shader_get_uniform(shader, "ViewProjectionMatrix"); + interface->viewprojectioninverse = GPU_shader_get_uniform(shader, "ViewProjectionMatrixInverse"); interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix"); interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix"); interface->worldnormal = GPU_shader_get_uniform(shader, "WorldNormalMatrix"); @@ -1275,21 +1283,33 @@ static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*o RegionView3D *rv3d = DST.draw_ctx.rv3d; DRWInterface *interface = shgroup->interface; - float mvp[4][4], mv[4][4], n[3][3], wn[3][3]; + float mvp[4][4], mv[4][4], mi[4][4], mvi[4][4], pi[4][4], n[3][3], wn[3][3]; float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */ + bool do_pi = (interface->projectioninverse != -1); bool do_mvp = (interface->modelviewprojection != -1); + bool do_mi = (interface->modelinverse != -1); bool do_mv = (interface->modelview != -1); + bool do_mvi = (interface->modelviewinverse != -1); bool do_n = (interface->normal != -1); bool do_wn = (interface->worldnormal != -1); bool do_eye = (interface->eye != -1); + if (do_pi) { + invert_m4_m4(pi, rv3d->winmat); + } + if (do_mi) { + invert_m4_m4(mi, obmat); + } if (do_mvp) { mul_m4_m4m4(mvp, rv3d->persmat, obmat); } - if (do_mv || do_n || do_eye) { + if (do_mv || do_mvi || do_n || do_eye) { mul_m4_m4m4(mv, rv3d->viewmat, obmat); } + if (do_mvi) { + invert_m4_m4(mvi, mv); + } if (do_n || do_eye) { copy_m3_m4(n, mv); invert_m3(n); @@ -1313,6 +1333,9 @@ static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*o if (interface->model != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->model, 16, 1, (float *)obmat); } + if (interface->modelinverse != -1) { + GPU_shader_uniform_vector(shgroup->shader, interface->modelinverse, 16, 1, (float *)mi); + } if (interface->modelviewprojection != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp); } @@ -1322,15 +1345,24 @@ static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*o if (interface->viewprojection != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat); } + if (interface->viewprojectioninverse != -1) { + GPU_shader_uniform_vector(shgroup->shader, interface->viewprojectioninverse, 16, 1, (float *)rv3d->persinv); + } if (interface->projection != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)rv3d->winmat); } + if (interface->projectioninverse != -1) { + GPU_shader_uniform_vector(shgroup->shader, interface->projectioninverse, 16, 1, (float *)pi); + } if (interface->view != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->view, 16, 1, (float *)rv3d->viewmat); } if (interface->modelview != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->modelview, 16, 1, (float *)mv); } + if (interface->modelviewinverse != -1) { + GPU_shader_uniform_vector(shgroup->shader, interface->modelviewinverse, 16, 1, (float *)mvi); + } if (interface->normal != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n); } diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index d291db2a84d..0e230bc5037 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -624,6 +624,8 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final else if (input->source == GPU_SOURCE_BUILTIN) { if (input->builtin == GPU_INVERSE_VIEW_MATRIX) BLI_dynstr_append(ds, "viewinv"); + else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX) + BLI_dynstr_append(ds, "objinv"); else if (input->builtin == GPU_VIEW_POSITION) BLI_dynstr_append(ds, "viewposition"); else if (input->builtin == GPU_VIEW_NORMAL) @@ -691,6 +693,8 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use BLI_dynstr_append(ds, "void main()\n{\n"); if (use_new_shading) { + if (builtins & GPU_INVERSE_OBJECT_MATRIX) + BLI_dynstr_append(ds, "\tmat4 objinv = ModelMatrixInverse;\n"); if (builtins & GPU_INVERSE_VIEW_MATRIX) BLI_dynstr_append(ds, "\tmat4 viewinv = ViewMatrixInverse;\n"); if (builtins & GPU_VIEW_NORMAL) @@ -700,6 +704,8 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use } else { + if (builtins & GPU_INVERSE_OBJECT_MATRIX) + BLI_dynstr_append(ds, "\tmat4 objinv = unfinvobmat;\n"); if (builtins & GPU_INVERSE_VIEW_MATRIX) BLI_dynstr_append(ds, "\tmat4 viewinv = unfinvviewmat;\n"); if (builtins & GPU_VIEW_NORMAL) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 1da213b4103..df639f7047e 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1,8 +1,11 @@ uniform mat4 ModelViewMatrix; #ifndef PROBE_CAPTURE +#ifndef WORLD_BACKGROUND uniform mat4 ProjectionMatrix; #endif +#endif +uniform mat4 ModelMatrixInverse; uniform mat4 ModelViewMatrixInverse; uniform mat4 ViewMatrixInverse; uniform mat4 ProjectionMatrixInverse; @@ -2816,10 +2819,20 @@ void background_transform_to_world(vec3 viewvec, out vec3 worldvec) worldvec = (ModelViewMatrixInverse * co).xyz; } -#ifdef PROBE_CAPTURE +#if defined(PROBE_CAPTURE) || defined(WORLD_BACKGROUND) void environment_default_vector(out vec3 worldvec) { +#ifdef WORLD_BACKGROUND + vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewPosition, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); + vec4 co_homogenous = (ProjectionMatrixInverse * v); + + vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); + + co = normalize(co); + worldvec = (ViewMatrixInverse * co).xyz; +#else worldvec = normalize(worldPosition); +#endif } #endif @@ -2951,7 +2964,12 @@ void node_tex_coord_background( vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); co = normalize(co); + +#ifdef PROBE_CAPTURE + vec3 coords = normalize(worldPosition); +#else vec3 coords = (ModelViewMatrixInverse * co).xyz; +#endif generated = coords; normal = -coords; @@ -2966,6 +2984,10 @@ void node_tex_coord_background( reflection = -coords; } +#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) +#define node_tex_coord node_tex_coord_background +#endif + /* textures */ float calc_gradient(vec3 p, int gradient_type) |