shader特效之能量盾

  • 前言
  • 效果噪点图
  • 主要代码
    • index.html
    • depth-fs.js
    • depth-vs.js
    • shield-fs.js
    • shield-vs.js
  • 相关项目

前言

效果噪点图

为了可以自定义能量球的效果,这里使用外部加载来的噪点图做纹理,省去用代码写特效的过程。

主要代码

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><title>Energy shield</title><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /><style>body {margin: 0;padding: 0;}</style>
</head><body><script type="module">import * as THREE from '../../build/three.module.js'import * as TWEEN from '../../build/tween.esm.js'import Stats from '../jsm/libs/stats.module.js'import { OrbitControls } from '../jsm/controls/OrbitControls.js'import { shader as depthVertexShader } from './shaders/depth-vs.js'import { shader as depthFragmentShader } from './shaders/depth-fs.js'import { shader as shieldVertexShader } from './shaders/shield-vs.js'import { shader as shieldFragmentShader } from './shaders/shield-fs.js'// rendererconst renderer = new THREE.WebGLRenderer({ antialias: true })renderer.setPixelRatio(window.devicePixelRatio)renderer.shadowMap.enabled = truerenderer.shadowMap.type = THREE.PCFSoftShadowMaprenderer.outputEncoding = THREE.sRGBEncodingrenderer.gammaFactor = 2.2document.body.append(renderer.domElement)// statsconst stats = new Stats()document.body.appendChild(stats.domElement)// sceneconst scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 100)camera.position.set(0, 1, 2)// controlconst controls = new OrbitControls(camera, renderer.domElement)controls.minDistance = 0.5controls.maxDistance = 10controls.enableDamping = truecontrols.dampingFactor = 0.05controls.screenSpacePanning = truecontrols.autoRotate = false// cubeconst cubeGeometry = new THREE.BoxBufferGeometry(0.4, 0.4, 0.4)const cubeMaterial = new THREE.MeshStandardMaterial({color: 'rgb(100, 70, 30)',roughness: 0.4,metalness: 0.0,side: THREE.DoubleSide})const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)cube.castShadow = cube.receiveShadow = truecube.position.set(-0.6, 0.2, -0.6)cube.rotation.set(-Math.PI / 2, 0, 0)scene.add(cube)// groundconst groundGeometry = new THREE.PlaneBufferGeometry(3, 3)const groundMaterial = new THREE.MeshStandardMaterial({color: 'rgb(20, 20, 30)',roughness: 0.4,metalness: 0.0,side: THREE.DoubleSide})const ground = new THREE.Mesh(groundGeometry, groundMaterial)ground.castShadow = ground.receiveShadow = trueground.position.set(0, 0, 0)ground.rotation.set(-Math.PI / 2, 0, 0)scene.add(ground)// light1const light = new THREE.DirectionalLight(0xffffff)light.position.set(-2, 2, 0.5)light.castShadow = truelight.shadow.camera.top = 2light.shadow.camera.bottom = -2light.shadow.camera.right = 2light.shadow.camera.left = -2light.shadow.bias = -0.00001light.shadow.mapSize.set(4096, 4096)scene.add(light)// light2const hemiLight = new THREE.HemisphereLight(0xbbbbbb, 0x080808, 1)scene.add(hemiLight)// light1 helperscene.add(new THREE.DirectionalLightHelper(light, 2, 0xFFFF00))// axis helperscene.add(new THREE.AxesHelper(100))const depthMaterial = new THREE.RawShaderMaterial({uniforms: {},vertexShader: depthVertexShader,fragmentShader: depthFragmentShader,})const depth = new THREE.WebGLRenderTarget(1, 1, {wrapS: THREE.ClampToEdgeWrapping,wrapT: THREE.ClampToEdgeWrapping,minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBAFormat,type: THREE.UnsignedByteType,stencilBuffer: false,depthBuffer: true})const hdr = new THREE.WebGLRenderTarget(1, 1, {wrapS: THREE.ClampToEdgeWrapping,wrapT: THREE.ClampToEdgeWrapping,minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBAFormat,type: THREE.UnsignedByteType,stencilBuffer: false,depthBuffer: true})// shieldconst textureLoader = new THREE.TextureLoader()const texture = textureLoader.load('./imgs/noise1.png')texture.wrapS = texture.wrapT = THREE.RepeatWrappingconst shieldGeometry = new THREE.SphereBufferGeometry(0.5, 100, 100)const shieldMaterial = new THREE.RawShaderMaterial({uniforms: {depthBuffer: { value: null },resolution: { value: new THREE.Vector2(1, 1) },bufColor: { value: null },u_tex: { value: null },time: { value: 0 }},vertexShader: shieldVertexShader,fragmentShader: shieldFragmentShader,transparent: true,depthWrite: false,side: THREE.DoubleSide})const shield = new THREE.Mesh(shieldGeometry, shieldMaterial)shield.position.set(0, 0.3, 0)shield.material.uniforms.depthBuffer.value = depth.textureshield.material.uniforms.bufColor.value = depth.textureshield.material.uniforms.u_tex.value = texturescene.add(shield)// tweenfunction moveCube() {const tween = new TWEEN.Tween(cube.position)tween.to({x: 0.6,z: 0.6}, 5000)tween.yoyo(true)tween.repeat(Infinity)tween.start()}// resizefunction resize() {const width = window.innerWidthconst height = window.innerHeightconst dPR = window.devicePixelRatiocamera.aspect = width / heightcamera.updateProjectionMatrix()renderer.setSize(width, height)depth.setSize(width * dPR, height * dPR)hdr.setSize(width * dPR, height * dPR)shield.material.uniforms.resolution.value.set(width * dPR, height * dPR)}// renderfunction render() {shield.visible = falsescene.overrideMaterial = depthMaterialrenderer.setRenderTarget(depth)renderer.render(scene, camera)shield.visible = truescene.overrideMaterial = nullrenderer.setRenderTarget(null)renderer.render(scene, camera)renderer.setAnimationLoop(render)TWEEN.update()stats.update()controls.update()shield.material.uniforms.time.value = performance.now()}window.addEventListener('resize', resize)moveCube()resize()render()</script>
</body></html>

