@firecms/neat 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/shaders.ts CHANGED
@@ -72,7 +72,10 @@ export const vertexShaderSource = `void main() {
72
72
 
73
73
  v_color = color;
74
74
 
75
- // 4. VERTEX POSITION
75
+ // 4. FRESNEL (rim glow)
76
+ // (Calculated in fragment shader using displacement slope approximation)
77
+
78
+ // 5. VERTEX POSITION
76
79
  vec3 newPosition = position + normal * v_displacement_amount * u_wave_amplitude;
77
80
  gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
78
81
  v_new_position = gl_Position;
@@ -95,31 +98,32 @@ float fbm(vec3 x) {
95
98
  return value;
96
99
  }
97
100
 
101
+ // Branchless HSL to RGB for iridescence
102
+ vec3 hsl2rgb(float h, float s, float l) {
103
+ vec3 rgb = clamp(abs(mod(h * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
104
+ return l + s * (rgb - 0.5) * (1.0 - abs(2.0 * l - 1.0));
105
+ }
106
+
98
107
  void main() {
99
108
  vec2 finalUv = vFlowUv;
100
109
 
101
110
  vec3 baseColor;
102
111
 
103
112
  if (u_enable_procedural_texture > 0.5) {
104
- // Calculate flow field distance for ease effect
105
113
  vec2 ppp = -1.0 + 2.0 * finalUv;
106
114
  ppp += 0.1 * cos((1.5 * u_flow_scale) * ppp.yx + 1.1 * u_time + vec2(0.1, 1.1));
107
115
  ppp += 0.1 * cos((2.3 * u_flow_scale) * ppp.yx + 1.3 * u_time + vec2(3.2, 3.4));
108
116
  ppp += 0.1 * cos((2.2 * u_flow_scale) * ppp.yx + 1.7 * u_time + vec2(1.8, 5.2));
109
117
  ppp += u_flow_distortion_a * cos((u_flow_distortion_b * u_flow_scale) * ppp.yx + 1.4 * u_time + vec2(6.3, 3.9));
110
- float r = length(ppp); // Flow distance
118
+ float r = length(ppp);
111
119
 
112
- // Ease blending: 0 = topographic (flow), 1 = image (UV)
113
120
  float vx = (finalUv.x * u_texture_ease) + (r * (1.0 - u_texture_ease));
114
121
  float vy = (finalUv.y * u_texture_ease) + (0.0 * (1.0 - u_texture_ease));
115
122
  vec2 texUv = vec2(vx, vy);
116
123
 
117
- // PARALLAX SCROLLING
118
- // We manually apply a smaller offset here to make the texture lag behind
119
- float parallaxFactor = 0.25; // 25% speed of the color mixing
124
+ float parallaxFactor = 0.25;
120
125
  texUv.y -= (u_y_offset * u_y_offset_color_multiplier / u_plane_height) * parallaxFactor;
121
-
122
- texUv *= 1.5; // Tiling scale
126
+ texUv *= 1.5;
123
127
 
124
128
  vec4 texSample = texture2D(u_procedural_texture, texUv);
125
129
  baseColor = texSample.rgb;
@@ -129,24 +133,70 @@ void main() {
129
133
 
130
134
  vec3 color = baseColor;
131
135
 
136
+ // === DOMAIN WARPING (simplified: 3 fbm calls instead of 5) ===
137
+ if (u_domain_warp_enabled > 0.5) {
138
+ vec3 p = vec3(finalUv * u_domain_warp_scale, u_time * 0.15);
139
+ vec2 q = vec2(fbm(p), fbm(p + vec3(5.2, 1.3, 0.0)));
140
+ float f = fbm(p + vec3(4.0 * q, 0.0));
141
+ vec3 warpColor = color * (1.0 + f * 0.8 * u_domain_warp_intensity);
142
+ float pattern = clamp(f * f * f + 0.6 * f * f + 0.5 * f, 0.0, 1.0);
143
+ color = mix(color, warpColor * (0.6 + pattern * 0.8), u_domain_warp_intensity * 0.7);
144
+ }
145
+
132
146
  // Post-processing
133
147
  color += v_displacement_amount * u_highlights;
134
- // Replace pow() with direct multiplication to avoid negative base undefined behavior in GLSL
135
148
  float shadowFactor = 1.0 - v_displacement_amount;
136
149
  color -= shadowFactor * shadowFactor * u_shadows;
137
150
  color = saturation(color, 1.0 + u_saturation);
138
151
  color = color * u_brightness;
139
152
 
140
- // Grain
141
- vec2 noiseCoords = gl_FragCoord.xy / u_grain_scale;
153
+ // === IRIDESCENCE ===
154
+ if (u_iridescence_enabled > 0.5) {
155
+ float hue = fract(v_displacement_amount * 0.5 + 0.5 + u_time * u_iridescence_speed * 0.05);
156
+ vec3 iriColor = hsl2rgb(hue, 0.8, 0.6);
157
+ color = mix(color, iriColor, u_iridescence_intensity * abs(v_displacement_amount) * 0.6);
158
+ }
159
+
160
+ // === FRESNEL (Rim glow) ===
161
+ if (u_fresnel_enabled > 0.5) {
162
+ float slope = 1.0 - abs(v_displacement_amount);
163
+ float fresnel = pow(max(slope, 0.0), u_fresnel_power);
164
+ color += u_fresnel_color * fresnel * u_fresnel_intensity;
165
+ }
166
+
167
+ // === VIGNETTE ===
168
+ if (u_vignette_intensity > 0.0) {
169
+ float dist = length(vUv - vec2(0.5));
170
+ float vig = smoothstep(u_vignette_radius, u_vignette_radius * 0.3, dist);
171
+ color *= mix(1.0, vig, u_vignette_intensity);
172
+ }
173
+
174
+ // === FAKE BLOOM ===
175
+ if (u_bloom_intensity > 0.0) {
176
+ float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
177
+ float bloomMask = smoothstep(u_bloom_threshold, 1.0, luma);
178
+ color += color * bloomMask * u_bloom_intensity;
179
+ }
180
+
181
+ // === CHROMATIC ABERRATION ===
182
+ if (u_chromatic_aberration > 0.0) {
183
+ float caAmount = u_chromatic_aberration * 0.008;
184
+ float dist = length(vUv - vec2(0.5));
185
+ float rShift = v_displacement_amount + caAmount * dist;
186
+ float bShift = v_displacement_amount - caAmount * dist;
187
+ color.r *= 1.0 + rShift * caAmount * 10.0;
188
+ color.b *= 1.0 - bShift * caAmount * 10.0;
189
+ }
190
+
191
+ // Grain (use cheap hash noise instead of expensive fbm when static)
142
192
  float grain = 0.0;
143
-
144
- // Completely bypass expensive noise generation if grain is disabled
145
193
  if (u_grain_intensity > 0.0) {
194
+ vec2 noiseCoords = gl_FragCoord.xy / u_grain_scale;
146
195
  if (u_grain_speed != 0.0) {
147
196
  grain = fbm(vec3(noiseCoords, u_time * u_grain_speed));
148
197
  } else {
149
- grain = fbm(vec3(noiseCoords, 0.0));
198
+ // Static grain: use cheap hash instead of fbm
199
+ grain = random(noiseCoords) - 0.5;
150
200
  }
151
201
 
152
202
  grain = grain * 0.5 + 0.5;
@@ -206,6 +256,12 @@ uniform float u_flow_distortion_b;
206
256
  uniform float u_flow_scale;
207
257
  uniform float u_flow_ease;
208
258
  uniform float u_flow_enabled;
259
+
260
+ // Fresnel uniforms
261
+ uniform float u_fresnel_enabled;
262
+ uniform float u_fresnel_power;
263
+ uniform float u_fresnel_intensity;
264
+ uniform vec3 u_fresnel_color;
209
265
  `;
