Merge pull request #96114 from BlueCube3310/sh-lightmap-packing
LightmapGI: Pack L1 SH coefficients for directional lightmaps
This commit is contained in:
commit
aa07333abe
|
@ -1803,22 +1803,22 @@ void main() {
|
|||
|
||||
#ifdef LIGHTMAP_BICUBIC_FILTER
|
||||
vec3 lm_light_l0 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), lightmap_texture_size).rgb;
|
||||
vec3 lm_light_l1n1 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), lightmap_texture_size).rgb;
|
||||
vec3 lm_light_l1_0 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), lightmap_texture_size).rgb;
|
||||
vec3 lm_light_l1p1 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), lightmap_texture_size).rgb;
|
||||
vec3 lm_light_l1n1 = (textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
|
||||
vec3 lm_light_l1_0 = (textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
|
||||
vec3 lm_light_l1p1 = (textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
|
||||
#else
|
||||
vec3 lm_light_l0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
|
||||
vec3 lm_light_l1n1 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb;
|
||||
vec3 lm_light_l1_0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
|
||||
vec3 lm_light_l1p1 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
|
||||
vec3 lm_light_l1n1 = (textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
||||
vec3 lm_light_l1_0 = (textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
||||
vec3 lm_light_l1p1 = (textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb - vec3(0.5)) * 2.0;
|
||||
#endif
|
||||
|
||||
vec3 n = normalize(lightmap_normal_xform * normal);
|
||||
|
||||
ambient_light += lm_light_l0 * lightmap_exposure_normalization;
|
||||
ambient_light += lm_light_l1n1 * n.y * lightmap_exposure_normalization;
|
||||
ambient_light += lm_light_l1_0 * n.z * lightmap_exposure_normalization;
|
||||
ambient_light += lm_light_l1p1 * n.x * lightmap_exposure_normalization;
|
||||
ambient_light += lm_light_l1n1 * n.y * (lm_light_l0 * lightmap_exposure_normalization * 4.0);
|
||||
ambient_light += lm_light_l1_0 * n.z * (lm_light_l0 * lightmap_exposure_normalization * 4.0);
|
||||
ambient_light += lm_light_l1p1 * n.x * (lm_light_l0 * lightmap_exposure_normalization * 4.0);
|
||||
#else
|
||||
#ifdef LIGHTMAP_BICUBIC_FILTER
|
||||
ambient_light += textureArray_bicubic(lightmap_textures, uvw, lightmap_texture_size).rgb * lightmap_exposure_normalization;
|
||||
|
|
|
@ -793,6 +793,35 @@ LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref<RDShade
|
|||
return BAKE_OK;
|
||||
}
|
||||
|
||||
LightmapperRD::BakeError LightmapperRD::_pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) {
|
||||
Vector<RD::Uniform> uniforms = dilate_or_denoise_common_uniforms(source_light_tex, dest_light_tex);
|
||||
|
||||
RID compute_shader_pack = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("pack_coeffs"));
|
||||
ERR_FAIL_COND_V(compute_shader_pack.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
|
||||
RID compute_shader_pack_pipeline = rd->compute_pipeline_create(compute_shader_pack);
|
||||
|
||||
RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_pack, 1);
|
||||
|
||||
RD::ComputeListID compute_list = rd->compute_list_begin();
|
||||
rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_pack_pipeline);
|
||||
rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
|
||||
rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1);
|
||||
push_constant.region_ofs[0] = 0;
|
||||
push_constant.region_ofs[1] = 0;
|
||||
Vector3i group_size(Math::division_round_up(atlas_size.x, 8), Math::division_round_up(atlas_size.y, 8), 1); //restore group size
|
||||
|
||||
for (int i = 0; i < atlas_slices; i++) {
|
||||
push_constant.atlas_slice = i;
|
||||
rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
|
||||
rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
|
||||
//no barrier, let them run all together
|
||||
}
|
||||
rd->compute_list_end();
|
||||
rd->free(compute_shader_pack);
|
||||
|
||||
return BAKE_OK;
|
||||
}
|
||||
|
||||
Error LightmapperRD::_store_pfm(RenderingDevice *p_rd, RID p_atlas_tex, int p_index, const Size2i &p_atlas_size, const String &p_name) {
|
||||
Vector<uint8_t> data = p_rd->texture_get_data(p_atlas_tex, p_index);
|
||||
Ref<Image> img = Image::create_from_data(p_atlas_size.width, p_atlas_size.height, false, Image::FORMAT_RGBAH, data);
|
||||
|
@ -2002,6 +2031,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
|
|||
}
|
||||
}
|
||||
|
||||
if (p_bake_sh) {
|
||||
SWAP(light_accum_tex, light_accum_tex2);
|
||||
BakeError error = _pack_l1(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices);
|
||||
if (unlikely(error != BAKE_OK)) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TEXTURES
|
||||
|
||||
for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
|
||||
|
|
|
@ -273,6 +273,7 @@ class LightmapperRD : public Lightmapper {
|
|||
|
||||
BakeError _dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
|
||||
BakeError _denoise(RenderingDevice *p_rd, Ref<RDShaderFile> &p_compute_shader, const RID &p_compute_base_uniform_set, PushConstant &p_push_constant, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, float p_denoiser_strength, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function, void *p_bake_userdata);
|
||||
BakeError _pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
|
||||
|
||||
Error _store_pfm(RenderingDevice *p_rd, RID p_atlas_tex, int p_index, const Size2i &p_atlas_size, const String &p_name);
|
||||
Ref<Image> _read_pfm(const String &p_name);
|
||||
|
|
|
@ -6,6 +6,7 @@ dilate = "#define MODE_DILATE";
|
|||
unocclude = "#define MODE_UNOCCLUDE";
|
||||
light_probes = "#define MODE_LIGHT_PROBES";
|
||||
denoise = "#define MODE_DENOISE";
|
||||
pack_coeffs = "#define MODE_PACK_L1_COEFFS";
|
||||
|
||||
#[compute]
|
||||
|
||||
|
@ -63,7 +64,7 @@ layout(rgba16f, set = 1, binding = 4) uniform restrict image2DArray accum_light;
|
|||
layout(set = 1, binding = 5) uniform texture2D environment;
|
||||
#endif
|
||||
|
||||
#if defined(MODE_DILATE) || defined(MODE_DENOISE)
|
||||
#if defined(MODE_DILATE) || defined(MODE_DENOISE) || defined(MODE_PACK_L1_COEFFS)
|
||||
layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_light;
|
||||
layout(set = 1, binding = 1) uniform texture2DArray source_light;
|
||||
#endif
|
||||
|
@ -1037,4 +1038,28 @@ void main() {
|
|||
imageStore(dest_light, ivec3(atlas_pos, lightmap_slice), vec4(denoised_rgb, input_light.a));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MODE_PACK_L1_COEFFS
|
||||
vec4 base_coeff = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice * 4), 0);
|
||||
|
||||
for (int i = 1; i < 4; i++) {
|
||||
vec4 c = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice * 4 + i), 0);
|
||||
|
||||
if (abs(base_coeff.r) > 0.0) {
|
||||
c.r /= (base_coeff.r * 8);
|
||||
}
|
||||
|
||||
if (abs(base_coeff.g) > 0.0) {
|
||||
c.g /= (base_coeff.g * 8);
|
||||
}
|
||||
|
||||
if (abs(base_coeff.b) > 0.0) {
|
||||
c.b /= (base_coeff.b * 8);
|
||||
}
|
||||
|
||||
c.rgb += vec3(0.5);
|
||||
c.rgb = clamp(c.rgb, vec3(0.0), vec3(1.0));
|
||||
imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice * 4 + i), c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -151,6 +151,14 @@ bool LightmapGIData::is_using_spherical_harmonics() const {
|
|||
return uses_spherical_harmonics;
|
||||
}
|
||||
|
||||
void LightmapGIData::_set_uses_packed_directional(bool p_enable) {
|
||||
_uses_packed_directional = p_enable;
|
||||
}
|
||||
|
||||
bool LightmapGIData::_is_using_packed_directional() const {
|
||||
return _uses_packed_directional;
|
||||
}
|
||||
|
||||
void LightmapGIData::set_capture_data(const AABB &p_bounds, bool p_interior, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree, float p_baked_exposure) {
|
||||
if (p_points.size()) {
|
||||
int pc = p_points.size();
|
||||
|
@ -255,6 +263,9 @@ void LightmapGIData::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &LightmapGIData::set_uses_spherical_harmonics);
|
||||
ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &LightmapGIData::is_using_spherical_harmonics);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_set_uses_packed_directional", "_uses_packed_directional"), &LightmapGIData::_set_uses_packed_directional);
|
||||
ClassDB::bind_method(D_METHOD("_is_using_packed_directional"), &LightmapGIData::_is_using_packed_directional);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &LightmapGIData::add_user);
|
||||
ClassDB::bind_method(D_METHOD("get_user_count"), &LightmapGIData::get_user_count);
|
||||
ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &LightmapGIData::get_user_path);
|
||||
|
@ -267,6 +278,7 @@ void LightmapGIData::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uses_spherical_harmonics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_uses_spherical_harmonics", "is_using_spherical_harmonics");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "probe_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_probe_data", "_get_probe_data");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "_uses_packed_directional", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_uses_packed_directional", "_is_using_packed_directional");
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
ClassDB::bind_method(D_METHOD("set_light_texture", "light_texture"), &LightmapGIData::set_light_texture);
|
||||
|
@ -1187,6 +1199,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
|
|||
}
|
||||
|
||||
gi_data->set_lightmap_textures(textures);
|
||||
gi_data->_set_uses_packed_directional(directional); // New SH lightmaps are packed automatically.
|
||||
gi_data->set_uses_spherical_harmonics(directional);
|
||||
|
||||
for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
|
||||
|
@ -1352,6 +1365,12 @@ void LightmapGI::_notification(int p_what) {
|
|||
switch (p_what) {
|
||||
case NOTIFICATION_POST_ENTER_TREE: {
|
||||
if (light_data.is_valid()) {
|
||||
ERR_FAIL_COND_MSG(
|
||||
light_data->is_using_spherical_harmonics() && !light_data->_is_using_packed_directional(),
|
||||
vformat(
|
||||
"%s (%s): The directional lightmap textures are stored in a format that isn't supported anymore. Please bake lightmaps again to make lightmaps display from this node again.",
|
||||
get_light_data()->get_path(), get_name()));
|
||||
|
||||
_assign_lightmaps();
|
||||
}
|
||||
} break;
|
||||
|
|
|
@ -49,6 +49,8 @@ class LightmapGIData : public Resource {
|
|||
bool uses_spherical_harmonics = false;
|
||||
bool interior = false;
|
||||
|
||||
bool _uses_packed_directional = false;
|
||||
|
||||
RID lightmap;
|
||||
AABB bounds;
|
||||
float baked_exposure = 1.0;
|
||||
|
@ -92,6 +94,9 @@ public:
|
|||
void set_uses_spherical_harmonics(bool p_enable);
|
||||
bool is_using_spherical_harmonics() const;
|
||||
|
||||
void _set_uses_packed_directional(bool p_enable);
|
||||
bool _is_using_packed_directional() const;
|
||||
|
||||
bool is_interior() const;
|
||||
float get_baked_exposure() const;
|
||||
|
||||
|
|
|
@ -1513,7 +1513,6 @@ void fragment_shader(in SceneData scene_data) {
|
|||
|
||||
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;
|
||||
|
@ -1521,23 +1520,23 @@ void fragment_shader(in SceneData scene_data) {
|
|||
|
||||
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;
|
||||
lm_light_l1_0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), lightmaps.data[ofs].light_texture_size).rgb;
|
||||
lm_light_l1p1 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.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;
|
||||
} 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;
|
||||
lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
|
||||
lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 3.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;
|
||||
}
|
||||
|
||||
vec3 n = normalize(lightmaps.data[ofs].normal_xform * normal);
|
||||
float en = lightmaps.data[ofs].exposure_normalization;
|
||||
|
||||
ambient_light += lm_light_l0 * en;
|
||||
ambient_light += lm_light_l1n1 * n.y * en;
|
||||
ambient_light += lm_light_l1_0 * n.z * en;
|
||||
ambient_light += lm_light_l1p1 * n.x * 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);
|
||||
|
||||
} else {
|
||||
if (sc_use_lightmap_bicubic_filter) {
|
||||
|
|
|
@ -1280,23 +1280,23 @@ void main() {
|
|||
|
||||
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;
|
||||
lm_light_l1_0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), lightmaps.data[ofs].light_texture_size).rgb;
|
||||
lm_light_l1p1 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.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;
|
||||
} 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;
|
||||
lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
|
||||
lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 3.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;
|
||||
}
|
||||
|
||||
vec3 n = normalize(lightmaps.data[ofs].normal_xform * normal);
|
||||
float exposure_normalization = lightmaps.data[ofs].exposure_normalization;
|
||||
|
||||
ambient_light += lm_light_l0 * exposure_normalization;
|
||||
ambient_light += lm_light_l1n1 * n.y * exposure_normalization;
|
||||
ambient_light += lm_light_l1_0 * n.z * exposure_normalization;
|
||||
ambient_light += lm_light_l1p1 * n.x * exposure_normalization;
|
||||
ambient_light += lm_light_l1n1 * n.y * (lm_light_l0 * exposure_normalization * 4.0);
|
||||
ambient_light += lm_light_l1_0 * n.z * (lm_light_l0 * exposure_normalization * 4.0);
|
||||
ambient_light += lm_light_l1p1 * n.x * (lm_light_l0 * exposure_normalization * 4.0);
|
||||
} else {
|
||||
if (sc_use_lightmap_bicubic_filter) {
|
||||
ambient_light += textureArray_bicubic(lightmap_textures[ofs], uvw, lightmaps.data[ofs].light_texture_size).rgb * lightmaps.data[ofs].exposure_normalization;
|
||||
|
|
Loading…
Reference in New Issue