Eevee: Draw background shader.

Also fixes some remaining errors caused by some matrices not updated.
This commit is contained in:
2017-05-04 17:39:50 +02:00
parent 5601a62179
commit 4ef0513aab
7 changed files with 135 additions and 10 deletions

View File

@@ -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)

View File

@@ -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);
}
@@ -429,6 +434,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);
@@ -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);

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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)