Skip to content

Commit dd18d9e

Browse files
committed
spring fluid: other random generator
1 parent 47955e3 commit dd18d9e

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

src/pages/spring-fluid/fragment.glsl

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const vec2 left = vec2(-1, 0);
1616

1717
uniform float k; // spring constant
1818
uniform float damping; // velocity damping
19-
const float scale = 1.0; // scale for reading/formatting velocity/offsets
19+
const float scale = 1.0f; // scale for reading/formatting velocity/offsets
2020
uniform float clamp_value; // clamp max velocity/offsets
2121
uniform float turbulence_factor; // turbulence strength multiplier [0 - 10]
2222

@@ -39,23 +39,57 @@ vec4 getPixel(vec2 coord) {
3939
}
4040

4141
vec2 getOffset(vec4 pixel) {
42-
return vec2(pixel.z * 2.0 - 1.0, pixel.a * 2.0 - 1.0) * scale;
42+
return vec2(pixel.z * 2.0f - 1.0f, pixel.a * 2.0f - 1.0f) * scale;
4343
}
4444

4545
vec2 getVelocity(vec4 pixel) {
46-
return vec2(pixel.x * 2.0 - 1.0, pixel.y * 2.0 - 1.0) * scale;
46+
return vec2(pixel.x * 2.0f - 1.0f, pixel.y * 2.0f - 1.0f) * scale;
4747
}
4848

4949
bool isEdgePixel(vec2 coord) {
50-
if(coord.x <= 1.0 || coord.x >= resolution.x - 1.0 || coord.y <= 1.0 || coord.y >= resolution.y - 1.0) return true;
51-
if (texture(obstacles, coord / resolution.xy).r > 0.5) return true;
50+
if(coord.x <= 1.0f || coord.x >= resolution.x - 1.0f || coord.y <= 1.0f || coord.y >= resolution.y - 1.0f)
51+
return true;
52+
if(texture(obstacles, coord / resolution.xy).r > 0.5f)
53+
return true;
5254
return false;
5355
}
5456

5557
// random number [0,1] inclusive
5658
float rand(vec2 identity) {
57-
vec2 seeded = identity + vec2(seed * 0.1, seed * 0.2);
58-
return fract(sin(dot(seeded, vec2(12.9898, 78.233))) * 43758.5453);
59+
vec2 seeded = identity + vec2(seed * 0.1f, seed * 0.2f);
60+
return fract(sin(dot(seeded, vec2(12.9898f, 78.233f))) * 43758.5453f);
61+
}
62+
63+
// A single iteration of Bob Jenkins' One-At-A-Time hashing algorithm for u32.
64+
uint hash_u32(uint x_in) {
65+
uint x = x_in;
66+
x += (x << 10u);
67+
x ^= (x >> 6u);
68+
x += (x << 3u);
69+
x ^= (x >> 11u);
70+
x += (x << 15u);
71+
return x;
72+
}
73+
74+
// Construct a float with half-open range [0:1] using low 23 bits.
75+
// All zeroes yields 0.0, all ones yields the next smallest representable value below 1.0.
76+
float float_construct_from_u32(uint m_in) {
77+
uint ieeeMantissa = 0x007FFFFFu; // binary32 mantissa bitmask
78+
uint ieeeOne = 0x3F800000u; // 1.0 in IEEE binary32
79+
80+
uint m = m_in;
81+
m &= ieeeMantissa; // Keep only mantissa bits (fractional part)
82+
m |= ieeeOne; // Add fractional part to 1.0
83+
84+
float f = uintBitsToFloat(m); // Range [1:2]
85+
return f - 1.0f; // Range [0:1]
86+
}
87+
88+
// Pseudo-random value in half-open range [0:1] from a f32 seed.
89+
// from https://marktension.nl/blog/my_favorite_wgsl_random_func_so_far/
90+
float random_uniform(vec2 identity) {
91+
float seeded = identity.x * seed * 0.1f + identity.y * seed * 0.2f;
92+
return float_construct_from_u32(hash_u32(floatBitsToUint(seeded)));
5993
}
6094

6195
vec2 updateForces(vec2 forces, vec2 position, vec2 direction) {
@@ -67,7 +101,7 @@ vec2 updateForces(vec2 forces, vec2 position, vec2 direction) {
67101

68102
vec2 spring_vec = n_position - position;
69103
float current_length = length(spring_vec);
70-
if (current_length > 0.001) { // avoid division by zero
104+
if(current_length > 0.001f) { // avoid division by zero
71105
vec2 spring_dir = spring_vec / current_length;
72106
float displacement = current_length - rest_length;
73107

@@ -81,17 +115,16 @@ vec2 updateForces(vec2 forces, vec2 position, vec2 direction) {
81115
}
82116

83117
vec2 format(vec2 v) {
84-
return clamp(v / scale * 0.5 + vec2(0.5), 0.0, 1.0);
118+
return clamp(v / scale * 0.5f + vec2(0.5f), 0.0f, 1.0f);
85119
}
86120

87-
88121
void main() {
89122
vec4 rgba = getPixel();
90123

91124
bool isEdge = isEdgePixel(gl_FragCoord.xy);
92125

93-
if (isEdge) {
94-
fragColor = vec4(0.5, 0.5, 0.5, 0.5);
126+
if(isEdge) {
127+
fragColor = vec4(0.5f, 0.5f, 0.5f, 0.5f);
95128
return;
96129
}
97130

@@ -100,7 +133,7 @@ void main() {
100133
vec2 position = vec2(gl_FragCoord.xy + offsets);
101134

102135
// spring force from neighbors
103-
vec2 forces = vec2(0.0, 0.0);
136+
vec2 forces = vec2(0.0f, 0.0f);
104137
forces = updateForces(forces, position, left);
105138
forces = updateForces(forces, position, right);
106139
forces = updateForces(forces, position, top);
@@ -111,33 +144,30 @@ void main() {
111144
forces = updateForces(forces, position, bottom + right);
112145

113146
// turbulence / noise
114-
if (turbulence_factor > 0.0) {
147+
if(turbulence_factor > 0.0f) {
115148
float turbulence_strength = turbulence_factor * length(velocity);
116149
float noise = rand(gl_FragCoord.xy);
117-
vec2 turbulence = vec2(cos(noise * 6.28318), sin(noise * 6.28318));
150+
vec2 turbulence = vec2(cos(noise * 6.28318f), sin(noise * 6.28318f));
118151
forces += turbulence * turbulence_strength;
119152
}
120153

121154
// velocity
122155
velocity += forces * dt;
123156
velocity *= damping;
124-
if (length(velocity) < clamp_value * scale) {
125-
velocity = vec2(0.0, 0.0);
157+
if(length(velocity) < clamp_value * scale) {
158+
velocity = vec2(0.0f, 0.0f);
126159
}
127160

128161
// position
129162
offsets += velocity * dt;
130-
if (velocity.x == 0.0 && velocity.y == 0.0 && length(offsets) < clamp_value * scale) {
131-
offsets = vec2(0.0, 0.0);
163+
if(velocity.x == 0.0f && velocity.y == 0.0f && length(offsets) < clamp_value * scale) {
164+
offsets = vec2(0.0f, 0.0f);
132165
}
133166

134167
// clamp
135168
offsets = format(offsets);
136169
velocity = format(velocity);
137170

138171
// output
139-
fragColor = vec4(
140-
velocity,
141-
offsets
142-
);
172+
fragColor = vec4(velocity, offsets);
143173
}

0 commit comments

Comments
 (0)