64 lines
2.8 KiB
HLSL
64 lines
2.8 KiB
HLSL
|
|
float3 GerstnerWave(float3 position, float steepness, float wavelength, float speed, float direction, inout float3 tangent, inout float3 binormal, float globalOffset)
|
||
|
|
{
|
||
|
|
// Normalizar la dirección para la propagación de la ola
|
||
|
|
direction = direction * 2 - 1;
|
||
|
|
float2 d = normalize(float2(cos(3.14159 * direction), sin(3.14159 * direction)));
|
||
|
|
|
||
|
|
// Número de onda
|
||
|
|
float k = 2 * 3.14159 / wavelength;
|
||
|
|
|
||
|
|
// Calcular la fase de la ola, incluyendo el desplazamiento global
|
||
|
|
float f = k * (dot(d, position.xz) - speed * _Time.y + globalOffset);
|
||
|
|
|
||
|
|
// Amplitud de la ola
|
||
|
|
float a = steepness / k;
|
||
|
|
|
||
|
|
// Ajustar el tangente y el binormal para las normales
|
||
|
|
tangent += float3(
|
||
|
|
-d.x * d.x * (steepness * sin(f)),
|
||
|
|
d.x * (steepness * cos(f)),
|
||
|
|
-d.x * d.y * (steepness * sin(f))
|
||
|
|
);
|
||
|
|
|
||
|
|
binormal += float3(
|
||
|
|
-d.x * d.y * (steepness * sin(f)),
|
||
|
|
d.y * (steepness * cos(f)),
|
||
|
|
-d.y * d.y * (steepness * sin(f))
|
||
|
|
);
|
||
|
|
|
||
|
|
// Retornar el desplazamiento de la ola en el plano XZ y la altura vertical
|
||
|
|
return float3(
|
||
|
|
d.x * (a * cos(f)), // Desplazamiento en X
|
||
|
|
a * sin(f), // Desplazamiento en Y (altura)
|
||
|
|
d.y * (a * cos(f)) // Desplazamiento en Z
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
void GerstnerWaves_float(float3 position, float steepness, float wavelength, float speed, float4 directions, float tileSize, out float3 Offset, out float3 normal)
|
||
|
|
{
|
||
|
|
// Calcular el desplazamiento global para las olas en base a la posición absoluta
|
||
|
|
float globalOffsetX = floor(position.x / tileSize) * tileSize;
|
||
|
|
float globalOffsetZ = floor(position.z / tileSize) * tileSize;
|
||
|
|
|
||
|
|
// Envolver la posición X y Z usando fmod para asegurar el tileado, manteniendo el Y sin cambios
|
||
|
|
float3 tiledPosition = float3(
|
||
|
|
fmod(position.x, tileSize), // Envolver eje X
|
||
|
|
position.y, // Y sin cambios
|
||
|
|
fmod(position.z, tileSize) // Envolver eje Z
|
||
|
|
);
|
||
|
|
|
||
|
|
// Inicializar el desplazamiento y los vectores de tangente/binormal
|
||
|
|
Offset = float3(0, 0, 0);
|
||
|
|
float3 tangent = float3(1, 0, 0);
|
||
|
|
float3 binormal = float3(0, 0, 1);
|
||
|
|
|
||
|
|
// Aplicar las olas Gerstner a las direcciones, con el desplazamiento global en X y Z
|
||
|
|
Offset += GerstnerWave(tiledPosition, steepness, wavelength, speed, directions.x, tangent, binormal, globalOffsetX + globalOffsetZ);
|
||
|
|
Offset += GerstnerWave(tiledPosition, steepness, wavelength, speed, directions.y, tangent, binormal, globalOffsetX + globalOffsetZ);
|
||
|
|
Offset += GerstnerWave(tiledPosition, steepness, wavelength, speed, directions.z, tangent, binormal, globalOffsetX + globalOffsetZ);
|
||
|
|
Offset += GerstnerWave(tiledPosition, steepness, wavelength, speed, directions.w, tangent, binormal, globalOffsetX + globalOffsetZ);
|
||
|
|
|
||
|
|
// Normalizar el producto cruzado de binormal y tangente para obtener la normal
|
||
|
|
normal = normalize(cross(binormal, tangent));
|
||
|
|
}
|