From 1dc2964b3b0e62a8954ae754bc6e1a7515a94d97 Mon Sep 17 00:00:00 2001 From: Panos Karabelas Date: Wed, 25 Oct 2023 03:21:19 +0100 Subject: [PATCH] [Wind] Introduced low and high frequency noise to the base sine waves for enchanced realism, also adjusted the phases so they they will not cancel it's other out --- data/shaders/vertex_simulation.hlsl | 43 ++++++++++++++---------- runtime/Rendering/Renderer_Resources.cpp | 2 +- runtime/World/World.cpp | 6 ++-- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/data/shaders/vertex_simulation.hlsl b/data/shaders/vertex_simulation.hlsl index 4a1dda2d2..454d80d3c 100644 --- a/data/shaders/vertex_simulation.hlsl +++ b/data/shaders/vertex_simulation.hlsl @@ -19,8 +19,6 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -// thse functions are shared between depth_prepass.hlsl and g_buffer.hlsl, this is because the calculations have to be exactly the same - struct vertex_simulation { struct wind @@ -41,28 +39,37 @@ struct vertex_simulation static float4 apply(uint instance_id, float4 position_vertex, float3 position_transform, float time) { - static const float3 wind_direction = float3(1, 0, 0); - static const float wind_vertex_sway_extent = 0.1f; // oscillation amplitude + 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 wave - float phase_offset = float(instance_id) * PI_HALF; - float base_wave1 = sin((time * wind_vertex_sway_speed) + position_vertex.x + phase_offset); - float base_wave2 = sin((time * wind_vertex_sway_speed * 0.8f) + position_vertex.x + phase_offset + PI_HALF); // out of phase - - // perlin noise - float noise_factor = perlin_noise(position_vertex.x * 0.1f + time) - 0.5f; - // combine base waves with noise - float combined_wave = (base_wave1 + base_wave2) * 0.5f + noise_factor; - - // don't sway at the bottom of the mesh, sway the most at the top + // base oscillation, a combination of two since ways with a phase difference of + 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); + + // 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 - position_transform.y) / buffer_material.world_space_height); // calculate final offset - float3 offset = wind_direction * (combined_wave + noise_factor) * wind_vertex_sway_extent * sway_factor; - + float3 offset = wind_direction * combined_wave * wind_vertex_sway_extent * sway_factor; + position_vertex.xyz += offset; + return position_vertex; } }; diff --git a/runtime/Rendering/Renderer_Resources.cpp b/runtime/Rendering/Renderer_Resources.cpp index 25e128ff3..41ca1ef22 100644 --- a/runtime/Rendering/Renderer_Resources.cpp +++ b/runtime/Rendering/Renderer_Resources.cpp @@ -510,7 +510,7 @@ namespace Spartan } else if (type == Renderer_MeshType::Grid) { - uint32_t resolution = 500; + uint32_t resolution = 1000; Geometry::CreateGrid(&vertices, &indices, resolution); mesh->SetResourceFilePath(project_directory + "standard_grid" + EXTENSION_MODEL); } diff --git a/runtime/World/World.cpp b/runtime/World/World.cpp index 953d0df36..de45c929b 100644 --- a/runtime/World/World.cpp +++ b/runtime/World/World.cpp @@ -860,7 +860,7 @@ namespace Spartan shared_ptr water = CreateEntity(); water->SetObjectName("water"); water->GetTransform()->SetPosition(Vector3(0.0f, terrain->GetWaterLevel(), 0.0f)); - water->GetTransform()->SetScale(Vector3(2000.0f, 1.0f, 2000.0f)); + water->GetTransform()->SetScale(Vector3(1100.0f, 1.0f, 1100.0f)); Renderable* renderable = water->AddComponent().get(); renderable->SetGeometry(Renderer_MeshType::Grid); @@ -874,8 +874,8 @@ namespace Spartan material->SetTexture(MaterialTexture::Normal, "project\\terrain\\water_normal_2.jpeg"); material->SetProperty(MaterialProperty::MultiplierRoughness, 0.2f); // just a bit of roughness to diffuse the sun a little material->SetProperty(MaterialProperty::MultiplierNormal, 0.3f); - material->SetProperty(MaterialProperty::TextureTilingX, 500.0f); - material->SetProperty(MaterialProperty::TextureTilingY, 500.0f); + material->SetProperty(MaterialProperty::TextureTilingX, 250.0f); + material->SetProperty(MaterialProperty::TextureTilingY, 250.0f); material->SetProperty(MaterialProperty::TextureAnimate, 1.0f); material->SetProperty(MaterialProperty::VertexAnimateWater, 1.0f);