#Stylized Clouds

3 messages · Page 1 of 1 (latest)

worthy bramble
#

Hi, I am trying to make stylized clouds like this photo.
This photo is actually from a youtube painting tutorial.
The technique is as follows:

  1. paint the background
  2. paint a cloud silhouette
  3. paint brighter highlights and smudge them in a general direction away from the light
    My goal is to get a 3d version very close to reference.I am also looking for performance.

The current idea is to get a 3d silhouette using carefully placed billboards.
I am using InstancedBufferGeometry and InstancedBufferAttribute
I have a simple fragment shader clips them into circles with noisy small scale details (see the unlit version)
Now I have add some lighting but the billboards fight for depth (noticed when changing the view)

Additionally, I would like to understand how blending works in threejs specially about the performance aspects.

#
const vertexShader = /*glsl*/`
    attribute vec3 translate;
    attribute float scale;
    uniform float time;
    varying vec2 vUv;
    varying vec3 vTranslate;
    ${valueNoise()}
    void main(){
        vUv=uv;
        float d=length(vUv-0.5);
        vTranslate=translate;
        vec4 mvPosition = modelViewMatrix * vec4(translate, 1.0 );
        mvPosition.xyz +=position*scale;
        gl_Position = projectionMatrix * mvPosition;
    }
`;
const fragmentShader = /*glsl*/`
    uniform float time;
    uniform vec3 color;
    uniform vec3 highlight;
    varying vec3 vTranslate;
    varying vec2 vUv;
    ${valueNoise()}
    void main(){
        float d=length(vUv-0.5);
        if(d>0.5)discard;
        float depth=length(vTranslate-cameraPosition);
       
        vec3 viewDir=normalize(vTranslate-cameraPosition);
        vec3 vf=0.1*viewDir;
        vec2 vfUv=vf.xy;
        vec2 sUv=0.5+(vUv-0.5)*pow(1.-2.*(d),.5)+vfUv+vTranslate.xz;
        vec3 vn=2.*noised(sUv*20.0+vec2(time)*0.4)+2.*noised(sUv*50.0-vec2(time)*0.5);
        float edge=smoothstep(0.15,0.2,d);
        float c_edge=1.-(1.+edge*(vn.x+vf.x))*(1.-edge);
        if((c_edge)>0.9)discard;
        float s=dot(vUv,vec2(0.7));
        float ss=smoothstep(0.5,1.,s);
        float f=ss*c_edge;
        vec3 mixedColor=mix(color,highlight,f);
        gl_FragColor = vec4(vec3(mixedColor),ss);
    }
`;
const material = new THREE.ShaderMaterial({
    transparent: true,
    // blendEquation: THREE.AddEquation,
    // blending: THREE.AdditiveBlending,
    uniforms: {
        'time': { value: 0.0 },
        "color": { value: new THREE.Color(0xB6E8FF) },
        "highlight": { value: new THREE.Color(0xFAFEFF) }
    },
    vertexShader: vertexShader,
    fragmentShader: fragmentShader,
});
worthy bramble