mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 08:46:40 +08:00
fix(glass): refine fluid response coverage (#641)
This commit is contained in:
@@ -4149,8 +4149,8 @@ describe('glass optical surface discovery', () => {
|
|||||||
expect(scene.children[0].material.fragmentShader).toContain('uniform float uReflectionStrength')
|
expect(scene.children[0].material.fragmentShader).toContain('uniform float uReflectionStrength')
|
||||||
expect(scene.children[0].material.fragmentShader).not.toContain('uWakeProgress')
|
expect(scene.children[0].material.fragmentShader).not.toContain('uWakeProgress')
|
||||||
expect(scene.children[0].material.fragmentShader).not.toContain('temporalEnergy')
|
expect(scene.children[0].material.fragmentShader).not.toContain('temporalEnergy')
|
||||||
expect(scene.children[0].material.fragmentShader).toContain('const float dynamicRangeScale = 0.40')
|
expect(scene.children[0].material.fragmentShader).toContain('const float dynamicRangeScale = 0.52')
|
||||||
expect(scene.children[0].material.fragmentShader).toContain('const float dynamicRangeDensity = 6.250')
|
expect(scene.children[0].material.fragmentShader).toContain('const float dynamicRangeDensity = 3.698')
|
||||||
expect(scene.children[0].material.fragmentShader).toContain('float pointerSpread = mix(26.0, 17.0, uQuality)')
|
expect(scene.children[0].material.fragmentShader).toContain('float pointerSpread = mix(26.0, 17.0, uQuality)')
|
||||||
expect(scene.children[0].material.fragmentShader).not.toContain(
|
expect(scene.children[0].material.fragmentShader).not.toContain(
|
||||||
'mix(mix(26.0, 17.0, uQuality), mix(12.0, 8.0, uQuality), frosted)',
|
'mix(mix(26.0, 17.0, uQuality), mix(12.0, 8.0, uQuality), frosted)',
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
import { createGlassFluidDynamics, GLASS_FLUID_FIELD_FRAGMENT_SHADER } from '@/rendering/glass/glassFluidDynamics'
|
import {
|
||||||
|
createGlassFluidDynamics,
|
||||||
|
GLASS_FLUID_DYNAMIC_RANGE_DENSITY,
|
||||||
|
GLASS_FLUID_DYNAMIC_RANGE_SCALE,
|
||||||
|
GLASS_FLUID_FIELD_FRAGMENT_SHADER,
|
||||||
|
GLASS_FLUID_FRAGMENT_SURFACE_REFRACTION,
|
||||||
|
GLASS_FLUID_FRAGMENT_SURFACE_SHAPE,
|
||||||
|
} from '@/rendering/glass/glassFluidDynamics'
|
||||||
|
|
||||||
class FakeVector2 {
|
class FakeVector2 {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -179,9 +186,26 @@ describe('glass fluid dynamics', () => {
|
|||||||
|
|
||||||
it('keeps the established field injection and decay equations', () => {
|
it('keeps the established field injection and decay equations', () => {
|
||||||
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('previousEnergy * uDecay')
|
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('previousEnergy * uDecay')
|
||||||
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('distanceSquared * 437.500')
|
expect(GLASS_FLUID_DYNAMIC_RANGE_SCALE).toBe(0.52)
|
||||||
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('distanceSquared * 262.500')
|
expect(GLASS_FLUID_DYNAMIC_RANGE_DENSITY).toBeCloseTo(3.698, 3)
|
||||||
|
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('distanceSquared * 258.876')
|
||||||
|
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('distanceSquared * 155.325')
|
||||||
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('injection * 0.44')
|
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).toContain('injection * 0.44')
|
||||||
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).not.toContain('uImpulse')
|
expect(GLASS_FLUID_FIELD_FRAGMENT_SHADER).not.toContain('uImpulse')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('narrows directional material coverage without replacing fluid refraction energy', () => {
|
||||||
|
expect(GLASS_FLUID_FRAGMENT_SURFACE_SHAPE).toContain(
|
||||||
|
'smoothstep(0.001, 0.012, length(uPointerVelocity))',
|
||||||
|
)
|
||||||
|
expect(GLASS_FLUID_FRAGMENT_SURFACE_SHAPE).toContain('directionalCoverageShape')
|
||||||
|
expect(GLASS_FLUID_FRAGMENT_SURFACE_SHAPE).toContain('pointerCoverageEnergy')
|
||||||
|
expect(GLASS_FLUID_FRAGMENT_SURFACE_SHAPE).toContain(
|
||||||
|
'pow(clamp(pointerCoverageShape * uMotion, 0.0, 1.0), 1.15)',
|
||||||
|
)
|
||||||
|
expect(GLASS_FLUID_FRAGMENT_SURFACE_REFRACTION).toContain(
|
||||||
|
'pointerDelta * pointerEnergy * pointerStrength',
|
||||||
|
)
|
||||||
|
expect(GLASS_FLUID_FRAGMENT_SURFACE_REFRACTION).not.toContain('pointerCoverageEnergy')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export interface GlassFluidDynamics {
|
|||||||
step(): Texture
|
step(): Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GLASS_FLUID_DYNAMIC_RANGE_SCALE = 0.4
|
export const GLASS_FLUID_DYNAMIC_RANGE_SCALE = 0.52
|
||||||
export const GLASS_FLUID_DYNAMIC_RANGE_DENSITY = 1 / GLASS_FLUID_DYNAMIC_RANGE_SCALE ** 2
|
export const GLASS_FLUID_DYNAMIC_RANGE_DENSITY = 1 / GLASS_FLUID_DYNAMIC_RANGE_SCALE ** 2
|
||||||
const GLASS_FLUID_BUFFER_SCALE = 0.25
|
const GLASS_FLUID_BUFFER_SCALE = 0.25
|
||||||
|
|
||||||
@@ -216,8 +216,25 @@ export const GLASS_FLUID_FRAGMENT_SURFACE_SHAPE = ` vec2 pointerDelta = uPoin
|
|||||||
uDeformationStrength *
|
uDeformationStrength *
|
||||||
uFlowStrength;
|
uFlowStrength;
|
||||||
float wakeEnergy = abs(wakeShape) * wakeEnvelope * uMotion;
|
float wakeEnergy = abs(wakeShape) * wakeEnvelope * uMotion;
|
||||||
|
// 覆盖能量比位移核更快收敛,避免高斯尾部把真实折射扩成整块色调覆盖。
|
||||||
|
float coverageDirectionality = max(
|
||||||
|
sharedDirectionality,
|
||||||
|
smoothstep(0.001, 0.012, length(uPointerVelocity))
|
||||||
|
);
|
||||||
|
float coverageWakeTravel =
|
||||||
|
0.08 * coverageDirectionality * mix(0.86, 1.18, uMotionExpansion);
|
||||||
|
float directionalCoverageShape = exp(-(
|
||||||
|
pow(pointerAlong + coverageWakeTravel * 0.45, 2.0) * pointerSpread * 0.55 +
|
||||||
|
pointerAcross * pointerAcross * pointerSpread * 2.8
|
||||||
|
));
|
||||||
|
float pointerCoverageShape = mix(
|
||||||
|
radialPointerShape,
|
||||||
|
directionalCoverageShape,
|
||||||
|
coverageDirectionality
|
||||||
|
);
|
||||||
|
float pointerCoverageEnergy = pow(clamp(pointerCoverageShape * uMotion, 0.0, 1.0), 1.15);
|
||||||
float liquidEnergy = clamp(max(
|
float liquidEnergy = clamp(max(
|
||||||
pointerEnergy,
|
pointerCoverageEnergy,
|
||||||
max(min(1.0, trailEnergy) * 0.68, wakeEnergy * 0.82)
|
max(min(1.0, trailEnergy) * 0.68, wakeEnergy * 0.82)
|
||||||
), 0.0, 1.0);`
|
), 0.0, 1.0);`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user