210
266
  }
211
267
 
@@ -218,6 +274,7 @@ varying vec3 v_color;
218
274
  varying float v_displacement_amount;
219
275
 
220
276
  uniform float u_time;
277
+ uniform vec2 u_resolution;
221
278
  uniform float u_plane_height;
222
279
 
223
280
  uniform float u_shadows;
@@ -241,6 +298,35 @@ uniform float u_flow_scale;
241
298
  uniform sampler2D u_procedural_texture;
242
299
  uniform float u_enable_procedural_texture;
243
300
  uniform float u_texture_ease;
301
+
302
+ // Domain warping uniforms
303
+ uniform float u_domain_warp_enabled;
304
+ uniform float u_domain_warp_intensity;
305
+ uniform float u_domain_warp_scale;
306
+
307
+ // Vignette uniforms
308
+ uniform float u_vignette_intensity;
309
+ uniform float u_vignette_radius;
310
+
311
+ // Fresnel uniforms (fragment side)
312
+ uniform float u_fresnel_enabled;
313
+ uniform float u_fresnel_power;
314
+ uniform float u_fresnel_intensity;
315
+ uniform vec3 u_fresnel_color;
316
+
317
+
318
+
319
+ // Iridescence uniforms
320
+ uniform float u_iridescence_enabled;
321
+ uniform float u_iridescence_intensity;
322
+ uniform float u_iridescence_speed;
323
+
324
+ // Bloom uniforms
325
+ uniform float u_bloom_intensity;
326
+ uniform float u_bloom_threshold;
327
+
328
+ // Chromatic aberration
329
+ uniform float u_chromatic_aberration;
244
330
  `;
245
331
  }
246
332
 
package/src/types.ts CHANGED
@@ -41,6 +41,33 @@ export type NeatConfig = {
41
41
  textureShapeCircles?: number;
42
42
  textureShapeBars?: number;
43
43
  textureShapeSquiggles?: number;
44
+
45
+ // Domain warping
46
+ domainWarpEnabled?: boolean;
47
+ domainWarpIntensity?: number;
48
+ domainWarpScale?: number;
49
+
50
+ // Vignette
51
+ vignetteIntensity?: number;
52
+ vignetteRadius?: number;
53
+
54
+ // Fresnel (rim glow)
55
+ fresnelEnabled?: boolean;
56
+ fresnelPower?: number;
57
+ fresnelIntensity?: number;
58
+ fresnelColor?: string;
59
+
60
+ // Iridescence
61
+ iridescenceEnabled?: boolean;
62
+ iridescenceIntensity?: number;
63
+ iridescenceSpeed?: number;
64
+
65
+ // Bloom (fake)
66
+ bloomIntensity?: number;
67
+ bloomThreshold?: number;
68
+
69
+ // Chromatic aberration
70
+ chromaticAberration?: number;
44
71
  };
45
72
 
46
73
  export type NeatColor = {