Three.js 使用着色器 实现跳动的心

Three.js 使用着色器 实现跳动的心

预览: https://threehub.cn/#/codeMirror?navigation=ThreeJS&classify=shader&id=jumpHeart

bash 复制代码
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

const box = document.getElementById('box')
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 1000)
camera.position.set(0, 0, 10)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(box.clientWidth, box.clientHeight)
box.appendChild(renderer.domElement)
new OrbitControls(camera, renderer.domElement)
scene.add(new THREE.AxesHelper(50000))
window.onresize = () => {
    renderer.setSize(box.clientWidth, box.clientHeight)
    camera.aspect = box.clientWidth / box.clientHeight
    camera.updateProjectionMatrix()
}

const { mesh, uniforms } = getShaderMesh()
scene.add(mesh)

animate()
function animate() {
    uniforms.iTime.value += 0.01
    requestAnimationFrame(animate)
    renderer.render(scene, camera)
}

function getShaderMesh() {

    const uniforms = {
        iTime: {
            value: 0
        },
        iResolution: {
            value: new THREE.Vector2(1900, 1900)
        },
        iChannel0: {
            value: window.iChannel0
        }
    }

    const geometry = new THREE.PlaneGeometry(20, 20);
    const material = new THREE.ShaderMaterial({
        uniforms,
        side: 2,
        depthWrite: false,
        transparent: true,
        vertexShader: `
            varying vec3 vPosition;
            varying vec2 vUv;
            void main() { 
                vUv = uv; 
                vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
                gl_Position = projectionMatrix * mvPosition;
            }
        `,
        fragmentShader: `
        uniform float iTime; 
		uniform vec2 iResolution;  
		varying vec2 vUv;  
         
        void main(void) {
            vec2 p = (vUv - 0.5 ) * 2.0;
            // vec2 p = (2.0*fragCoord-iResolution.xy)/min(iResolution.y,iResolution.x);
	
            // background color
            vec3 bcol = vec3(1.0,0.8,0.7-0.07*p.y)*(1.0-0.25*length(p));
        
            // animate
            float tt = mod(iTime,1.5)/1.5;
            float ss = pow(tt,.2)*0.5 + 0.5;
            ss = 1.0 + ss*0.5*sin(tt*6.2831*3.0 + p.y*0.5)*exp(-tt*4.0);
            p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);
        
            // shape
        #if 0
            p *= 0.8;
            p.y = -0.1 - p.y*1.2 + abs(p.x)*(1.0-abs(p.x));
            float r = length(p);
            float d = 0.5;
        #else
            p.y -= 0.25;
            float a = atan(p.x,p.y)/3.141593;
            float r = length(p);
            float h = abs(a);
            float d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);
        #endif
            
            // color
            float s = 0.75 + 0.75*p.x;
            s *= 1.0-0.4*r;
            s = 0.3 + 0.7*s;
            s *= 0.5+0.5*pow( 1.0-clamp(r/d, 0.0, 1.0 ), 0.1 );
            vec3 hcol = vec3(1.0,0.4*r,0.3)*s;
            
            vec3 col = mix( bcol, hcol, smoothstep( -0.01, 0.01, d-r) );
        
            gl_FragColor = vec4(col,1.0);
	        // gl_FragColor = vec4(col*1.3, 1.0);
        }
        `
    })
    const mesh = new THREE.Mesh(geometry, material);

    return {
        mesh,
        uniforms
    }
}


/**
 * 名称: 跳动的心
 * 作者: stonerao https://github.com/stonerao
*/
相关推荐
小徐不会敲代码~13 小时前
Vue3 学习2
前端·javascript·学习
m0_7400437313 小时前
Vue2 语法糖简洁指南
前端·javascript·vue.js
zhougl99613 小时前
区分__proto__和prototype
开发语言·javascript·原型模式
天天向上102414 小时前
成功阻止chrome浏览器自动填充密码
服务器·前端·chrome
一水鉴天14 小时前
整体设计 定稿 之6 完整设计文档讨论及定稿 之1(豆包周助手)
java·前端·数据库
Java.熵减码农14 小时前
基于VueCli自定义创建项目
前端·javascript·vue.js
追逐梦想之路_随笔14 小时前
Js使用多线程Worker和单线程异步处理数据时间比较
前端·javascript
史上最菜开发14 小时前
Ant Design Vue V1.7.8版本,a-input 去空格
javascript·vue.js·anti-design-vue
光算科技14 小时前
商品颜色/尺码选项太多|谷歌爬虫不收录怎么办
java·javascript·爬虫