国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語言 - JavaScript - js教程 - three.js如何實現(xiàn)3D動態(tài)文字效果

three.js如何實現(xiàn)3D動態(tài)文字效果

2022-01-25 16:33alphardex js教程

這篇文章主要給大家介紹了關(guān)于three.js如何實現(xiàn)3D動態(tài)文字效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

大家好,這里是 CSS 魔法使――alphardex。

之前在逛國外網(wǎng)站的時候,發(fā)現(xiàn)有些網(wǎng)站的文字是刻在3D圖形上的,并且能在圖形上運動,視覺效果相當(dāng)不錯,于是筆者就也想用three.js來嘗試復(fù)現(xiàn)出這種效果

three.js如何實現(xiàn)3D動態(tài)文字效果

上圖只是所有效果的其中之一,接下來讓我們一起開干吧~

準(zhǔn)備工作

筆者自行封裝的three.js模板:Three.js Starter

讀者可以點擊右下角fork一份后再開始本項目

本項目需要用到位圖字體,可以直接復(fù)制demo的HTML里的font字體代碼

一個注意點:three-bmfont-text這個庫依賴全局的three.js,因此要在JS里額外引入一次three.js,如下圖

three.js如何實現(xiàn)3D動態(tài)文字效果

實現(xiàn)思路

  1. 加載位圖字體文件,將其轉(zhuǎn)化為文字對象所需要的形狀和材質(zhì)
  2. 創(chuàng)建文字對象
  3. 創(chuàng)建渲染目標(biāo),可以理解為canvas中的canvas,因為接下來我們要將文字對象本身當(dāng)做貼圖
  4. 創(chuàng)建承載字體的容器,將文字對象作為貼圖貼上去
  5. 動畫

正片

搭好架子

<div class="relative w-screen h-screen">
 <div class="kinetic-text w-full h-full bg-blue-1"></div>
 <div class="font">
 <font>
  一坨從demo里CV而來的字體代碼
 </font>
 </div>
</div>
:root {
 --blue-color-1: #2c3e50;
}

.bg-blue-1 {
 background: var(--blue-color-1);
}
import createGeometry from "https://cdn.skypack.dev/three-bmfont-text@3.0.1";
import MSDFShader from "https://cdn.skypack.dev/three-bmfont-text@3.0.1/shaders/msdf";
import parseBmfontXml from "https://cdn.skypack.dev/parse-bmfont-xml@1.1.4";

const font = parseBmfontXml(document.querySelector(".font").innerHTML);
const fontAtlas = "https://i.loli.net/2021/02/20/DcEhuYNjxCgeU42.png";

const kineticTextTorusKnotVertexShader = `(頂點著色器代碼,先空著,具體見下文)`;

const kineticTextTorusKnotFragmentShader = `(片元著色器代碼,先空著,具體見下文)`;

class KineticText extends Base {
 constructor(sel: string, debug: boolean) {
 super(sel, debug);
 this.cameraPosition = new THREE.Vector3(0, 0, 4);
 this.clock = new THREE.Clock();
 this.meshConfig = {
  torusKnot: {
  vertexShader: kineticTextTorusKnotVertexShader,
  fragmentShader: kineticTextTorusKnotFragmentShader,
  geometry: new THREE.TorusKnotGeometry(9, 3, 768, 3, 4, 3)
  }
 };
 this.meshNames = Object.keys(this.meshConfig);
 this.params = {
  meshName: "torusKnot",
  velocity: 0.5,
  shadow: 5,
  color: "#000000",
  frequency: 0.5,
  text: "ALPHARDEX",
  cameraZ: 2.5
 };
 }
 // 初始化
 async init() {
 this.createScene();
 this.createPerspectiveCamera();
 this.createRenderer(true);
 await this.createKineticText(this.params.text);
 this.createLight();
 this.createOrbitControls();
 this.addListeners();
 this.setLoop();
 }
 // 創(chuàng)建動態(tài)文字
 async createKineticText(text: string) {
 await this.createFontText(text);
 this.createRenderTarget();
 this.createTextContainer();
 }
}

加載和創(chuàng)建字體

首先加載字體文件,并創(chuàng)建出形狀和材質(zhì),有了這兩樣就能創(chuàng)建出字體對象了

