Eevee: Correct Mipmap texel alignment.
Since we are working with non power of 2 textures, the mipmap level UV does not line up perfectly. This resulted in skewed filtering and bad sampling of the min/max depth buffer.
This commit is contained in:
parent
e0078cd953
commit
292f5ab758
|
@ -493,6 +493,17 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
|||
(int)viewport_size[0] / 2, (int)viewport_size[1] / 2,
|
||||
&texmin, 1);
|
||||
|
||||
/* Compute Mipmap texel alignement. */
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
float mip_size[2] = {viewport_size[0], viewport_size[1]};
|
||||
for (int j = 0; j < i; ++j) {
|
||||
mip_size[0] = floorf(fmaxf(1.0f, mip_size[0] / 2.0f));
|
||||
mip_size[1] = floorf(fmaxf(1.0f, mip_size[1] / 2.0f));
|
||||
}
|
||||
stl->g_data->mip_ratio[i][0] = viewport_size[0] / (mip_size[0] * powf(2.0f, floorf(log2f(floorf(viewport_size[0] / mip_size[0])))));
|
||||
stl->g_data->mip_ratio[i][1] = viewport_size[1] / (mip_size[1] * powf(2.0f, floorf(log2f(floorf(viewport_size[1] / mip_size[1])))));
|
||||
}
|
||||
|
||||
/* Cannot define 2 depth texture for one framebuffer. So allocate ourself. */
|
||||
if (txl->maxzbuffer == NULL) {
|
||||
txl->maxzbuffer = DRW_texture_create_2D((int)viewport_size[0] / 2, (int)viewport_size[1] / 2, DRW_TEX_DEPTH_24, DRW_TEX_MIPMAP, NULL);
|
||||
|
@ -754,6 +765,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
|||
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
|
||||
DRW_shgroup_uniform_buffer(grp, "minzBuffer", &stl->g_data->minzbuffer);
|
||||
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
|
||||
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
|
||||
DRW_shgroup_uniform_vec4(grp, "ssrParameters", &effects->ssr_quality, 1);
|
||||
DRW_shgroup_uniform_int(grp, "rayCount", &effects->ssr_ray_count, 1);
|
||||
DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
|
||||
|
@ -773,6 +785,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
|||
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
|
||||
DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
|
||||
DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
|
||||
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
|
||||
DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1);
|
||||
DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1);
|
||||
DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
|
||||
|
|
|
@ -470,6 +470,8 @@ typedef struct EEVEE_PrivateData {
|
|||
float viewvecs[2][4];
|
||||
/* For planar probes */
|
||||
float texel_size[2];
|
||||
/* To correct mip level texel mis-alignement */
|
||||
float mip_ratio[10][2]; /* TODO put in a UBO */
|
||||
/* For double buffering */
|
||||
bool valid_double_buffer;
|
||||
float prev_persmat[4][4];
|
||||
|
|
|
@ -27,6 +27,8 @@ flat in int shFace; /* Shadow layer we are rendering to. */
|
|||
#define ViewMatrix FaceViewMatrix[shFace]
|
||||
#endif
|
||||
|
||||
uniform vec2 mipRatio[10];
|
||||
|
||||
#define cameraForward normalize(ViewMatrixInverse[2].xyz)
|
||||
#define cameraPos ViewMatrixInverse[3].xyz
|
||||
#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
|
||||
|
|
|
@ -307,6 +307,10 @@ vec4 get_ssr_sample(
|
|||
/* Estimate a cone footprint to sample a corresponding mipmap level. */
|
||||
float mip = BRDF_BIAS * clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, MAX_MIP) - 1.0;
|
||||
|
||||
/* Correct UVs for mipmaping mis-alignment */
|
||||
float low_mip = floor(mip);
|
||||
ref_uvs *= mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
|
||||
|
||||
/* Slide 54 */
|
||||
float bsdf = bsdf_ggx(N, L, V, roughnessSquared);
|
||||
float weight = step(1e-8, hit_co_pdf.w) * bsdf / max(1e-8, hit_co_pdf.w);
|
||||
|
|
|
@ -18,6 +18,8 @@ float sample_depth(vec2 uv, int index, float lod)
|
|||
return textureLod(planarDepth, vec3(uv, index), 0.0).r;
|
||||
}
|
||||
else {
|
||||
/* Correct UVs for mipmaping mis-alignment */
|
||||
uv *= mipRatio[int(lod + 1.0)];
|
||||
return textureLod(maxzBuffer, uv, lod).r;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue