Skip to content

Commit

Permalink
[Lighting] For the directional light, the color and intensity are no …
Browse files Browse the repository at this point in the history
…longer ad hoc, they are now derived from the atmospheric scattering texture (which uses the ad hoc values to begin with)
  • Loading branch information
PanosK92 committed Nov 20, 2023
1 parent a30d952 commit 376fa01
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 71 deletions.
10 changes: 10 additions & 0 deletions data/shaders/common_structs.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ struct Light
n_dot_l = saturate(dot(surface_normal, -to_pixel)); // Pre-compute n_dot_l since it's used in many places
attenuation = compute_attenuation(surface_position);

// we are doing IBL from an atmospheric scattering texture, so we sample that
if (light_is_directional())
{
float2 uv = direction_sphere_uv(-forward);
uint mip_level = ENVIRONMENT_MAX_MIP - 3; // instead of taking multiple samples around the direction of the
// sun, we'll use a blurry mip to "capture" more light from that direction
color = tex_environment.SampleLevel(samplers[sampler_trilinear_clamp], uv, mip_level).rgb;
intensity = luminance(color) * 20.0f;
}

// apply occlusion
float occlusion_factor = is_ssgi_enabled() ? occlusion : 1.0;
radiance = color * intensity * attenuation * n_dot_l * occlusion_factor;
Expand Down
33 changes: 17 additions & 16 deletions data/shaders/common_vertex_simulation.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,36 @@ struct vertex_simulation
static const float3 base_wind_direction = float3(1, 0, 0);
static const float wind_vertex_sway_extent = 0.4f; // oscillation amplitude
static const float wind_vertex_sway_speed = 4.0f; // oscillation frequency

// base oscillation, a combination of two since ways with a phase difference of
// base oscillation, a combination of two sine waves with a phase difference
float phase_offset = float(instance_id) * PI_HALF;
float phase1 = (time * wind_vertex_sway_speed) + position_vertex.x + phase_offset;
float phase_diff = PI / 4.0f; // not a multiple of half pi to avoid total cancelation
float phase2 = phase1 + phase_diff;
float base_wave1 = sin(phase1);
float base_wave2 = sin(phase2);

// phase difference to ensure continuous motion
float phase_diff = PI / 3.0f; // choosing a non-half-multiples of PI to avoid total cancellation
float phase2 = phase1 + phase_diff;
float base_wave1 = sin(phase1);
float base_wave2 = sin(phase2);

// perlin noise for low-frequency wind changes
float low_freq_noise = perlin_noise(time * 0.1f);
float wind_direction_factor = lerp(-1.0f, 1.0f, low_freq_noise);
float3 wind_direction = base_wind_direction * wind_direction_factor;

// high-frequency perlin noise for flutter
float high_freq_noise = perlin_noise(position_vertex.x * 10.0f + time * 10.0f) - 0.5f;

// combine all factors
float combined_wave = (base_wave1 + base_wave2 + high_freq_noise) / 3.0f;

// reduce sway at the bottom, increase at the top
float sway_factor = saturate((position_vertex.y - animation_pivot.y) / buffer_material.world_space_height);

// calculate final offset
float3 offset = wind_direction * combined_wave * wind_vertex_sway_extent * sway_factor;

position_vertex.xyz += offset;

return position_vertex;
}
};
Expand All @@ -78,16 +80,15 @@ struct vertex_simulation
{
static float3 apply(float3 position_vertex, float time)
{
static const float base_wave_height = 0.1f;
static const float base_wave_frequency = 20.0f;
static const float base_wave_speed = 0.5f;
static const float3 base_wave_direction = float3(1.0f, 0.0f, 0.0f);
static const float base_wave_height = 0.06f;
static const float base_wave_frequency = 20.0f;
static const float base_wave_speed = 0.5f;

// interleave 4 waves to have a more complex wave pattern
float3 offset = float3(0.0f, 0.0f, 0.0f);
for (int i = 0; i < 4; i++)
{
// Modulate base wave parameters based on index
// modulate base wave parameters based on index
float wave_height = base_wave_height * (0.75f + i * 0.1f);
float wave_frequency = base_wave_frequency * (0.9f + i * 0.05f);
float wave_speed = base_wave_speed * (0.9f + i * 0.05f);
Expand Down
2 changes: 1 addition & 1 deletion editor/ImGui/Implementation/ImGui_TransformGizmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ namespace ImGui::TransformGizmo
if (Spartan::Input::GetKeyUp(Spartan::KeyCode::Click_Left))
{
Spartan::CommandStack::Add<Spartan::CommandTransform>(entity.get(), position_previous, rotation_previous, scale_previous);
first_use = true;
}
}
}

static bool allow_picking()
{
first_use = true;
return !ImGuizmo::IsOver() && !ImGuizmo::IsUsing();
}
}
2 changes: 1 addition & 1 deletion runtime/RHI/RHI_Implemenation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace Spartan
bool RHI_Context::validation = true;
bool RHI_Context::gpu_markers = true;
bool RHI_Context::gpu_profiling = true;
bool RHI_Context::renderdoc = true;
bool RHI_Context::renderdoc = false;
#else
bool RHI_Context::validation = false;
bool RHI_Context::gpu_markers = false;
Expand Down
3 changes: 2 additions & 1 deletion runtime/Rendering/Renderer_Passes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ namespace Spartan
cmd_list->SetTexture(Renderer_BindingsUav::tex2, tex_specular);
cmd_list->SetTexture(Renderer_BindingsUav::tex3, tex_volumetric);
cmd_list->SetTexture(Renderer_BindingsSrv::ssgi, GetRenderTarget(Renderer_RenderTexture::ssgi_filtered));