depth-fs.js

const shader = `#version 300 esprecision highp float;#include <packing>in vec2 vUv;
in float vDepth;out vec4 color;void main() {float depth = (vDepth - .1) / ( 10.0 -.1);color = packDepthToRGBA(depth);
}
`;export { shader };

depth-vs.js

const shader = `#version 300 esprecision highp float;in vec3 position;
in vec2 uv;uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;out vec2 vUv;
out float vDepth;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);vDepth = gl_Position.z;
}
`;export { shader };

shield-fs.js

const shader = `#version 300 esprecision highp float;#include <packing>uniform sampler2D depthBuffer;
uniform vec2 resolution;
uniform float time;
uniform sampler2D u_tex;in float vRim;
in vec2 vUv;
in float vDepth;out vec4 color;const vec4 baseColor = vec4(0.0,0.9,0.0,0.1);void main() {// 基础色color = baseColor;// 动态纹理vec4 maskA = texture(u_tex, vUv);maskA.a = maskA.r;color += maskA;// 边界高亮vec2 uv = gl_FragCoord.xy / resolution;vec4 packedDepth = texture(depthBuffer, uv);float sceneDepth = unpackRGBAToDepth(packedDepth);float depth = (vDepth - .1) / ( 10.0 -.1);float diff = abs(depth - sceneDepth);float contact = diff * 20.;contact = 1. - contact;contact = max(contact, 0.);contact = pow(contact, 20.);contact *= diff*1000.;float a = max(contact, vRim);float fade = 1. - pow(vRim, 10.);color += a * fade;
}
`;export { shader };

shield-vs.js

const shader = `#version 300 esprecision highp float;in vec3 position;
in vec3 normal;
in vec2 uv;uniform mat3 normalMatrix;
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform float time;out vec2 vUv;
out float vRim;
out float vDepth;void main() {vUv = uv;vUv.x += time * 0.0001;vUv.y += time * 0.0006;vec3 n = normalMatrix * normal;vec4 viewPosition = modelViewMatrix * vec4( position, 1. );vec3 eye = normalize(-viewPosition.xyz);vRim = 1.0 - abs(dot(eye,n));vRim = pow(vRim, 5.);vec3 worldPosition = (modelMatrix * vec4(position, 1.)).xyz;  gl_Position = projectionMatrix * viewPosition;vDepth = gl_Position.z;
}
`;export { shader };

相关项目

