soapBubbleVertex.glsl
1uniform float uTime;
2uniform int uOctaves;
3uniform float uTimeFrequency;
4uniform float uAmplitude;
5uniform float uFrequency;
6
7attribute vec4 tangent;
8
9varying vec2 vUv;
10varying vec3 vPosition;
11varying vec3 varyNormal;
12
13// Permutation function for noise
14vec3 permute(vec3 x) {
15 return mod(((x*34.0)+1.0)*x, 289.0);
16}
17
18// Noise function
19float noise(vec3 p) {
20 vec3 i = floor(p);
21 vec3 f = fract(p);
22 vec3 u = f*f*(3.0-2.0*f);
23
24 return mix(mix(mix( dot(permute(i + vec3(0,0,0)), f - vec3(0,0,0)),
25 dot(permute(i + vec3(1,0,0)), f - vec3(1,0,0)), u.x),
26 mix( dot(permute(i + vec3(0,1,0)), f - vec3(0,1,0)),
27 dot(permute(i + vec3(1,1,0)), f - vec3(1,1,0)), u.x), u.y),
28 mix(mix( dot(permute(i + vec3(0,0,1)), f - vec3(0,0,1)),
29 dot(permute(i + vec3(1,0,1)), f - vec3(1,0,1)), u.x),
30 mix( dot(permute(i + vec3(0,1,1)), f - vec3(0,1,1)),
31 dot(permute(i + vec3(1,1,1)), f - vec3(1,1,1)), u.x), u.y), u.z);
32}
33
34float fractalNoise(vec3 p, int octaves) {
35 float noiseValue = 0.0;
36 float amplitude = uAmplitude;
37 float frequency = 1.0;
38 for (int i = 0; i < octaves; i++) {
39 noiseValue += amplitude * noise(p * frequency);
40 amplitude *= 0.5;
41 frequency *= 2.0;
42 }
43 return noiseValue;
44}
45
46
47float getDisplacement(vec3 p) {
48 return fractalNoise(p * uFrequency + vec3(uTime * uTimeFrequency), uOctaves);
49}
50
51float getDisplacementEffect(float noiseValue) {
52 return sin(noiseValue) * cos(noiseValue);
53}
54
55void main() {
56
57 vec3 biTangent = cross(normal, tangent.xyz);
58 float shift = 0.01;
59 vec3 positionA = csm_Position + tangent.xyz * shift;
60 vec3 positionB = csm_Position + biTangent * shift;
61
62 vPosition = position;
63
64 float displacement = getDisplacementEffect(getDisplacement(vPosition));
65 float displacementA = getDisplacementEffect(getDisplacement(positionA));
66 float displacementB = getDisplacementEffect( getDisplacement(positionB));
67
68 csm_Position += normal * displacement;
69 positionA += normal * displacementA;
70 positionB += normal * displacementB;
71
72 vec3 toA = normalize(positionA - csm_Position);
73 vec3 toB = normalize(positionB - csm_Position);
74 csm_Normal = normalize(cross(toA, toB));
75
76 vUv = uv;
77 varyNormal = csm_Normal;
78}
79
soapBubbleFragment.glsl
1varying vec2 vUv;
2varying vec3 varyNormal;
3varying vec3 vPosition;
4
5uniform float uOpacity;
6uniform vec3 uCameraPosition;
7uniform sampler2D uNoiseTexture;
8uniform float uNoiseStrength;
9uniform float uMinWavelength;
10uniform float uMaxWavelength;
11
12vec3 wavelengthToRGB(float wavelength) {
13 vec3 color;
14
15 if(wavelength >= 380.0 && wavelength < 440.0) {
16 color = vec3((440.0 - wavelength) / (440.0 - 380.0), 0.0, 1.0);
17 } else if(wavelength >= 440.0 && wavelength < 490.0) {
18 color = vec3(0.0, (wavelength - 440.0) / (490.0 - 440.0), 1.0);
19 } else if(wavelength >= 490.0 && wavelength < 510.0) {
20 color = vec3(0.0, 1.0, (510.0 - wavelength) / (510.0 - 490.0));
21 } else if(wavelength >= 510.0 && wavelength < 580.0) {
22 color = vec3((wavelength - 510.0) / (580.0 - 510.0), 1.0, 0.0);
23 } else if(wavelength >= 580.0 && wavelength < 645.0) {
24 color = vec3(1.0, (645.0 - wavelength) / (645.0 - 580.0), 0.0);
25 } else if(wavelength >= 645.0 && wavelength <= 780.0) {
26 color = vec3(1.0, 0.0, 0.0);
27 } else {
28 color = vec3(0.0);
29 }
30
31 // 波長に基づいて強度を調整
32 float factor = 0.1;
33 if(wavelength >= 380.0 && wavelength < 420.0) {
34 factor = 0.1 + 0.9 * (wavelength - 380.0) / (420.0 - 380.0);
35 } else if(wavelength >= 420.0 && wavelength <= 700.0) {
36 factor = 1.0;
37 } else if(wavelength > 700.0 && wavelength <= 780.0) {
38 factor = 0.1 + 0.9 * (780.0 - wavelength) / (780.0 - 700.0);
39 }
40
41 color *= factor;
42
43 return color;
44}
45
46vec3 applyGammaCorrection(vec3 color, float gamma) {
47 return pow(color, vec3(1.0 / gamma));
48}
49
50
51void main() {
52 //camera direction effect
53 vec3 viewDir = normalize(uCameraPosition - vPosition);
54 float dotProduct = dot(normalize(varyNormal), viewDir);
55 float wavelength = mix(uMinWavelength, uMaxWavelength, abs(dotProduct));
56 vec3 baseColor = mix(vec3(1.0), wavelengthToRGB(clamp(wavelength, uMinWavelength, uMaxWavelength)), 1.0 - abs(dotProduct));
57
58 //noise effect
59 vec2 repeatUv = fract(vUv * uNoiseStrength);
60 float noiseValue = texture(uNoiseTexture, repeatUv).r;
61
62 // //combine effects
63 wavelength += noiseValue;
64 baseColor = mix(baseColor, wavelengthToRGB(clamp(wavelength, uMinWavelength, uMaxWavelength)), noiseValue);
65 baseColor = applyGammaCorrection(baseColor, 2.2);
66
67 csm_DiffuseColor.rgb = vec3(baseColor);
68 csm_DiffuseColor.a = uOpacity;
69
70 csm_Roughness = .0;
71 csm_Metalness = 1.0;
72}