class KineticText extends Base {
 loadFontText(text: string): any {
 return new Promise((resolve) => {
  const fontGeo = createGeometry({
  font,
  text
  });
  const loader = new THREE.TextureLoader();
  loader.load(fontAtlas, (texture) => {
  const fontMat = new THREE.RawShaderMaterial(
   MSDFShader({
   map: texture,
   side: THREE.DoubleSide,
   transparent: true,
   negate: false,
   color: 0xffffff
   })
  );
  resolve({ fontGeo, fontMat });
  });
 });
 }
 async createFontText(text: string) {
 const { fontGeo, fontMat } = await this.loadFontText(text);
 const textMesh = this.createMesh({
  geometry: fontGeo,
  material: fontMat
 });
 textMesh.position.set(-0.965, -0.525, 0);
 textMesh.rotation.set(ky.deg2rad(180), 0, 0);
 textMesh.scale.set(0.008, 0.025, 1);
 this.textMesh = textMesh;
 }
}

著色器

頂點著色器

通用模板,直接CV即可

varying vec2 vUv;
varying vec3 vPosition;

void main(){
 vec4 modelPosition=modelMatrix*vec4(position,1.);
 vec4 viewPosition=viewMatrix*modelPosition;
 vec4 projectedPosition=projectionMatrix*viewPosition;
 gl_Position=projectedPosition;
 
 vUv=uv;
 vPosition=position;
}

片元著色器

利用fract函數(shù)創(chuàng)建重復(fù)的貼圖,加上位移距離displacement使得貼圖能隨著時間的增加而動起來,再用clamp函數(shù)來根據(jù)z軸大小限定陰影的范圍,意思是離畫面越遠(yuǎn)則陰影越重,反之離畫面越近則陰影越輕

uniform sampler2D uTexture;
uniform float uTime;
uniform float uVelocity;
uniform float uShadow;

varying vec2 vUv;
varying vec3 vPosition;

void main(){
 vec2 repeat=vec2(12.,3.);
 vec2 repeatedUv=vUv*repeat;
 vec2 displacement=vec2(uTime*uVelocity,0.);
 vec2 uv=fract(repeatedUv+displacement);
 vec3 texture=texture2D(uTexture,uv).rgb;
 // texture*=vec3(uv.x,uv.y,1.);
 float shadow=clamp(vPosition.z/uShadow,0.,1.);// farther darker (to 0).
 vec3 color=vec3(texture*shadow);
 gl_FragColor=vec4(color,1.);
}

此時文本顯示到了屏幕上

創(chuàng)建渲染目標(biāo)

為了將字體對象本身作為貼圖,創(chuàng)建了一個渲染目標(biāo)

class KineticText extends Base {
 createRenderTarget() {
 const rt = new THREE.WebGLRenderTarget(
  window.innerWidth,
  window.innerHeight
 );
 this.rt = rt;
 const rtCamera = new THREE.PerspectiveCamera(45, 1, 0.1, 1000);
 rtCamera.position.z = this.params.cameraZ;
 this.rtCamera = rtCamera;
 const rtScene = new THREE.Scene();
 rtScene.add(this.textMesh);
 this.rtScene = rtScene;
 }
}

創(chuàng)建字體容器

創(chuàng)建一個容器,并將字體對象本身作為貼圖貼上去,再應(yīng)用動畫即可完成

class KineticText extends Base {
 createTextContainer() {
 if (this.mesh) {
  this.scene.remove(this.mesh);
  this.mesh = null;
  this.material!.dispose();
  this.material = null;
 }
 this.rtScene.background = new THREE.Color(this.params.color);
 const meshConfig = this.meshConfig[this.params.meshName];
 const geometry = meshConfig.geometry;
 const material = new THREE.ShaderMaterial({
  vertexShader: meshConfig.vertexShader,
  fragmentShader: meshConfig.fragmentShader,
  uniforms: {
  uTime: {
   value: 0
  },
  uVelocity: {
   value: this.params.velocity
  },
  uTexture: {
   value: this.rt.texture
  },
  uShadow: {
   value: this.params.shadow
  },
  uFrequency: {
   value: this.params.frequency
  }
  }
 });
 this.material = material;
 const mesh = this.createMesh({
  geometry,
  material
 });
 this.mesh = mesh;
 }
 update() {
 if (this.rtScene) {
  this.renderer.setRenderTarget(this.rt);
  this.renderer.render(this.rtScene, this.rtCamera);
  this.renderer.setRenderTarget(null);
 }
 const elapsedTime = this.clock.getElapsedTime();
 if (this.material) {
  this.material.uniforms.uTime.value = elapsedTime;
 }
 }
}

