STUDIO TAMA


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}