webgl_framebuffer_texture

2024-06-07 07:28
文章标签 framebuffer webgl texture

本文主要是介绍webgl_framebuffer_texture,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ThreeJS 官方案例学习(webgl_framebuffer_texture)

1.效果图

在这里插入图片描述

2.源码

<template><div><div id="container"></div><div id="selection"><div></div></div></div>
</template>
<script>
import * as THREE from 'three';
// 导入控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 引入房间环境,创建一个室内环境
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
// 导入性能监视器
import Stats from 'three/examples/jsm/libs/stats.module.js';
// 导入gltf载入库、模型加载器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
// 引入模型解压器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
//GUI界面
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
import gsap from 'gsap';
import * as GeometryUtils from 'three/examples/jsm/utils/GeometryUtils.js';
const dpr = window.devicePixelRatio;const textureSize = 128 * dpr;
export default {data() {return {container: null, //界面需要渲染的容器scene: null,	// 场景对象camera: null, //相机对象(透视相机)renderer: null, //渲染器对象controller: null,	// 相机控件对象stats: null,// 性能监听器mixer: null,//动画混合器clock: new THREE.Clock(),// 创建一个clock对象,用于跟踪时间vector: new THREE.Vector2(),//用于计算复制部分帧数据的起始位置color: new THREE.Color(),//Color颜色对象,方便后续使用offset: 0,//颜色偏移度line: null,//线模型sprite: null,//点精灵材质texture: null,//帧缓冲纹理cameraOrtho: null,//正交相机sceneOrtho: null,//};},mounted() {this.init()this.animate()  //如果引入了模型并存在动画,可在模型引入成功后加载动画window.addEventListener("resize", this.onWindowSize)},beforeUnmount() {console.log('beforeUnmount===============');// 组件销毁时置空,视具体情况自定义销毁,以下实例不完整this.container = nullthis.scene = nullthis.camera = nullthis.renderer = nullthis.controller = nullthis.stats = nullthis.mixer = nullthis.model = null//导入的模型},methods: {/*** @description 初始化*/init() {this.container = document.getElementById('container')this.setScene()this.setCamera()this.setRenderer()this.addHelper()this.setController()this.setPMREMGenerator()this.setLight()this.setGltfLoader()// this.addStatus()},/*** @description 创建场景*/setScene() {// 创建场景对象Scenethis.scene = new THREE.Scene()// 设置场景背景// this.scene.background = new THREE.Color(0xbfe3dd);this.sceneOrtho = new THREE.Scene();},/*** @description 创建相机*/setCamera() {// 第二参数就是 长度和宽度比 默认采用浏览器  返回以像素为单位的窗口的内部宽度和高度this.camera = new THREE.PerspectiveCamera(70, this.container.clientWidth / this.container.clientHeight, 1, 1000)// 设置相机位置this.camera.position.set(0, 0, 20)// 设置摄像头宽高比例this.camera.aspect = this.container.clientWidth / this.container.clientHeight;// 设置摄像头投影矩阵this.camera.updateProjectionMatrix();// 设置相机视线方向this.camera.lookAt(new THREE.Vector3(0, 0, 0))// 0, 0, 0 this.scene.position// 将相机加入场景this.scene.add(this.camera)// 添加正交相机this.cameraOrtho = new THREE.OrthographicCamera(- this.container.clientWidth / 2, this.container.clientWidth / 2, this.container.clientHeight / 2, - this.container.clientHeight / 2, 1, 10);this.cameraOrtho.position.z = 10;},/*** @description 创建渲染器*/setRenderer() {// 初始化渲染器this.renderer = new THREE.WebGLRenderer({antialias: true,// 设置抗锯齿logarithmicDepthBuffer: true,  // 是否使用对数深度缓存})// 设置渲染器宽高this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);// 设置渲染器的像素比// this.renderer.setPixelRatio(window.devicePixelRatio);// 是否需要对对象排序// this.renderer.sortObjects = false;// 渲染器是否在渲染每一帧之前自动清除其输出this.renderer.autoClear = false;// 将渲染器添加到页面this.container.appendChild(this.renderer.domElement);},/*** @description 添加创建控制器*/setController() {// 为什么要绑定 selection 对象(可能selection的css层级最高,需要绑定它才能移动模型)this.controller = new OrbitControls(this.camera, document.getElementById('selection'));// 绑定这个也可以运行 this.renderer.domElement,但是要降低 selection 的层级,但是降低了就看不到白色边框了,需要另外除了白色边框// this.controller = new OrbitControls(this.camera, this.renderer.domElement);// 控制缩放范围// this.controller.minDistance = 1;// this.controller.maxDistance = 5;//是否开启右键拖拽this.controller.enablePan = false;// 阻尼(惯性)this.controller.enableDamping = true; //启用阻尼(惯性)this.controller.dampingFactor = 0.04; //阻尼惯性有多大},/*** @description 创建辅助坐标轴*/addHelper() {// 模拟相机视锥体的辅助对象let helper = new THREE.CameraHelper(this.camera);// this.scene.add(helper);//创建辅助坐标轴、轴辅助 (每一个轴的长度)let axisHelper = new THREE.AxesHelper(150);  // 红线是X轴,绿线是Y轴,蓝线是Z轴this.scene.add(axisHelper)// 坐标格辅助对象let gridHelper = new THREE.GridHelper(100, 30, 0x2C2C2C, 0x888888);// this.scene.add(gridHelper);},/*** @description 给场景添加环境光效果*/setPMREMGenerator() {// 预过滤的Mipmapped辐射环境贴图const pmremGenerator = new THREE.PMREMGenerator(this.renderer);this.scene.environment = pmremGenerator.fromScene(new RoomEnvironment(this.renderer), 0.04).texture;},/*** @description 设置光源*/setLight() {// 环境光const ambientLight = new THREE.AmbientLight(0x404040, 4);// this.scene.add(ambientLight);// 平行光const directionalLight = new THREE.DirectionalLight(0xffffff, 100);// this.scene.add(directionalLight);// 点光源 - 照模型const test = new THREE.PointLight("#ffffff", 10, 2);// test.position.set(0, 0, 0);// this.scene.add(test);//点光源 - 辅助对象const testHelperMap = new THREE.PointLightHelper(test);// this.scene.add(testHelperMap);},/*** @description 创建性能监听器*/addStatus() {// 创建一个性能监听器this.stats = new Stats();// 将性能监听器添加到容器中this.container.appendChild(this.stats.dom);},/*** @description 添加创建模型*/setGltfLoader() {// 添加线模型const points = GeometryUtils.gosper(8)const geometry = new THREE.BufferGeometry()const positionAttribute = new THREE.Float32BufferAttribute(points, 3)geometry.setAttribute('position', positionAttribute)geometry.center()const colorAttribute = new THREE.BufferAttribute(new Float32Array(positionAttribute.array.length), 3)colorAttribute.setUsage(THREE.DynamicDrawUsage);geometry.setAttribute('color', colorAttribute);const material = new THREE.LineBasicMaterial({ vertexColors: true });// 使用点设置的颜色,使用点设置的颜色this.line = new THREE.Line(geometry, material)this.line.scale.setScalar(0.05)this.scene.add(this.line)//实例化一个framebuffer纹理this.texture = new THREE.FramebufferTexture(textureSize, textureSize);//(这个类只能与 WebGLRenderer.copyFramebufferToTexture() 结合使用)const spriteMaterial = new THREE.SpriteMaterial({ map: this.texture });//创建Sprite平面this.sprite = new THREE.Sprite(spriteMaterial);this.sprite.scale.set(textureSize, textureSize, 1);this.sceneOrtho.add(this.sprite)this.updateSpritePosition()this.updateColors(colorAttribute);},/*** @description 更新Sprite位置*/updateSpritePosition() {const halfWidth = this.container.clientWidth / 2;const halfHeight = this.container.clientHeight / 2;const halfImageWidth = textureSize / 2;const halfImageHeight = textureSize / 2;this.sprite.position.set(- halfWidth + halfImageWidth, halfHeight - halfImageHeight, 1);},/*** @description 模型颜色更新*/updateColors(colorAttribute) {const l = colorAttribute.count;for (let i = 0; i < l; i++) {const h = ((this.offset + i) % l) / l;this.color.setHSL(h, 1, 0.5);colorAttribute.setX(i, this.color.r);colorAttribute.setY(i, this.color.g);colorAttribute.setZ(i, this.color.b);}colorAttribute.needsUpdate = true;// 颜色循环速度(偏离量)this.offset -= 10;},/*** @description 监听屏幕的大小改变,修改渲染器的宽高,相机的比例*/// 窗口变化onWindowSize() {// 更新摄像头this.camera.aspect = this.container.clientWidth / this.container.clientHeight;// 更新摄像机的投影矩阵this.camera.updateProjectionMatrix();//更新渲染器this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);// 设置渲染器的像素比this.renderer.setPixelRatio(window.devicePixelRatio)// 更新cameraOrthoconst width = this.container.clientWidth;const height = this.container.clientHeight;this.cameraOrtho.left = - width / 2;this.cameraOrtho.right = width / 2;this.cameraOrtho.top = height / 2;this.cameraOrtho.bottom = - height / 2;this.cameraOrtho.updateProjectionMatrix();this.updateSpritePosition()},/*** @description 动画执行函数*/animate() {// 引擎自动更新渲染器requestAnimationFrame(this.animate);//update()函数内会执行camera.lookAt(x, y, z)this.controller.update();// 更新性能监听器// this.stats.update();// 模型颜色更新const colorAttribute = this.line.geometry.getAttribute('color');this.updateColors(colorAttribute);//场景渲染this.renderer.clear();// 重新渲染场景this.renderer.render(this.scene, this.camera);// 计算复制部分帧数据的起始位置this.vector.x = (this.container.clientWidth * dpr / 2) - (textureSize / 2);this.vector.y = (this.container.clientHeight * dpr / 2) - (textureSize / 2);//复制渲染帧的一部分到framebuffer纹理this.renderer.copyFramebufferToTexture(this.vector, this.texture);this.renderer.clearDepth();this.renderer.render(this.sceneOrtho, this.cameraOrtho);},},
};
</script>
<style>
#container {position: absolute;width: 100%;height: 100%;
}#selection {position: fixed;display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100%;width: 100%;top: 0;z-index: 999;
}#selection>div {height: 128px;width: 128px;border: 1px solid white;
}
</style>r {position: absolute;width: 100%;height: 100%;
}#selection {position: fixed;display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100%;width: 100%;top: 0;z-index: 999;
}#selection>div {height: 128px;width: 128px;border: 1px solid white;
}
</style>