// set shadow maps
if (light->GetShadowsEnabled())
{
Expand All @@ -979,6 +979,7 @@ namespace Spartan
{
cmd_list->SetTexture(Renderer_BindingsSrv::light_directional_depth, light->GetDepthTexture());
cmd_list->SetTexture(Renderer_BindingsSrv::light_directional_color, tex_color);
cmd_list->SetTexture(Renderer_BindingsSrv::environment, GetRenderTarget(Renderer_RenderTexture::atmospheric_scattering));
}
else if (light->GetLightType() == LightType::Point)
{
Expand Down
2 changes: 1 addition & 1 deletion runtime/Rendering/Renderer_Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ namespace Spartan
}
else if (type == Renderer_MeshType::Grid)
{
uint32_t resolution = 1000;
uint32_t resolution = 2000;
Geometry::CreateGrid(&vertices, &indices, resolution);
mesh->SetResourceFilePath(project_directory + "standard_grid" + EXTENSION_MODEL);
}
Expand Down
23 changes: 10 additions & 13 deletions runtime/World/Components/PhysicsBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ namespace Spartan
}
}

Spartan::Math::Vector3 PhysicsBody::GetLinearVelocity() const
Vector3 PhysicsBody::GetLinearVelocity() const
{
if (!m_rigid_body)
return Vector3::Zero;
Expand Down Expand Up @@ -808,19 +808,16 @@ namespace Spartan
return;
}

terrain_width = terrain->GetHeightMap()->GetWidth();
terrain_length = terrain->GetHeightMap()->GetHeight();

btHeightfieldTerrainShape* shape_local = new btHeightfieldTerrainShape(
terrain_width, // width
terrain_length, // length
terrain->GetHeightData(), // data - row major
1.0f, // height scale
terrain->GetMinY(), // min height
terrain->GetMaxY(), // max height
1, // Up axis (0=x, 1=y, 2=z)
PHY_FLOAT, // Data type
false // Flip quad edges or not
terrain->GetHeightMap()->GetWidth(), // width
terrain->GetHeightMap()->GetHeight(), // length
terrain->GetHeightData(), // data - row major
1.0f, // height scale
terrain->GetMinY(), // min height
terrain->GetMaxY(), // max height
1, // Up axis (0=x, 1=y, 2=z)
PHY_FLOAT, // Data type
false // Flip quad edges or not
);

shape_local->setLocalScaling(ToBtVector3(size));
Expand Down
75 changes: 37 additions & 38 deletions runtime/World/Components/Terrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

