diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-06-14 12:09:13 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-06-15 01:55:44 +0300 |
commit | 49ba446f68954b7c32fbe40d733044cfbe39ff5d (patch) | |
tree | 47456f044b78629818eceb3479fe3f3c1bc5df15 | |
parent | 88602ea017da9b658e0e03d2f740098fcc0e6cc4 (diff) |
Eevee: Split irradiance functions to their own new file.
4 files changed, 151 insertions, 172 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 6de9e7fef1d..35dcc8dbd88 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -83,6 +83,7 @@ extern char datatoc_bsdf_lut_frag_glsl[]; extern char datatoc_bsdf_common_lib_glsl[]; extern char datatoc_bsdf_direct_lib_glsl[]; extern char datatoc_bsdf_sampling_lib_glsl[]; +extern char datatoc_irradiance_lib_glsl[]; extern char datatoc_lit_surface_frag_glsl[]; extern char datatoc_lit_surface_vert_glsl[]; extern char datatoc_shadow_frag_glsl[]; @@ -167,6 +168,7 @@ void EEVEE_materials_init(void) /* Shaders */ DynStr *ds_frag = BLI_dynstr_new(); BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_ltc_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_bsdf_direct_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_lit_surface_frag_glsl); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 77ff614b2c1..ece4250741c 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -40,31 +40,6 @@ struct GridData { #define g_resolution resolution_offset.xyz #define g_offset resolution_offset.w -#ifdef IRRADIANCE_CUBEMAP -struct IrradianceData { - vec3 color; -}; -#elif defined(IRRADIANCE_SH_L2) -struct IrradianceData { - vec3 shcoefs[9]; -}; -#else /* defined(IRRADIANCE_HL2) */ -struct IrradianceData { - vec3 cubesides[3]; -}; -#endif - -/* TODO remove sh once we have irradiance grid */ -#define shcoef0 shcoefs[0].rgb -#define shcoef1 vec3(shcoefs[0].a, shcoefs[1].rg) -#define shcoef2 vec3(shcoefs[1].ba, shcoefs[2].r) -#define shcoef3 shcoefs[2].gba -#define shcoef4 shcoefs[3].rgb -#define shcoef5 vec3(shcoefs[3].a, shcoefs[4].rg) -#define shcoef6 vec3(shcoefs[4].ba, shcoefs[5].r) -#define shcoef7 shcoefs[5].gba -#define shcoef8 shcoefs[6].rgb - struct LightData { vec4 position_influence; /* w : InfluenceRadius */ vec4 color_spec; /* w : Spec Intensity */ @@ -252,65 +227,6 @@ float buffer_depth(bool is_persp, float z, float zf, float zn) } } -#define spherical_harmonics spherical_harmonics_L2 - -/* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ -vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) -{ - vec3 sh = vec3(0.0); - - sh += 0.282095 * shcoefs[0]; - - sh += -0.488603 * N.z * shcoefs[1]; - sh += 0.488603 * N.y * shcoefs[2]; - sh += -0.488603 * N.x * shcoefs[3]; - - return sh; -} - -vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) -{ - vec3 sh = vec3(0.0); - - sh += 0.282095 * shcoefs[0]; - - sh += -0.488603 * N.z * shcoefs[1]; - sh += 0.488603 * N.y * shcoefs[2]; - sh += -0.488603 * N.x * shcoefs[3]; - - sh += 1.092548 * N.x * N.z * shcoefs[4]; - sh += -1.092548 * N.z * N.y * shcoefs[5]; - sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; - sh += -1.092548 * N.x * N.y * shcoefs[7]; - sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; - - return sh; -} - -vec3 hl2_basis(vec3 N, vec3 cubesides[3]) -{ - vec3 irradiance = vec3(0.0); - - vec3 n_squared = N * N; - - irradiance += n_squared.x * cubesides[0]; - irradiance += n_squared.y * cubesides[1]; - irradiance += n_squared.z * cubesides[2]; - - return irradiance; -} - -vec3 compute_irradiance(vec3 N, IrradianceData ird) -{ -#if defined(IRRADIANCE_CUBEMAP) - return ird.color; -#elif defined(IRRADIANCE_SH_L2) - return spherical_harmonics_L2(N, ird.shcoefs); -#else /* defined(IRRADIANCE_HL2) */ - return hl2_basis(N, ird.cubesides); -#endif -} - vec3 get_specular_dominant_dir(vec3 N, vec3 R, float roughness) { float smoothness = 1.0 - roughness; diff --git a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl new file mode 100644 index 00000000000..0f95d552d1f --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl @@ -0,0 +1,141 @@ + +uniform sampler2D irradianceGrid; + +#ifdef IRRADIANCE_CUBEMAP +struct IrradianceData { + vec3 color; +}; +#elif defined(IRRADIANCE_SH_L2) +struct IrradianceData { + vec3 shcoefs[9]; +}; +#else /* defined(IRRADIANCE_HL2) */ +struct IrradianceData { + vec3 cubesides[3]; +}; +#endif + +IrradianceData load_irradiance_cell(int cell, vec3 N) +{ + /* Keep in sync with diffuse_filter_probe() */ + +#if defined(IRRADIANCE_CUBEMAP) + + #define AMBIANT_CUBESIZE 8 + ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); + int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; + cell_co.x *= cell % cell_per_row; + cell_co.y *= cell / cell_per_row; + + vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); + + vec2 uvs = mapping_octahedron(N, texelSize); + uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); + uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); + + IrradianceData ir; + ir.color = texture(irradianceGrid, uvs).rgb; + +#elif defined(IRRADIANCE_SH_L2) + + ivec2 cell_co = ivec2(3, 3); + int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; + cell_co.x *= cell % cell_per_row; + cell_co.y *= cell / cell_per_row; + + ivec3 ofs = ivec3(0, 1, 2); + + IrradianceData ir; + ir.shcoefs[0] = texelFetch(irradianceGrid, cell_co + ofs.xx, 0).rgb; + ir.shcoefs[1] = texelFetch(irradianceGrid, cell_co + ofs.yx, 0).rgb; + ir.shcoefs[2] = texelFetch(irradianceGrid, cell_co + ofs.zx, 0).rgb; + ir.shcoefs[3] = texelFetch(irradianceGrid, cell_co + ofs.xy, 0).rgb; + ir.shcoefs[4] = texelFetch(irradianceGrid, cell_co + ofs.yy, 0).rgb; + ir.shcoefs[5] = texelFetch(irradianceGrid, cell_co + ofs.zy, 0).rgb; + ir.shcoefs[6] = texelFetch(irradianceGrid, cell_co + ofs.xz, 0).rgb; + ir.shcoefs[7] = texelFetch(irradianceGrid, cell_co + ofs.yz, 0).rgb; + ir.shcoefs[8] = texelFetch(irradianceGrid, cell_co + ofs.zz, 0).rgb; + +#else /* defined(IRRADIANCE_HL2) */ + + ivec2 cell_co = ivec2(3, 2); + int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; + cell_co.x *= cell % cell_per_row; + cell_co.y *= cell / cell_per_row; + + ivec3 is_negative = ivec3(step(0.0, -N)); + + IrradianceData ir; + ir.cubesides[0] = texelFetch(irradianceGrid, cell_co + ivec2(0, is_negative.x), 0).rgb; + ir.cubesides[1] = texelFetch(irradianceGrid, cell_co + ivec2(1, is_negative.y), 0).rgb; + ir.cubesides[2] = texelFetch(irradianceGrid, cell_co + ivec2(2, is_negative.z), 0).rgb; + +#endif + + return ir; +} + +/* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ +vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) +{ + vec3 sh = vec3(0.0); + + sh += 0.282095 * shcoefs[0]; + + sh += -0.488603 * N.z * shcoefs[1]; + sh += 0.488603 * N.y * shcoefs[2]; + sh += -0.488603 * N.x * shcoefs[3]; + + return sh; +} + +vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) +{ + vec3 sh = vec3(0.0); + + sh += 0.282095 * shcoefs[0]; + + sh += -0.488603 * N.z * shcoefs[1]; + sh += 0.488603 * N.y * shcoefs[2]; + sh += -0.488603 * N.x * shcoefs[3]; + + sh += 1.092548 * N.x * N.z * shcoefs[4]; + sh += -1.092548 * N.z * N.y * shcoefs[5]; + sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; + sh += -1.092548 * N.x * N.y * shcoefs[7]; + sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; + + return sh; +} + +vec3 hl2_basis(vec3 N, vec3 cubesides[3]) +{ + vec3 irradiance = vec3(0.0); + + vec3 n_squared = N * N; + + irradiance += n_squared.x * cubesides[0]; + irradiance += n_squared.y * cubesides[1]; + irradiance += n_squared.z * cubesides[2]; + + return irradiance; +} + +vec3 compute_irradiance(vec3 N, IrradianceData ird) +{ +#if defined(IRRADIANCE_CUBEMAP) + return ird.color; +#elif defined(IRRADIANCE_SH_L2) + return spherical_harmonics_L2(N, ird.shcoefs); +#else /* defined(IRRADIANCE_HL2) */ + return hl2_basis(N, ird.cubesides); +#endif +} + +vec3 get_cell_color(ivec3 localpos, ivec3 gridres, int offset, vec3 ir_dir) +{ + /* Keep in sync with update_irradiance_probe */ + int cell = offset + localpos.z + localpos.y * gridres.z + localpos.x * gridres.z * gridres.y; + IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); + return compute_irradiance(ir_dir, ir_data); +} 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 6dd9bbcdf6c..6bd2e3f4822 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -6,8 +6,8 @@ uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrixInverse; uniform sampler2DArray probeCubes; -uniform sampler2D irradianceGrid; uniform float lodMax; +uniform bool specToggle; #ifndef UTIL_TEX #define UTIL_TEX @@ -185,6 +185,8 @@ void light_shade( specular = direct_ggx_point(sd, roughness, f0); } #endif + + specular *= float(specToggle); } #endif @@ -310,88 +312,6 @@ float probe_attenuation(vec3 W, ProbeData pd) return fac; } -IrradianceData load_irradiance_cell(int cell, vec3 N) -{ - /* Keep in sync with diffuse_filter_probe() */ - -#if defined(IRRADIANCE_CUBEMAP) - - #define AMBIANT_CUBESIZE 8 - ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); - int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; - cell_co.x *= cell % cell_per_row; - cell_co.y *= cell / cell_per_row; - - vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); - - vec2 uvs = mapping_octahedron(N, texelSize); - uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); - uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); - - IrradianceData ir; - ir.color = texture(irradianceGrid, uvs).rgb; - -#elif defined(IRRADIANCE_SH_L2) - - ivec2 cell_co = ivec2(3, 3); - int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; - cell_co.x *= cell % cell_per_row; - cell_co.y *= cell / cell_per_row; - - ivec3 ofs = ivec3(0, 1, 2); - - IrradianceData ir; - ir.shcoefs[0] = texelFetch(irradianceGrid, cell_co + ofs.xx, 0).rgb; - ir.shcoefs[1] = texelFetch(irradianceGrid, cell_co + ofs.yx, 0).rgb; - ir.shcoefs[2] = texelFetch(irradianceGrid, cell_co + ofs.zx, 0).rgb; - ir.shcoefs[3] = texelFetch(irradianceGrid, cell_co + ofs.xy, 0).rgb; - ir.shcoefs[4] = texelFetch(irradianceGrid, cell_co + ofs.yy, 0).rgb; - ir.shcoefs[5] = texelFetch(irradianceGrid, cell_co + ofs.zy, 0).rgb; - ir.shcoefs[6] = texelFetch(irradianceGrid, cell_co + ofs.xz, 0).rgb; - ir.shcoefs[7] = texelFetch(irradianceGrid, cell_co + ofs.yz, 0).rgb; - ir.shcoefs[8] = texelFetch(irradianceGrid, cell_co + ofs.zz, 0).rgb; - -#else /* defined(IRRADIANCE_HL2) */ - - ivec2 cell_co = ivec2(3, 2); - int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; - cell_co.x *= cell % cell_per_row; - cell_co.y *= cell / cell_per_row; - - ivec3 is_negative = ivec3(step(0.0, -N)); - - IrradianceData ir; - ir.cubesides[0] = texelFetch(irradianceGrid, cell_co + ivec2(0, is_negative.x), 0).rgb; - ir.cubesides[1] = texelFetch(irradianceGrid, cell_co + ivec2(1, is_negative.y), 0).rgb; - ir.cubesides[2] = texelFetch(irradianceGrid, cell_co + ivec2(2, is_negative.z), 0).rgb; - -#endif - - return ir; -} - -vec3 get_cell_color(ivec3 localpos, ivec3 gridres, int offset, vec3 ir_dir) -{ - /* Keep in sync with update_irradiance_probe */ - - int cell = offset + localpos.z + localpos.y * gridres.z + localpos.x * gridres.z * gridres.y; - IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); - return compute_irradiance(ir_dir, ir_data); -} - -vec3 trilinear_filtering(vec3 weights, - vec3 cell0_col, vec3 cell_x_col, vec3 cell_y_col, vec3 cell_z_col, vec3 cell_xy_col, vec3 cell_xz_col, vec3 cell_yz_col, vec3 cell_xyz_col) -{ - vec3 x_mix_0 = mix(cell0_col, cell_x_col, weights.x); - vec3 x_mix_y = mix(cell_y_col, cell_xy_col, weights.x); - vec3 x_mix_z = mix(cell_z_col, cell_xz_col, weights.x); - vec3 x_mix_yz = mix(cell_yz_col, cell_xyz_col, weights.x); - vec3 y_mix_0 = mix(x_mix_0, x_mix_y, weights.y); - vec3 y_mix_z = mix(x_mix_z, x_mix_yz, weights.y); - vec3 z_mix1 = mix(y_mix_0, y_mix_z, weights.z); - return z_mix1; -} - vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, float ao) { roughness = clamp(roughness, 1e-8, 0.9999); @@ -413,7 +333,7 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, #endif - /* Analitic Lights */ + /* Analytic Lights */ for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) { LightData ld = lights_data[i]; vec3 diff, spec; @@ -496,7 +416,7 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, float weight = trilinear.x * trilinear.y * trilinear.z; /* Smooth backface test */ - // weight *= max(0.005, dot(ws_light, sd.N)); + // weight *= sqrt(max(0.002, dot(ws_light, sd.N))); /* Avoid zero weight */ weight = max(0.00001, weight); @@ -509,12 +429,12 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, vec3 indirect_diffuse = irradiance_accum / weight_accum; - // float influ_diff = min(fade, (1.0 - spec_accum.a)); - float influ_diff = min(1.0, (1.0 - spec_accum.a)); + float influ_diff = min(fade, (1.0 - diff_accum.a)); diff_accum.rgb += indirect_diffuse * influ_diff; diff_accum.a += influ_diff; + /* For Debug purpose */ // return texture(irradianceGrid, sd.W.xy).rgb; } } @@ -533,7 +453,7 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, } vec3 indirect_radiance = - spec_accum.rgb * F_ibl(f0, brdf_lut) + + spec_accum.rgb * F_ibl(f0, brdf_lut) * float(specToggle) + diff_accum.rgb * albedo; return radiance + indirect_radiance * ao; |