这篇关于webgl_framebuffer_texture的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038525

相关文章

解决TMP_InputField 在WebGL(抖音)上不能唤起虚拟键盘,不能使用手机内置输入法的问题

整整花费了一天时间测试和解决。试验了多个方法,花了不少美刀,最终才发现抖音这个官方文档,哭了: https://partner.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/game-engine/rd-to-SCgame/open-capacity/capability-adaptation/sc_webgl_keyboa

WebGL:二、ThreeJs 简介

在初步学习OpenGL 和 WebGL(基于 OpenGL ES) 之后,发现这两者都对初学者不够友好,繁多复杂的API,以及高深的建模原理矩阵运算,线代等大大提高了学习的门槛。 ThreeJs是对webGL提供的接口进行了良好的封装,简化了很多专业知识,学习成本明显降低。 以下,是用webGL绘制一个矩形的样例片段: (ps:我就画一个矩形,一下子就整这么多方法,这还算是

WebGL on iOS8 终于等到了这一天

WWDC2014刚结束,这次的大会是名符其实的开发者大会,更贴切的应该说的确是一次软件开发者的大会,对于OSX和iOS的更多功能特性让人兴奋,Swift新语言促成了如上图片 但我更感兴趣的是WebGL终于官方的在OSX和iOS上得到了支持,这篇《A first look at what iOS8 means for Phaser and Pixi.js》分享了在iOS下运行We

HTML5的WebGL实现的3D和2D拓扑树

在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到指定的节点比较困难,而3D上的树状结构在展现上配合HT for Web的弹力布局组件会显得比较直观,一眼望去可以把整个树状结构数据看个大概,但是在弹力布局的作用下,其层次结构看得就不是那么清晰了。所以这时候结构清晰的3D树的需求就来了,那

基于HTML5的WebGL结合Box2DJS物理引擎应用

上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是二维的平面碰撞物理引擎,但同样通过3D的呈现能让人更直观的体验到碰撞效果,最终例子效果: http://hightopo.com/demo/box2djs/ht-box2d-demo.html

WebGL实现HTML5的贪吃蛇3D游戏

js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型,多次想尝试提交个小游戏但总无法写出让自己满意还能控制在这么小的字节范围。 自己写不出来,站在巨人肩膀总是有机会吧,想起《基于HTML5的电信网管3D机房监控应用》这篇提到的threejs,bab

基于HTML5的WebGL呈现A星算法的3D可视化

http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现,算法基于开源 https://github.com/bgrins/javascript-astar 的javascript实现,其实作者也有个不错的2D例子实现 http://w

基于HTML5的WebGL经典3D虚拟机房漫游动画

第一人称在 3D 中的用法要参考第一人称在射击游戏中的使用,第一人称射击游戏(FPS)是以第一人称视角为中心围绕枪和其他武器为基础的视频游戏类型 ; 也就是说,玩家通过主角的眼睛来体验动作。自从流派开始以来,先进的 3D 和伪 3D 图形已经对硬件发展提出了挑战,而多人游戏已经不可或缺。   Doom 的截图,这个流派的突破游戏之一,展示了第一人称射击游戏的典型视角   现在博物馆或者公司也经

根据矩阵变化实现基于 HTML5 的 WebGL 3D 自动布局

在数学中,矩阵是以行和列排列的数字,符号或表达式的矩形阵列,任何矩阵都可以通过相关字段的标量乘以元素。矩阵的主要应用是表示线性变换,即f(x)= 4 x等线性函数的推广。例如,旋转的载体在三维空间是一个线性变换,这可以通过一个表示旋转矩阵 [R :如果v是一个列向量描述(只有一列的矩阵)的位置在空间中的点,该产品器Rv是列矢量描述旋转后该点的位置。两个变换矩阵的乘积是表示两个变换组成的矩阵。矩阵

玩转 HTML5 下 WebGL 的 3D 模型交并补

CSG 构造实体几何这个概念在工业水利水电施工上、游戏上已经有很多人使用了,最简单的实体表示叫作体元,通常是形状简单的物体,如立方体、圆柱体、棱柱、棱锥、球体、圆锥等。根据每个软件包的不同这些体元也有所不同,在一些软件包中可以使用弯曲的物体进行 CSG 处理,在另外一些软件包中则不支持这些功能。构造物体就是将体元根据集合论的布尔逻辑组合在一起,这些运算包括:并集、交集以及补集。我们一般可以用 CS