diff --git a/prop_instance_merger.cpp b/prop_instance_merger.cpp index 2665dd0..655e854 100644 --- a/prop_instance_merger.cpp +++ b/prop_instance_merger.cpp @@ -407,6 +407,8 @@ void PropInstanceMerger::_build() { _job->reset_meshes(); } + _job->clear_lights(); + for (int i = 0; i < get_child_count(); ++i) { Node *n = get_child(i); diff --git a/prop_instance_prop_job.cpp b/prop_instance_prop_job.cpp index fec7aa2..419e57a 100644 --- a/prop_instance_prop_job.cpp +++ b/prop_instance_prop_job.cpp @@ -31,13 +31,13 @@ SOFTWARE. #endif #include "jobs/prop_mesher_job_step.h" +#include "lights/prop_light.h" #include "material_cache/prop_material_cache.h" #include "prop_instance.h" #include "prop_instance_merger.h" #include "prop_mesher.h" -#include "singleton/prop_cache.h" #include "scene/resources/shape.h" -#include "lights/prop_light.h" +#include "singleton/prop_cache.h" #ifdef MESH_DATA_RESOURCE_PRESENT #include "../mesh_data_resource/mesh_data_resource.h" @@ -132,7 +132,6 @@ void PropInstancePropJob::clear_meshes() { } #endif - void PropInstancePropJob::add_light(const Ref &light) { _prop_mesher->add_light(light); } @@ -188,8 +187,6 @@ void PropInstancePropJob::phase_physics_process() { } void PropInstancePropJob::phase_prop() { -#ifdef MESH_DATA_RESOURCE_PRESENT - if (!_prop_mesher.is_valid()) { set_complete(true); //So threadpool knows it's done return; @@ -203,6 +200,7 @@ void PropInstancePropJob::phase_prop() { return; } +#ifdef MESH_DATA_RESOURCE_PRESENT for (int i = 0; i < _prop_mesh_datas.size(); ++i) { PMDREntry &e = _prop_mesh_datas.write[i]; @@ -217,6 +215,7 @@ void PropInstancePropJob::phase_prop() { _prop_mesher->add_mesh_data_resource_transform(mesh, t, uvr); } +#endif if (_prop_mesher->get_vertex_count() == 0) { //reset_meshes(); @@ -232,60 +231,15 @@ void PropInstancePropJob::phase_prop() { } } - /* if (should_do()) { - if ((chunk->get_build_flags() & TerraChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) { - _prop_mesher->bake_colors(_chunk); + if ((_prop_mesher->get_build_flags() & PropMesher::BUILD_FLAG_USE_LIGHTING) != 0) { + _prop_mesher->bake_colors(); } if (should_return()) { return; } } -*/ - /* - //lights should be added here by the prop instance preemtively - //Also this system should use it's own lights - if (should_do()) { - if ((chunk->get_build_flags() & TerraChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) { - TerraWorldDefault *world = Object::cast_to(chunk->get_voxel_world()); - - if (world) { - for (int i = 0; i < chunk->mesh_data_resource_get_count(); ++i) { - if (!chunk->mesh_data_resource_get_is_inside(i)) { - Ref mdr = chunk->mesh_data_resource_get(i); - - ERR_CONTINUE(!mdr.is_valid()); - - Transform trf = chunk->mesh_data_resource_get_transform(i); - - Array arr = mdr->get_array(); - - if (arr.size() <= Mesh::ARRAY_VERTEX) { - continue; - } - - PoolVector3Array varr = arr[Mesh::ARRAY_VERTEX]; - - if (varr.size() == 0) { - continue; - } - - PoolColorArray carr = world->get_vertex_colors(trf, varr); - - get_prop_mesher()->add_mesh_data_resource_transform_colored(mdr, trf, carr, chunk->mesh_data_resource_get_uv_rect(i)); - } - } - } - } - - if (should_return()) { - return; - } - } - */ - -#endif reset_stages(); next_phase(); @@ -714,7 +668,7 @@ PropInstancePropJob::PropInstancePropJob() { //todo allocate this in a virtual method _prop_mesher.instance(); - //_prop_mesher->set_build_flags(PropMesher::BUILD_FLAG_USE_LIGHTING | PropMesher::BUILD_FLAG_USE_AO | PropMesher::BUILD_FLAG_USE_RAO | PropMesher::BUILD_FLAG_GENERATE_AO | PropMesher::BUILD_FLAG_AUTO_GENERATE_RAO | PropMesher::BUILD_FLAG_BAKE_LIGHTS); + _prop_mesher->set_build_flags(PropMesher::BUILD_FLAG_USE_LIGHTING | PropMesher::BUILD_FLAG_USE_AO | PropMesher::BUILD_FLAG_USE_RAO | PropMesher::BUILD_FLAG_BAKE_LIGHTS); } PropInstancePropJob::~PropInstancePropJob() { diff --git a/prop_mesher.cpp b/prop_mesher.cpp index 1d3d0f7..915a253 100644 --- a/prop_mesher.cpp +++ b/prop_mesher.cpp @@ -598,7 +598,7 @@ void PropMesher::generate_ao() { }*/ } -uint8_t PropMesher::get_random_ao(const Vector3 &position) { +float PropMesher::get_random_ao(const Vector3 &position) { float val = _noise->get_noise_3d(position.x, position.y, position.z); val *= _rao_scale_factor; @@ -609,7 +609,49 @@ uint8_t PropMesher::get_random_ao(const Vector3 &position) { if (val < 0) val = -val; - return static_cast(val * 255.0); + return val; +} + +Color PropMesher::get_light_color_at(const Vector3 &position, const Vector3 &normal) { + Vector3 v_lightDiffuse; + + //calculate the lights value + for (int i = 0; i < _lights.size(); ++i) { + Ref light = _lights.get(i); + + Vector3 lightDir = light->get_position() - position; + + float dist2 = lightDir.dot(lightDir); + //inverse sqrt + lightDir *= (1.0 / sqrt(dist2)); + + float NdotL = normal.dot(lightDir); + + if (NdotL > 1.0) { + NdotL = 1.0; + } else if (NdotL < 0.0) { + NdotL = 0.0; + } + + Color cc = light->get_color(); + Vector3 cv(cc.r, cc.g, cc.b); + + Vector3 value = cv * (NdotL / (1.0 + dist2)); + + value *= light->get_size(); + v_lightDiffuse += value; + + /* + float dist2 = Mathf.Clamp(Vector3.Distance(transformedLights[i], vertices), 0f, 15f); + dist2 /= 35f; + + Vector3 value = Vector3.one; + value *= ((float) lights[i].Strength) / 255f; + value *= (1 - dist2); + v_lightDiffuse += value;*/ + } + + return Color(v_lightDiffuse.x, v_lightDiffuse.y, v_lightDiffuse.z); } void PropMesher::add_mesher(const Ref &mesher) { @@ -671,63 +713,102 @@ PoolVector PropMesher::build_collider() const { } void PropMesher::bake_colors() { - //if ((get_build_flags() & TerraChunkDefault::BUILD_FLAG_USE_LIGHTING) == 0) - // return; - - /* - if (_vertices.size() == 0) + if ((get_build_flags() & PropMesher::BUILD_FLAG_USE_LIGHTING) == 0) { return; + } - uint8_t *channel_color_r = chunk->channel_get_valid(TerraChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R); - uint8_t *channel_color_g = chunk->channel_get_valid(TerraChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G); - uint8_t *channel_color_b = chunk->channel_get_valid(TerraChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B); - uint8_t *channel_ao = chunk->channel_get_valid(TerraChunkDefault::DEFAULT_CHANNEL_AO); - uint8_t *channel_rao = chunk->channel_get_valid(TerraChunkDefault::DEFAULT_CHANNEL_RANDOM_AO); + bool rao = (get_build_flags() & PropMesher::BUILD_FLAG_USE_RAO) != 0; + bool lights = (get_build_flags() & PropMesher::BUILD_FLAG_BAKE_LIGHTS) != 0; - Color base_light(_base_light_value, _base_light_value, _base_light_value); + if (rao && lights) { + bake_colors_lights_rao(); + return; + } + if (rao) { + bake_colors_rao(); + return; + } + + if (lights) { + bake_colors_lights(); + return; + } +} + +void PropMesher::bake_colors_rao() { for (int i = 0; i < _vertices.size(); ++i) { Vertex vertex = _vertices[i]; Vector3 vert = vertex.vertex; - unsigned int x = (unsigned int)(vert.x / _voxel_scale); - unsigned int z = (unsigned int)(vert.z / _voxel_scale); + Color light = Color(_base_light_value, _base_light_value, _base_light_value); - if (chunk->validate_data_position(x, z)) { - int indx = chunk->get_data_index(x, z); + float rao = get_random_ao(vert) * _ao_strength; - Color light = Color( - channel_color_r[indx] / 255.0, - channel_color_g[indx] / 255.0, - channel_color_b[indx] / 255.0); + light.r -= rao; + light.g -= rao; + light.b -= rao; - float ao = (channel_ao[indx] / 255.0) * _ao_strength; - float rao = channel_rao[indx] / 255.0; + light.r = CLAMP(light.r, 0, 1.0); + light.g = CLAMP(light.g, 0, 1.0); + light.b = CLAMP(light.b, 0, 1.0); - ao += rao; + Color c = vertex.color; + light.a = c.a; + vertex.color = light; - light.r += _base_light_value; - light.g += _base_light_value; - light.b += _base_light_value; + _vertices.set(i, vertex); + } +} +void PropMesher::bake_colors_lights_rao() { + for (int i = 0; i < _vertices.size(); ++i) { + Vertex vertex = _vertices[i]; + Vector3 vert = vertex.vertex; - light.r -= ao; - light.g -= ao; - light.b -= ao; + Color light = get_light_color_at(vert, vertex.normal); - light.r = CLAMP(light.r, 0, 1.0); - light.g = CLAMP(light.g, 0, 1.0); - light.b = CLAMP(light.b, 0, 1.0); + float rao = get_random_ao(vert) * _ao_strength; - Color c = vertex.color; - light.a = c.a; - vertex.color = light; + light.r += _base_light_value; + light.g += _base_light_value; + light.b += _base_light_value; - _vertices.set(i, vertex); - } else { - vertex.color = base_light; - _vertices.set(i, vertex); - } - }*/ + light.r -= rao; + light.g -= rao; + light.b -= rao; + + light.r = CLAMP(light.r, 0, 1.0); + light.g = CLAMP(light.g, 0, 1.0); + light.b = CLAMP(light.b, 0, 1.0); + + Color c = vertex.color; + light.a = c.a; + vertex.color = light; + + _vertices.set(i, vertex); + } +} +void PropMesher::bake_colors_lights() { + for (int i = 0; i < _vertices.size(); ++i) { + Vertex vertex = _vertices[i]; + Vector3 vert = vertex.vertex; + + Color light = get_light_color_at(vert, vertex.normal); + + light.r += _base_light_value; + light.g += _base_light_value; + light.b += _base_light_value; + + light.r = CLAMP(light.r, 0, 1.0); + light.g = CLAMP(light.g, 0, 1.0); + light.b = CLAMP(light.b, 0, 1.0); + + Color c = vertex.color; + light.a = c.a; + vertex.color = light; + + _vertices.set(i, vertex); + } } #ifdef TERRAMAN_PRESENT diff --git a/prop_mesher.h b/prop_mesher.h index 4720995..abaac2f 100644 --- a/prop_mesher.h +++ b/prop_mesher.h @@ -150,7 +150,8 @@ public: #endif void generate_ao(); - uint8_t get_random_ao(const Vector3 &position); + float get_random_ao(const Vector3 &position); + Color get_light_color_at(const Vector3 &position, const Vector3 &normal); void add_mesher(const Ref &mesher); void _add_mesher(const Ref &mesher); @@ -161,6 +162,9 @@ public: PoolVector build_collider() const; void bake_colors(); + void bake_colors_rao(); + void bake_colors_lights_rao(); + void bake_colors_lights(); #ifdef TERRAMAN_PRESENT void bake_lights(MeshInstance *node, Vector> &lights);