//= INCLUDES ============================
#include "pch.h"
#include <cfloat>
#include "Terrain.h"
#include "Renderable.h"
#include "../Entity.h"
Expand All @@ -40,41 +39,41 @@ using namespace Spartan::Math;
namespace Spartan
{
namespace
{
static bool load_and_normalize_height_data(vector<float>& height_data_out, shared_ptr<RHI_Texture> height_texture, float min_y, float max_y)
{
vector<std::byte> height_data = height_texture->GetMip(0, 0).bytes;

// if the data is not there, load it
if (height_data.empty())
bool generate_height_points_from_height_map(vector<float>& height_data_out, shared_ptr<RHI_Texture> height_texture, float min_y, float max_y)
{
if (height_texture->LoadFromFile(height_texture->GetResourceFilePath()))
{
height_data = height_texture->GetMip(0, 0).bytes;
vector<byte> height_data = height_texture->GetMip(0, 0).bytes;

if (height_data.empty())
// if the data is not there, load it
if (height_data.empty())
{
if (height_texture->LoadFromFile(height_texture->GetResourceFilePath()))
{
SP_LOG_ERROR("Failed to load height map");
return false;
height_data = height_texture->GetMip(0, 0).bytes;

if (height_data.empty())
{
SP_LOG_ERROR("Failed to load height map");
return false;
}
}
}
}

// bytes per pixel
uint32_t bytes_per_pixel = (height_texture->GetChannelCount() * height_texture->GetBitsPerChannel()) / 8;
// bytes per pixel
uint32_t bytes_per_pixel = (height_texture->GetChannelCount() * height_texture->GetBitsPerChannel()) / 8;

// normalize and scale height data
height_data_out.resize(height_data.size() / bytes_per_pixel);
for (uint32_t i = 0; i < height_data.size(); i += bytes_per_pixel)
{
// assuming the height is stored in the red channel (first channel)
height_data_out[i / bytes_per_pixel] = min_y + (static_cast<float>(height_data[i]) / 255.0f) * (max_y - min_y);
}
// normalize and scale height data
height_data_out.resize(height_data.size() / bytes_per_pixel);
for (uint32_t i = 0; i < height_data.size(); i += bytes_per_pixel)
{
// assuming the height is stored in the red channel (first channel)
height_data_out[i / bytes_per_pixel] = min_y + (static_cast<float>(height_data[i]) / 255.0f) * (max_y - min_y);
}

return true;
}
return true;
}

static void generate_positions(vector<Vector3>& positions, const vector<float>& height_map, const uint32_t width, const uint32_t height)
void generate_positions(vector<Vector3>& positions, const vector<float>& height_map, const uint32_t width, const uint32_t height)
{
SP_ASSERT_MSG(!height_map.empty(), "Height map is empty");

Expand All @@ -96,7 +95,7 @@ namespace Spartan
}
}

static void generate_vertices_and_indices(vector<RHI_Vertex_PosTexNorTan>& vertices, vector<uint32_t>& indices, const vector<Vector3>& positions, const uint32_t width, const uint32_t height)
void generate_vertices_and_indices(vector<RHI_Vertex_PosTexNorTan>& vertices, vector<uint32_t>& indices, const vector<Vector3>& positions, const uint32_t width, const uint32_t height)
{
SP_ASSERT_MSG(!positions.empty(), "Positions are empty");

Expand Down Expand Up @@ -141,23 +140,23 @@ namespace Spartan
vertices[index] = RHI_Vertex_PosTexNorTan(positions[index], Vector2(u + 1.0f / (width - 1), v + 1.0f / (height - 1)));

// bottom left of quad
index = index_bottom_left;
indices[k + 1] = index;
index = index_bottom_left;
indices[k + 1] = index;
vertices[index] = RHI_Vertex_PosTexNorTan(positions[index], Vector2(u, v + 1.0f / (height - 1)));

// top left of quad
index = index_top_left;
indices[k + 2] = index;
index = index_top_left;
indices[k + 2] = index;
vertices[index] = RHI_Vertex_PosTexNorTan(positions[index], Vector2(u, v));

// bottom right of quad
index = index_bottom_right;
indices[k + 3] = index;
index = index_bottom_right;
indices[k + 3] = index;
vertices[index] = RHI_Vertex_PosTexNorTan(positions[index], Vector2(u + 1.0f / (width - 1), v + 1.0f / (height - 1)));

// top left of quad
index = index_top_left;
indices[k + 4] = index;
index = index_top_left;
indices[k + 4] = index;
vertices[index] = RHI_Vertex_PosTexNorTan(positions[index], Vector2(u, v));

// top right of quad
Expand All @@ -170,7 +169,7 @@ namespace Spartan
}
}

static void generate_normals(const vector<uint32_t>& indices, vector<RHI_Vertex_PosTexNorTan>& vertices)
void generate_normals(const vector<uint32_t>& indices, vector<RHI_Vertex_PosTexNorTan>& vertices)
{
SP_ASSERT_MSG(!indices.empty(), "Indices are empty");
SP_ASSERT_MSG(!vertices.empty(), "Vertices are empty");
Expand Down Expand Up @@ -361,7 +360,7 @@ namespace Spartan
m_height_texture = height_map;
}

void Terrain::GenerateAsync(std::function<void()> on_complete)
void Terrain::GenerateAsync(function<void()> on_complete)
{
if (m_is_generating)
{
Expand All @@ -387,7 +386,7 @@ namespace Spartan
{
m_is_generating = true;

if (!load_and_normalize_height_data(m_height_data, m_height_texture, m_min_y, m_max_y))
if (!generate_height_points_from_height_map(m_height_data, m_height_texture, m_min_y, m_max_y))
{
m_is_generating = false;
return;
Expand Down

0 comments on commit 376fa01

Please sign in to comment.