Skip to content

Commit

Permalink
[Water] Improved wave patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
PanosK92 committed Oct 25, 2023
1 parent 8974215 commit 96c4f99
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 32 deletions.
2 changes: 1 addition & 1 deletion data/shaders/common_vertex_operations.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ float4 compute_screen_space_position(Vertex_PosUvNorTan input, uint instance_id,

if (material_vertex_animate_water())
{
world_position = vertex_simulation::wave::apply(world_position, buffer_frame.time);
world_position = vertex_simulation::water_wave::apply(world_position, buffer_frame.time);
}

return mul(world_position, view_projection);
Expand Down
2 changes: 1 addition & 1 deletion data/shaders/g_buffer.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ PixelInputType mainVS(Vertex_PosUvNorTan input, uint instance_id : SV_InstanceID
output.position_ss_current = output.position;
output.position_ss_previous = compute_screen_space_position(input, instance_id, pass_get_transform_previous(), buffer_frame.view_projection_previous);
// normals
output.normal_world = normalize(mul(input.normal, (float3x3)buffer_pass.transform)).xyz;
output.normal_world = normalize(mul(input.normal, (float3x3)buffer_pass.transform)).xyz;
output.tangent_world = normalize(mul(input.tangent, (float3x3)buffer_pass.transform)).xyz;
// uv
output.uv = input.uv;
Expand Down
69 changes: 39 additions & 30 deletions data/shaders/vertex_simulation.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,6 @@ 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

// wind
static const float3 wind_direction = float3(1, 0, 0);
static const float wind_vertex_sway_extent = 0.1f; // oscillation amplitude
static const float wind_vertex_sway_speed = 4.0f; // oscillation frequency

// wave
static const float wave_height = 0.2f;
static const float wave_frequency = 10.0f;
static const float wave_speed = 0.5f;
static const float3 wave_direction = float3(1.0f, 0.0f, 0.0f);

struct vertex_simulation
{
struct wind
Expand All @@ -52,6 +41,10 @@ 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 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);
Expand All @@ -74,30 +67,46 @@ struct vertex_simulation
}
};

struct wave
struct water_wave
{
// gerstner waves

static float4 apply(float4 position_vertex, float time)
{
// gerstner wave equation
float k = PI2 / wave_frequency;
float w = sqrt(9.8f / k) * wave_speed;

// phase and amplitude
float phase = dot(wave_direction, position_vertex.xz) * k + time * w;
float c = cos(phase);
float s = sin(phase);

// calculate new position
float3 offset;
offset.x = wave_height * wave_direction.x * c;
offset.z = wave_height * wave_direction.z * c;
offset.y = wave_height * s;

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);

// 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
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);

// dynamically calculate wave direction based on index
float angle = 2.0f * 3.14159f * i / 4.0f;
float2 wave_direction = float2(cos(angle), sin(angle));

// gerstner wave equation
float k = 2 * 3.14159 / wave_frequency;
float w = sqrt(9.8f / k) * wave_speed;

// phase and amplitude
float phase = dot(wave_direction, position_vertex.xz) * k + time * w;
float c = cos(phase);
float s = sin(phase);

// calculate new position for this wave and add to the offset
offset.x += wave_height * wave_direction.x * c;
offset.z += wave_height * wave_direction.y * c;
offset.y += wave_height * s;
}

position_vertex.xz += offset.xz;
position_vertex.y += offset.y;

return position_vertex;
}
};
Expand Down

0 comments on commit 96c4f99

Please sign in to comment.