mirror of https://github.com/godotengine/godot
Merge 239f299d6c into 15ff450680
This commit is contained in:
commit
d5948d0d00
|
|
@ -812,34 +812,34 @@ 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;
|
||||
}
|
||||
// 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, bool p_shadowmask) {
|
||||
Vector<uint8_t> data = p_rd->texture_get_data(p_atlas_tex, p_index);
|
||||
|
|
@ -2259,13 +2259,13 @@ 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;
|
||||
}
|
||||
}
|
||||
// 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
|
||||
|
||||
|
|
|
|||
|
|
@ -282,7 +282,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);
|
||||
// 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, bool p_shadowmask);
|
||||
Ref<Image> _read_pfm(const String &p_name, bool p_shadowmask);
|
||||
|
|
|
|||
|
|
@ -6,7 +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";
|
||||
//pack_coeffs = "#define MODE_PACK_L1_COEFFS";
|
||||
|
||||
#[compute]
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ layout(rgba8, set = 1, binding = 5) uniform restrict writeonly image2DArray shad
|
|||
layout(set = 1, binding = 5) uniform texture2D environment;
|
||||
#endif
|
||||
|
||||
#if defined(MODE_DILATE) || defined(MODE_DENOISE) || defined(MODE_PACK_L1_COEFFS)
|
||||
#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
|
||||
|
|
@ -861,15 +861,19 @@ void main() {
|
|||
light_for_texture += light;
|
||||
|
||||
#ifdef USE_SH_LIGHTMAPS
|
||||
// These coefficients include the factored out SH evaluation, diffuse convolution, and final application, as well as the BRDF 1/PI and the spherical monte carlo factor.
|
||||
// LO: 1/(2*sqrtPI) * 1/(2*sqrtPI) * PI * PI * 1/PI = 0.25
|
||||
// L1: sqrt(3/(4*pi)) * sqrt(3/(4*pi)) * (PI*2/3) * (2 * PI) * 1/PI = 1.0
|
||||
// Note: This only works because we aren't scaling, rotating, or combing harmonics, we are just directing applying them in the shader.
|
||||
// Since we don't want to double attenuate the light we need to undo attenuation based on the surface
|
||||
// normal before encoding it into SH coefficients
|
||||
if (dot(normal, light_dir) > 0.0) {
|
||||
light /= dot(normal, light_dir);
|
||||
}
|
||||
|
||||
// Different coefficients are used because we are directly encoding point lights.
|
||||
// L0: Zero is used since the lighting should be able to attenuate to zero (at 90 degrees)
|
||||
// L1: 1 is to no increase or decrease the lights intensity. This should match dynamic lighting.
|
||||
float c[4] = float[](
|
||||
0.25, //l0
|
||||
0, //l0
|
||||
light_dir.y, //l1n1
|
||||
light_dir.z, //l1n0
|
||||
light_dir.z, //l1n0 (Should always be positive)
|
||||
light_dir.x //l1p1
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -204,13 +204,13 @@ 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// bool LightmapGIData::_is_using_packed_directional() const {
|
||||
// return _uses_packed_directional;
|
||||
// }
|
||||
|
||||
void LightmapGIData::update_shadowmask_mode(ShadowmaskMode p_mode) {
|
||||
RS::get_singleton()->lightmap_set_shadowmask_mode(lightmap, (RS::ShadowmaskMode)p_mode);
|
||||
|
|
@ -327,8 +327,8 @@ 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("_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);
|
||||
|
|
@ -343,7 +343,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");
|
||||
// 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);
|
||||
|
|
@ -807,7 +807,7 @@ void LightmapGI::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, f
|
|||
}
|
||||
}
|
||||
|
||||
LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask) const {
|
||||
LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask, bool p_compress) const {
|
||||
Vector<Ref<Image>> images;
|
||||
images.resize(p_is_shadowmask ? p_lightmapper->get_shadowmask_texture_count() : p_lightmapper->get_bake_texture_count());
|
||||
|
||||
|
|
@ -849,7 +849,7 @@ LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Li
|
|||
config->set_value("remap", "type", "CompressedTexture2DArray");
|
||||
if (!config->has_section_key("params", "compress/mode")) {
|
||||
// Do not override an existing compression mode.
|
||||
config->set_value("params", "compress/mode", 2);
|
||||
config->set_value("params", "compress/mode", p_compress ? 2 : 3);
|
||||
}
|
||||
config->set_value("params", "compress/channel_pack", 1);
|
||||
config->set_value("params", "mipmaps/generate", false);
|
||||
|
|
@ -1289,12 +1289,12 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
|
|||
const bool save_shadowmask = shadowmask_mode != LightmapGIData::SHADOWMASK_MODE_NONE && shadowmask_texture_count > 0;
|
||||
|
||||
// Save the lightmap atlases.
|
||||
BakeError save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename, lightmap_textures, false);
|
||||
BakeError save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename, lightmap_textures, false, false);
|
||||
ERR_FAIL_COND_V(save_err != BAKE_ERROR_OK, save_err);
|
||||
|
||||
if (save_shadowmask) {
|
||||
// Save the shadowmask atlases.
|
||||
save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename + "_shadow", shadowmask_textures, true);
|
||||
save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename + "_shadow", shadowmask_textures, true, true);
|
||||
ERR_FAIL_COND_V(save_err != BAKE_ERROR_OK, save_err);
|
||||
}
|
||||
|
||||
|
|
@ -1319,7 +1319,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
|
|||
}
|
||||
|
||||
gi_data->set_uses_spherical_harmonics(directional);
|
||||
gi_data->_set_uses_packed_directional(directional); // New SH lightmaps are packed automatically.
|
||||
// gi_data->_set_uses_packed_directional(directional); // New SH lightmaps are packed automatically.
|
||||
|
||||
for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
|
||||
Dictionary d = lightmapper->get_bake_mesh_userdata(i);
|
||||
|
|
@ -1485,12 +1485,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()));
|
||||
|
||||
// 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()));
|
||||
//
|
||||
if (last_owner && last_owner != get_owner()) {
|
||||
light_data->clear_users();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ private:
|
|||
bool uses_spherical_harmonics = false;
|
||||
bool interior = false;
|
||||
|
||||
bool _uses_packed_directional = false;
|
||||
// bool _uses_packed_directional = false;
|
||||
|
||||
RID lightmap;
|
||||
AABB bounds;
|
||||
|
|
@ -110,8 +110,8 @@ 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;
|
||||
// void _set_uses_packed_directional(bool p_enable);
|
||||
// bool _is_using_packed_directional() const;
|
||||
|
||||
void update_shadowmask_mode(ShadowmaskMode p_mode);
|
||||
ShadowmaskMode get_shadowmask_mode() const;
|
||||
|
|
@ -273,7 +273,7 @@ private:
|
|||
void _plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cell_size, const Vector3 *p_triangle);
|
||||
void _gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool> &positions_used, const AABB &p_bounds);
|
||||
|
||||
BakeError _save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask = false) const;
|
||||
BakeError _save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask = false, bool p_compress = false) const;
|
||||
|
||||
protected:
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
|
|
|
|||
|
|
@ -1690,23 +1690,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 - 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_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;
|
||||
} 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_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;
|
||||
}
|
||||
|
||||
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 * (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);
|
||||
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;
|
||||
|
||||
} else {
|
||||
if (sc_use_lightmap_bicubic_filter()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue