mirror of https://github.com/godotengine/godot
LightmapGI: Use Geometrics technique for retrieving irradiance from SH
This commit is contained in:
parent
bdf625bd54
commit
90b5a3682a
|
|
@ -895,6 +895,22 @@ vec4 textureArray_bicubic(texture2DArray tex, vec3 uv, vec2 texture_size) {
|
||||||
return (g0(fuv.y) * (g0x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p0, uv.z)) + g1x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p1, uv.z)))) +
|
return (g0(fuv.y) * (g0x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p0, uv.z)) + g1x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p1, uv.z)))) +
|
||||||
(g1(fuv.y) * (g0x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p2, uv.z)) + g1x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p3, uv.z))));
|
(g1(fuv.y) * (g0x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p2, uv.z)) + g1x * texture(sampler2DArray(tex, SAMPLER_LINEAR_CLAMP), vec3(p3, uv.z))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/kayru/Probulator/blob/4a97a2b021eb2ca7ef696f4ddf36ba9a9432cbb6/Source/Probulator/SphericalHarmonics.h#L136-L151
|
||||||
|
// http://www.geomerics.com/wp-content/uploads/2015/08/CEDEC_Geomerics_ReconstructingDiffuseLighting1.pdf
|
||||||
|
float shEvaluateDiffuseL1Geomerics(vec4 sh, vec3 n) {
|
||||||
|
float R0 = sh.x;
|
||||||
|
|
||||||
|
vec3 R1 = 0.5f * sh.wyz;
|
||||||
|
float lenR1 = length(R1);
|
||||||
|
|
||||||
|
float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
|
||||||
|
|
||||||
|
float p = 1.0f + 2.0f * lenR1 / R0;
|
||||||
|
float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
|
||||||
|
|
||||||
|
return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
|
||||||
|
}
|
||||||
#endif //USE_LIGHTMAP
|
#endif //USE_LIGHTMAP
|
||||||
|
|
||||||
#ifdef USE_MULTIVIEW
|
#ifdef USE_MULTIVIEW
|
||||||
|
|
@ -1675,31 +1691,32 @@ void fragment_shader(in SceneData scene_data) {
|
||||||
uvw.z = float(slice);
|
uvw.z = float(slice);
|
||||||
|
|
||||||
if (uses_sh) {
|
if (uses_sh) {
|
||||||
uvw.z *= 4.0; //SH textures use 4 times more data
|
uvw.z *= 4.0; // SH textures use 4 times more data.
|
||||||
vec3 lm_light_l0;
|
vec3 lm_sh[4];
|
||||||
vec3 lm_light_l1n1;
|
|
||||||
vec3 lm_light_l1_0;
|
|
||||||
vec3 lm_light_l1p1;
|
|
||||||
|
|
||||||
if (sc_use_lightmap_bicubic_filter()) {
|
if (sc_use_lightmap_bicubic_filter()) {
|
||||||
lm_light_l0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 0.0), lightmaps.data[ofs].light_texture_size).rgb;
|
lm_sh[0] = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 0.0), lightmaps.data[ofs].light_texture_size).rgb;
|
||||||
lm_light_l1n1 = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 1.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
|
lm_sh[1] = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 1.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
|
||||||
lm_light_l1_0 = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
|
lm_sh[2] = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
|
||||||
lm_light_l1p1 = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
|
lm_sh[3] = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
|
||||||
} else {
|
} else {
|
||||||
lm_light_l0 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
|
lm_sh[0] = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
|
||||||
lm_light_l1n1 = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
lm_sh[1] = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
||||||
lm_light_l1_0 = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
lm_sh[2] = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
||||||
lm_light_l1p1 = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
lm_sh[3] = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 n = normalize(lightmaps.data[ofs].normal_xform * normal);
|
lm_sh[1] *= lm_sh[0] * 4.0;
|
||||||
float en = lightmaps.data[ofs].exposure_normalization;
|
lm_sh[2] *= lm_sh[0] * 4.0;
|
||||||
|
lm_sh[3] *= lm_sh[0] * 4.0;
|
||||||
|
|
||||||
ambient_light += lm_light_l0 * en;
|
vec3 sampleIrradianceSh;
|
||||||
ambient_light += lm_light_l1n1 * n.y * (lm_light_l0 * en * 4.0);
|
|
||||||
ambient_light += lm_light_l1_0 * n.z * (lm_light_l0 * en * 4.0);
|
for (uint i = 0; i < 3; i++) {
|
||||||
ambient_light += lm_light_l1p1 * n.x * (lm_light_l0 * en * 4.0);
|
sampleIrradianceSh[i] = shEvaluateDiffuseL1Geomerics(vec4(lm_sh[0][i], lm_sh[1][i], lm_sh[2][i], lm_sh[3][i]), normalize(lightmaps.data[ofs].normal_xform * normal));
|
||||||
|
}
|
||||||
|
|
||||||
|
ambient_light += sampleIrradianceSh * lightmaps.data[ofs].exposure_normalization;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (sc_use_lightmap_bicubic_filter()) {
|
if (sc_use_lightmap_bicubic_filter()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue