• 【Webgl_glsl&Threejs】搬运分享shader_飘落心形


    来源网站

    https://www.shadertoy.com/view/4sccWr
    
    • 1

    效果预览

    在这里插入图片描述

    代码演示

    将shadertory上的代码转成了threejs可以直接用的代码,引入文件的material,并在创建mesh或已有物体上使用material即可,使用时请注意uv对齐。

    import { DoubleSide, ShaderChunk, ShaderMaterial } from "three";
    //source: https://www.shadertoy.com/view/4sccWr
    // Into You - by Martijn Steinrucken aka BigWings - 2018
    // Email:countfrolic@gmail.com Twitter:@The_ArtOfCode
    // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
    
    // You can change the focal plane by moving the mouse up and down.
    
    // A video of the effect can be found here:
    // https://www.youtube.com/watch?v=lrMiME82Cuk
    
    // Making of video part1:
    // https://www.youtube.com/watch?v=dXyPOLf2MbU
    
    // Android Phone Wallpaper:
    // https://play.google.com/store/apps/details?id=com.TheArtOfCode.FallingHearts
    
    // Music - Novo Amor - Anchor
    // https://soundcloud.com/mrsuicidesheep/novo-amor-anchor
    
    const vertex = `
    ${ShaderChunk.logdepthbuf_pars_vertex}
    bool isPerspectiveMatrix(mat4) {
        return true;
    }
    
    varying vec4 m_pos;
    varying vec2 vUv;
    
    void main () {
        vUv = uv;
        // 从贴图中采样颜色值
        vec3 newPosition = normal*vec3(0,0,0)+position;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
    
          ${ShaderChunk.logdepthbuf_vertex}
    }
        `;
    
    // 片元着色器代码
    const fragment = /*glsl*/`
    ${ShaderChunk.logdepthbuf_pars_fragment}
    precision mediump float;
    varying vec2 vUv;
    uniform float uTime;
    uniform float uSpeed;
    
    
    #define S(a, b, t) smoothstep(a, b, t)
    #define sat(x) clamp(x, 0., 1.)
    #define HEARTCOL vec3(1., .01, .01)
    #define NUM_HEARTS 50.
    #define LIGHT_DIR vec3(.577, -.577, -.577)
    
    // Polynomial smooth max from IQ
    float smax( float a, float b, float k ) {
    	float h = sat( .5 + .5*(b-a)/k );
    	return mix( a, b, h ) + k*h*(1.-h);
    }
    // Quaternion rotation functions from Ollj
    vec4 qmulq(vec4 q1, vec4 q2){return vec4(q1.xyz*q2.w+q2.xyz*q1.w+cross(q1.xyz,q2.xyz),(q1.w*q2.w)-dot(q1.xyz,q2.xyz));}
    vec4 aa2q(vec3 axis, float angle){return vec4(normalize(axis)*sin(angle*0.5),cos(angle*0.5));}
    vec4 qinv(vec4 q){return vec4(-q.xyz,q.w)/dot(q,q);}
    vec3 qmulv(vec4 q, vec3 p){return qmulq(q,qmulq(vec4(p,.0),qinv(q))).xyz;}
    
    vec2 RaySphere(vec3 rd, vec3 p) {
        float l = dot(rd, p);
        float det = l*l - dot(p, p) + 1.;
        if (det < 0.) return vec2(-1);
    
        float sd = sqrt(det);
        return vec2(l - sd, l+sd);
    }
    
    struct sphereInfo {
    	vec3 p1, p2, n1, n2;
        vec2 uv1, uv2;
    };
    
    sphereInfo GetSphereUvs(vec3 rd, vec2 i, vec2 rot, vec3 s) {
    	sphereInfo res;
        rot *= 6.2831;
        vec4 q = aa2q(vec3(cos(rot.x),sin(rot.x),0), rot.y);
        vec3 o = qmulv(q, -s)+s;
        vec3 d = qmulv(q, rd);
        
        res.p1 = rd*i.x;
        vec3 p = o+d*i.x-s;
        res.uv1 = vec2(atan(p.x, p.z), p.y);
        res.n1 = res.p1-s;
        
        res.p2 = rd*i.y;
        p = o+d*i.y-s;
        res.uv2 = vec2(atan(p.x, p.z), p.y);
        res.n2 = s-res.p2;
            
        return res;
    }
    
    float Heart(vec2 uv, float b) {
    	uv.x*=.5;
        float shape = smax(sqrt(abs(uv.x)), b, .3*b)*.5;
        uv.y -= shape*(1.-b);
    
        return S(b, -b, length(uv)-.5);
    }
    
    vec4 HeartBall(vec3 rd, vec3 p, vec2 rot, float t, float blur) {
        vec2 d = RaySphere(rd, p);
        
       	vec4 col = vec4(0);
        if(d.x>0.) {
        	sphereInfo info = GetSphereUvs(rd, d, rot, p);
        	
            float sd = length(cross(p, rd));
            float edge =  S(1., mix(1., 0.1, blur), sd);
            
            float backMask = Heart(info.uv2, blur)*edge; 
            float frontMask = Heart(info.uv1, blur)*edge; 
            float frontLight = sat(dot(LIGHT_DIR, info.n1)*.8+.2);
            float backLight = sat(dot(LIGHT_DIR, info.n2)*.8+.2)*.9;
    
            col = mix(vec4(backLight*HEARTCOL, backMask), 
                      vec4(frontLight*HEARTCOL, frontMask), 
                      frontMask);
        }
        return col;
    }
    
    void main() {
        vec2 uv = vUv;
        uv-=.5;
        vec2 m =vec2(.5);
        float t = uTime*.3*uSpeed;
      
        vec3 rd = normalize(vec3(uv, 1));
        
        // m.y = iMouse.z>0. ? 1.-m.y : .4;
    
        vec2 rot = t*vec2(.12, .18);
        vec4 col = vec4(0);
            
        for(float i=0.; i<1.; i+=(1./NUM_HEARTS)) {
            float x = (fract(cos(i*536.3)*7464.4)-.5)*15.;
            float y = (fract(-t*.2+i*7.64)-.5)*15.;
            float z = mix(14., 2., i);
            
            float blur = mix(.03, .35, S(.0, .4, abs(m.y-i)));
            
            rot += (fract(sin(i*vec2(536.3, 23.4))*vec2(764.4, 987.3))-.5);
            vec4 heart = HeartBall(rd, vec3(x, y, z), rot, t, blur);
            
            col = mix(col, heart, heart.a);
        }
    	
      
     
      gl_FragColor = vec4(col);
    
      ${ShaderChunk.logdepthbuf_fragment}
    }
        `;
    
    const uniforms = {
        uTime: { value: 1.0 },
    };
    const CircleGridShaderMaterial = new ShaderMaterial({
        uniforms: {
            uTime: { value: 1.0 },
            uSpeed: { value: 1.0, max: 20, min: 0.1 }
        },
        vertexShader: vertex,
        fragmentShader: fragment,
        side: DoubleSide,
        transparent: true,
    });
    
    const loop = () => {
        requestAnimationFrame(loop)
        CircleGridShaderMaterial.uniforms.uTime.value += .001
    }
    loop()
    setInterval(() => {
        // CircleGridShaderMaterial.uniforms.uTime.value += .0001
    }, 5000);
    export default CircleGridShaderMaterial
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187

    页面展示

    flowHeart

  • 相关阅读:
    历史汇率查询易语言代码
    MySQL数据库——MySQL日志及分类
    类和对象的知识点补充
    部署LVS-NAT群集实验
    【机器学习】TF-IDF以及TfidfVectorizer
    什么是SQL 语句中相关子查询与非相关子查询
    AcWing 4604. 集合询问
    LeetCode刷题第4周小结
    Day06
    Ansible之playbook详解和应用实例
  • 原文地址:https://blog.csdn.net/qq_61834461/article/details/138159607