【Three.js】shader特效之能量盾相关推荐

  1. html、css、js粒子特效——前端

    html.css.js粒子特效--前端 看看效果图 首先是html结构 使用canvas设置一个画布 <canvas width="500px" height="5 ...

  2. js网状特效源代码下载

    原文:js网状特效源代码下载 源代码下载地址:http://www.zuidaima.com/share/1550463532010496.htm 適合自己的網站的開場

  3. auto.js蚂蚁森林收能量

    auto.js蚂蚁森林收能量 在网上看了一些自动收能量的脚本 写了一个脚本 使用AutoJs运行 AutoJS下载地址 :here 运行步骤如下: 1.解锁(点亮屏幕,切换到输入密码界面,输入密码) ...

  4. JS网页特效实例:禁止网页放入框架

    在网络上,为了防止网页被随意地引入到别人的框架里,可以通过判断网页是否为最顶层网页来禁止网页被放入框架. 补充下面代码,禁止网页放入框架. ```html <!DOCTYPE HTML> ...

  5. 分享111个JS文字特效,总有一款适合您

    分享111个JS文字特效,总有一款适合您 111个JS文字特效下载链接:https://pan.baidu.com/s/1Ql-wGwfjovvu78bvpwD-8w?pwd=wqgg  提取码:wq ...

  6. html5点击效果文字跳转,JS网页特效代码,点击跳出爱心和文字特效

    鼠标左键点击网页会跳出爱心,相信不少站长见过这种JS网页特效,有些点击还会跳出文字.橘子君也是觉得挺好奇的,然后也给网站加了一段时间这种特效,后来由于种种原因的考虑,博主又将该代码删除了.如果你对这种 ...

  7. 原生JS实现特效导航条

    分享一个用原生JS实现的特效导航条,效果如下: 实现代码如下: <!DOCTYPE html><head><meta charset="utf-8" ...

  8. js登录特效+ajax提交表单+异步刷新验证

    今天成功测试一种js登录特效+ajax提交表单+异步刷新验证,登录时特效提醒,无刷新ajax提交表单,获取验证结果,跳转正式页面:废话不多说,先直接分享代码: 1.主界面index.php  加载的这 ...

  9. unity黑白滤镜_Unity3D后期Shader特效-马赛克4-打印效果(黑白图像|明度比较)

    =========源文件下载群======== QQ群:818511955 ========================= 首先看效果 这次CS程序不变 =========CRLuo_Camera ...

最新文章

  1. python产生fir滤波器_Python中使用FIR滤波器firwin后信号的相移
  2. 组合部分标签向量并累加成完整向量
  3. ES6 Map对象的使用
  4. 获取python版本
  5. 大型网站的Google排名策略
  6. Pytorch《DCGAN模型》
  7. 《图解HTTP》阅读笔记--第六章--HTTP首部
  8. Geometry-enhanced molecular representation learning for property prediction|GeoGNN|将几何增强分子表示用于分子性质预测
  9. 怎么看服务器网络带宽?该怎样选择服务器的网络带宽和流量?
  10. 手机扫描二维码,下载apk
  11. C#图片处理:生成大尺寸图片,以边框颜色填充
  12. Linux防火墙设置黑白名单
  13. 小百对python的缺省参数的理解
  14. java web 编辑器_22个所见即所得在线 Web 编辑器
  15. 码蹄集 - MT3029 - 新月轩就餐
  16. 2021-03-13高级经理计算题:成本效益分析
  17. 【汇编和c语言】空函数和裸函数和调用约定
  18. 【学习OpenCV】warpAffine函数实现图像旋转
  19. 2022国赛题vsftpd
  20. compact mysql_mysql中compact行的存储结构

热门文章

  1. 计算机运行游戏慢怎么办,电脑运行速度慢怎么回事 电脑运行速度慢的解决方法...
  2. Java中String转换为单字String集合的三种实现方式
  3. Python环境变量与引包错误
  4. H664HY快速关闭气动抽气止回阀性能规范用途
  5. 10月29日晚8点,国产开源物联网操作系统TencentOS tiny线上直播开讲
  6. 力扣 -----最小绝对值(JavaScript解法)
  7. 程序员抢复联4首映票的正确方式
  8. 配置yarn下载源_npm、yarn 常用镜像源配置
  9. shell 数组遍历
  10. python高考谣言_Python爬取新版型冠状病毒“谣言”新版闻进行数据分析