別忘了把相機調(diào)遠(yuǎn)一些

this.cameraPosition = new THREE.Vector3(0, 0, 40);

風(fēng)騷的動態(tài)文字出現(xiàn)了:)

three.js如何實現(xiàn)3D動態(tài)文字效果

項目地址

Kinetic Text

demo里不止本文創(chuàng)建的這一種形狀,大家可以隨意把玩。

總結(jié)

到此這篇關(guān)于three.js如何實現(xiàn)3D動態(tài)文字效果的文章就介紹到這了,更多相關(guān)three.js 3D動態(tài)文字內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://juejin.cn/post/6931647184349691911

延伸 · 閱讀

精彩推薦
  • js教程Javascript實現(xiàn)漢字和拼音互轉(zhuǎn)的終極方案

    Javascript實現(xiàn)漢字和拼音互轉(zhuǎn)的終極方案

    網(wǎng)上關(guān)于JS實現(xiàn)漢字和拼音互轉(zhuǎn)的文章很多,但是比較雜亂,有的不支持多音字、不支持聲調(diào)或者字典文件太大,無法根據(jù)實際需要滿足需求。這篇文章給...

    我是小茗同學(xué)10352021-12-15
  • js教程詳解微信小程序軌跡回放實現(xiàn)及遇到的坑

    詳解微信小程序軌跡回放實現(xiàn)及遇到的坑

    這篇文章主要介紹了詳解微信小程序軌跡回放實現(xiàn)及遇到的坑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要...

    Keen6092022-01-12
  • js教程詳解uniapp的全局變量實現(xiàn)方式

    詳解uniapp的全局變量實現(xiàn)方式

    這篇文章主要介紹了詳解uniapp的全局變量實現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下...

    繭君10922021-12-29
  • js教程原生js拖拽功能制作滑動條實例代碼

    原生js拖拽功能制作滑動條實例代碼

    這篇文章主要介紹了原生js拖拽功能制作滑動條實例教程,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的...

    蔣偉平3452022-01-17
  • js教程ES6字符串的擴展實例

    ES6字符串的擴展實例

    這篇文章主要介紹了ES6字符串的擴展實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小...

    知否5552021-12-16
  • js教程ES6的循環(huán)與可迭代對象示例詳解

    ES6的循環(huán)與可迭代對象示例詳解

    這篇文章主要給大家介紹了關(guān)于ES6的循環(huán)與可迭代對象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,...

    瘋狂的技術(shù)宅11542022-01-12
  • js教程three.js 實現(xiàn)露珠滴落動畫效果的示例代碼

    three.js 實現(xiàn)露珠滴落動畫效果的示例代碼

    這篇文章主要介紹了three.js 實現(xiàn)露珠滴落動畫效果的示例代碼,非常不錯,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    稀土掘金11192022-01-24
  • js教程原生JavaScript實現(xiàn)購物車

    原生JavaScript實現(xiàn)購物車

    這篇文章主要為大家詳細(xì)介紹了原生JavaScript實現(xiàn)購物車,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    棟棟很優(yōu)秀啊4362021-12-29
主站蜘蛛池模板: 99热在线播放 | 欧美九九九 | 一级片黄色大片 | 日韩成人在线视频 | 国产精品久久一区 | 久久久久国产精品免费 | 免费观看av网站 | 六月成人网 | 日韩一区不卡 | 国产精品久久九九 | 不卡一区| 九九热在线免费视频 | 欧美国产一区二区三区 | 7799精品天天综合网 | 欧美日韩国产一区二区三区 | 久久久久久久久久久久网站 | 亚洲字幕 | 亚洲伊人久久影院 | 极品美女销魂一区二区三区 | 亚洲国产一区二区三区在线播放 | 黄视频网页 | 中文一区 | 亚洲精品一区 | 欧美日韩一区二区在线 | 欧美一级二级视频 | 国产成人在线一区二区 | 不卡一区 | 一级片免费视频 | 一区二区在线不卡 | 青春草国产免费福利视频一区 | 国产一区不卡 | 精品一级 | 欧美日韩成人 | 精品久久网 | 久久国产精品一区 | 在线a视频| 嫩草视频在线 | 欧美精品在线一区 | 国内自拍偷拍视频 | 成人午夜网| 国产麻豆一区二区三区 |