diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-04-26 00:48:26 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-04-26 00:51:05 +0300 |
commit | 82686f0a0c2c1d5c42b07288935440aea4713cad (patch) | |
tree | b9b750c1849c2446d420deb14b229e792d5bb594 /source/blender | |
parent | bb75b0bcbcea35fe32e439c8f3e618b66f5110cf (diff) |
Eevee: World default shader.
- Use uniform color world for the world probe.
- Refactored the Fresnel expression to be better with Area Lights.
- Squared the roughness for default materials.
Diffstat (limited to 'source/blender')
8 files changed, 85 insertions, 73 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 14dbd50c487..5be7ec81c05 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -110,11 +110,11 @@ data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC) 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/lit_surface_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/probe_filter_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/probe_sh_frag.glsl SRC) -data_to_c_simple(engines/eevee/shaders/probe_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/probe_geom.glsl SRC) data_to_c_simple(engines/eevee/shaders/probe_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee.c b/source/blender/draw/engines/eevee/eevee.c index 69d6c19b8a7..6ae29ba33a9 100644 --- a/source/blender/draw/engines/eevee/eevee.c +++ b/source/blender/draw/engines/eevee/eevee.c @@ -25,6 +25,8 @@ #include "DRW_render.h" +#include "DNA_world_types.h" + #include "BLI_dynstr.h" #include "BLI_rand.h" #include "GPU_glew.h" @@ -38,11 +40,11 @@ /* *********** STATIC *********** */ static struct { struct GPUShader *default_lit; + struct GPUShader *default_world; struct GPUShader *depth_sh; struct GPUShader *tonemap; struct GPUShader *shadow_sh; - /* Temp : use world shader */ - struct GPUShader *probe_sh; + struct GPUShader *probe_filter_sh; struct GPUShader *probe_spherical_harmonic_sh; @@ -55,6 +57,7 @@ static struct { } e_data = {NULL}; /* Engine data */ extern char datatoc_default_frag_glsl[]; +extern char datatoc_default_world_frag_glsl[]; extern char datatoc_ltc_lib_glsl[]; extern char datatoc_bsdf_lut_frag_glsl[]; extern char datatoc_bsdf_common_lib_glsl[]; @@ -68,11 +71,11 @@ extern char datatoc_shadow_geom_glsl[]; extern char datatoc_shadow_vert_glsl[]; extern char datatoc_probe_filter_frag_glsl[]; extern char datatoc_probe_sh_frag_glsl[]; -extern char datatoc_probe_frag_glsl[]; extern char datatoc_probe_geom_glsl[]; extern char datatoc_probe_vert_glsl[]; extern Material defmaterial; +extern GlobalsUboStorage ts; /* Van der Corput sequence */ /* From http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */ @@ -211,7 +214,7 @@ static void EEVEE_engine_init(void *ved) (int)viewport_size[0], (int)viewport_size[1], &tex, 1); - if (!e_data.default_lit) { + if (!e_data.depth_sh) { e_data.depth_sh = DRW_shader_create_3D_depth_only(); } @@ -243,9 +246,9 @@ static void EEVEE_engine_init(void *ved) datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_frag_glsl, NULL); } - if (!e_data.probe_sh) { - e_data.probe_sh = DRW_shader_create( - datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_probe_frag_glsl, NULL); + if (!e_data.default_world) { + e_data.default_world = DRW_shader_create( + datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_default_world_frag_glsl, NULL); } if (!e_data.probe_filter_sh) { @@ -370,9 +373,27 @@ static void EEVEE_cache_init(void *vedata) psl->probe_background = DRW_pass_create("Probe Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR); struct Batch *geom = DRW_cache_fullscreen_quad_get(); - DRWShadingGroup *grp = eevee_cube_shgroup(e_data.probe_sh, psl->probe_background, geom); - DRW_shgroup_uniform_int(grp, "Layer", &stl->probes->layer, 1); - DRW_shgroup_uniform_buffer(grp, "probeLatLong", &stl->probes->backgroundtex, 0); + DRWShadingGroup *grp; + + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + World *wo = scene->world; + + if (false) { /* TODO check for world nodetree */ + // GPUMaterial *gpumat = GPU_material_from_nodetree(struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options) + } + else { + float *col = ts.colorBackground; + static int zero = 0; + + if (wo) { + col = &wo->horr; + } + + grp = eevee_cube_shgroup(e_data.default_world, psl->probe_background, geom); + DRW_shgroup_uniform_int(grp, "Layer", &zero, 1); + DRW_shgroup_uniform_vec3(grp, "color", col, 1); + } } { @@ -562,7 +583,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.probe_sh); + DRW_SHADER_FREE_SAFE(e_data.default_world); DRW_SHADER_FREE_SAFE(e_data.probe_filter_sh); DRW_SHADER_FREE_SAFE(e_data.probe_spherical_harmonic_sh); DRW_SHADER_FREE_SAFE(e_data.tonemap); diff --git a/source/blender/draw/engines/eevee/eevee_probes.c b/source/blender/draw/engines/eevee/eevee_probes.c index 213f470e3a7..cb83f43dc73 100644 --- a/source/blender/draw/engines/eevee/eevee_probes.c +++ b/source/blender/draw/engines/eevee/eevee_probes.c @@ -147,19 +147,8 @@ void EEVEE_refresh_probe(EEVEE_Data *vedata) mul_m4_m4m4(pinfo->probemat[i], projmat, cubefacemat[i]); } - /* Debug Tex : Use World 1st Tex Slot */ - if (world && world->mtex[0]) { - MTex *mtex = world->mtex[0]; - if (mtex && mtex->tex) { - Tex *tex = mtex->tex; - if (tex->ima) { - pinfo->backgroundtex = GPU_texture_from_blender(tex->ima, &tex->iuser, GL_TEXTURE_2D, true, 0.0, 0); - - DRW_framebuffer_bind(fbl->probe_fb); - DRW_draw_pass(psl->probe_background); - } - } - } + DRW_framebuffer_bind(fbl->probe_fb); + DRW_draw_pass(psl->probe_background); /* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */ /* Bind next framebuffer to be able to write to probe_rt. */ diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl index 105b637c371..b0f31a403c7 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl @@ -83,14 +83,17 @@ float direct_diffuse_unit_disc(vec3 N, vec3 L) #endif /* ----------- GGx ------------ */ -float direct_ggx_point(ShadingData sd, float roughness) +vec3 direct_ggx_point(ShadingData sd, float roughness, vec3 f0) { float bsdf = bsdf_ggx(sd.N, sd.L, sd.V, roughness); bsdf /= sd.l_distance * sd.l_distance; - return bsdf; + + /* Fresnel */ + float VH = max(dot(sd.V, normalize(sd.V + sd.L)), 0.0); + return F_schlick(f0, VH) * bsdf; } -float direct_ggx_sphere(LightData ld, ShadingData sd, float roughness) +vec3 direct_ggx_sphere(LightData ld, ShadingData sd, float roughness, vec3 f0) { #ifdef USE_LTC vec3 P = line_aligned_plane_intersect(vec3(0.0), sd.spec_dominant_dir, sd.l_vector); @@ -128,9 +131,13 @@ float direct_ggx_sphere(LightData ld, ShadingData sd, float roughness) /* sqrt(pi/2) difference between square and disk area */ bsdf *= 1.25331413731; #endif - - bsdf *= texture(brdfLut, uv).b; /* Bsdf intensity */ + vec3 lut = texture(brdfLut, uv).rgb; + bsdf *= lut.b; /* Bsdf intensity */ bsdf *= M_1_2PI * M_1_PI; + + /* Rough fresnel approximation using the LUT */ + lut.xy = normalize(lut.xy); + vec3 spec = bsdf * lut.y + f0 * bsdf * lut.x; #else float energy_conservation; vec3 L = mrp_sphere(ld, sd, sd.spec_dominant_dir, roughness, energy_conservation); @@ -138,11 +145,15 @@ float direct_ggx_sphere(LightData ld, ShadingData sd, float roughness) bsdf *= energy_conservation / (sd.l_distance * sd.l_distance); bsdf *= max(ld.l_radius * ld.l_radius, 1e-16); /* radius is already inside energy_conservation */ + + /* Fresnel */ + float VH = max(dot(sd.V, normalize(sd.V + sd.L)), 0.0); + vec3 spec = F_schlick(f0, NV) * bsdf; #endif - return bsdf; + return spec; } -float direct_ggx_rectangle(LightData ld, ShadingData sd, float roughness) +vec3 direct_ggx_rectangle(LightData ld, ShadingData sd, float roughness, vec3 f0) { #ifdef USE_LTC float NV = max(dot(sd.N, sd.V), 1e-8); @@ -150,8 +161,13 @@ float direct_ggx_rectangle(LightData ld, ShadingData sd, float roughness) mat3 ltcmat = ltc_matrix(uv); float bsdf = ltc_evaluate(sd.N, sd.V, ltcmat, sd.area_data.corner); - bsdf *= texture(brdfLut, uv).b; /* Bsdf intensity */ + vec3 lut = texture(brdfLut, uv).rgb; + bsdf *= lut.b; /* Bsdf intensity */ bsdf *= M_1_2PI; + + /* Rough fresnel approximation using the LUT */ + lut.xy = normalize(lut.xy); + vec3 spec = bsdf * lut.y + f0 * bsdf * lut.x; #else float energy_conservation; vec3 L = mrp_area(ld, sd, sd.spec_dominant_dir, roughness, energy_conservation); @@ -161,8 +177,12 @@ float direct_ggx_rectangle(LightData ld, ShadingData sd, float roughness) /* fade mrp artifacts */ bsdf *= max(0.0, dot(-sd.spec_dominant_dir, ld.l_forward)); bsdf *= max(0.0, -dot(L, ld.l_forward)); + + /* Fresnel */ + float VH = max(dot(sd.V, normalize(sd.V + sd.L)), 0.0); + vec3 spec = F_schlick(f0, NV) * bsdf; #endif - return bsdf; + return spec; } #if 0 diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl index 02ececf7a68..4cb229e392b 100644 --- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl @@ -6,5 +6,6 @@ uniform int hardness; void main() { float roughness = 1.0 - float(hardness) / 511.0; + roughness *= roughness; fragColor = vec4(eevee_surface_lit(worldNormal, diffuse_col, specular_col, roughness), 1.0); } diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl new file mode 100644 index 00000000000..075ee22dc6f --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl @@ -0,0 +1,8 @@ + +uniform vec3 color; + +out vec4 FragColor; + +void main() { + FragColor = vec4(color, 1.0); +} diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index dca3c99453e..7a0a7b8da91 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -37,30 +37,30 @@ out vec4 fragColor; #define HEMI 3.0 #define AREA 4.0 -float light_diffuse(LightData ld, ShadingData sd) +vec3 light_diffuse(LightData ld, ShadingData sd, vec3 albedo) { if (ld.l_type == SUN) { - return direct_diffuse_sun(ld, sd); + return direct_diffuse_sun(ld, sd) * albedo; } else if (ld.l_type == AREA) { - return direct_diffuse_rectangle(ld, sd); + return direct_diffuse_rectangle(ld, sd) * albedo; } else { - return direct_diffuse_sphere(ld, sd); + return direct_diffuse_sphere(ld, sd) * albedo; } } -float light_specular(LightData ld, ShadingData sd, float roughness) +vec3 light_specular(LightData ld, ShadingData sd, float roughness, vec3 f0) { if (ld.l_type == SUN) { - return direct_ggx_point(sd, roughness); + return direct_ggx_point(sd, roughness, f0); } else if (ld.l_type == AREA) { - return direct_ggx_rectangle(ld, sd, roughness); + return direct_ggx_rectangle(ld, sd, roughness, f0); } else { - // return direct_ggx_point(sd, roughness); - return direct_ggx_sphere(ld, sd, roughness); + // return direct_ggx_point(sd, roughness, f0); + return direct_ggx_sphere(ld, sd, roughness, f0); } } @@ -254,11 +254,10 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness) light_common(ld, sd); float vis = light_visibility(ld, sd); - float spec = light_specular(ld, sd, roughness); - float diff = light_diffuse(ld, sd); - vec3 fresnel = light_fresnel(ld, sd, f0); + vec3 spec = light_specular(ld, sd, roughness, f0); + vec3 diff = light_diffuse(ld, sd, albedo); - radiance += vis * (albedo * diff + fresnel * spec) * ld.l_color; + radiance += vis * (diff + spec) * ld.l_color; } /* Envmaps */ diff --git a/source/blender/draw/engines/eevee/shaders/probe_frag.glsl b/source/blender/draw/engines/eevee/shaders/probe_frag.glsl deleted file mode 100644 index 9afdb33b583..00000000000 --- a/source/blender/draw/engines/eevee/shaders/probe_frag.glsl +++ /dev/null @@ -1,26 +0,0 @@ - -in vec3 worldPosition; - -uniform sampler2D probeLatLong; - -out vec4 FragColor; - -float hypot(float x, float y) { return sqrt(x*x + y*y); } - -void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color) -{ - vec3 nco = normalize(co); - float u = -atan(nco.y, nco.x) / (2.0 * 3.1415) + 0.5; - float v = atan(nco.z, hypot(nco.x, nco.y)) / 3.1415 + 0.5; - - color = texture(ima, vec2(u, v)); -} - -void main() { - vec3 L = normalize(worldPosition); - vec2 uvs = gl_FragCoord.xy / 256.0; - float dist = dot(L, vec3(0.0,1.0,0.0)); - dist = (dist > 0.99) ? 1e1 : 0.0; - FragColor = vec4(dist,dist,dist, 1.0); - node_tex_environment_equirectangular(L, probeLatLong, FragColor); -} |