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)))) +
|
||||
(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
|
||||
|
||||
#ifdef USE_MULTIVIEW
|
||||
|
|
@ -1675,31 +1691,32 @@ void fragment_shader(in SceneData scene_data) {
|
|||
uvw.z = float(slice);
|
||||
|
||||
if (uses_sh) {
|
||||
uvw.z *= 4.0; //SH textures use 4 times more data
|
||||
vec3 lm_light_l0;
|
||||
vec3 lm_light_l1n1;
|
||||
vec3 lm_light_l1_0;
|
||||
vec3 lm_light_l1p1;
|
||||
uvw.z *= 4.0; // SH textures use 4 times more data.
|
||||
vec3 lm_sh[4];
|
||||
|
||||
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_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_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_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[0] = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 0.0), lightmaps.data[ofs].light_texture_size).rgb;
|
||||
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_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_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 {
|
||||
lm_light_l0 = 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_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_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[0] = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
|
||||
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_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_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);
|
||||
float en = lightmaps.data[ofs].exposure_normalization;
|
||||
lm_sh[1] *= lm_sh[0] * 4.0;
|
||||
lm_sh[2] *= lm_sh[0] * 4.0;
|
||||
lm_sh[3] *= lm_sh[0] * 4.0;
|
||||
|
||||
ambient_light += lm_light_l0 * en;
|
||||
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);
|
||||
ambient_light += lm_light_l1p1 * n.x * (lm_light_l0 * en * 4.0);
|
||||
vec3 sampleIrradianceSh;
|
||||
|
||||
for (uint i = 0; i < 3; i++) {
|
||||
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 {
|
||||
if (sc_use_lightmap_bicubic_filter()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue