65 - three.js 筆記 - 載入 DDS 格式的紋理
阿新 • • 發佈:2018-11-12
1、DDS紋理格式
首先,圖片轉換成dds
格式,佔用磁碟會變大,但是轉換成dds
格式之後架載入到記憶體和視訊記憶體的佔用量會變小。
1.1、dds格式簡介
DDS
格式要追述到S3
(Silicon & Software Systems
)公司提出的一種紋理壓縮格式S3TC
(S3 Texture Compression
),其目的是通過對紋理的壓縮, 以達到節約系統頻寬並提高效能的目的.。
S3TC
就是通過壓縮方式, 利用有限的紋理快取空間來儲存更多的紋理, 因為它支援6:1
的壓縮比例, 所以6M
的紋理可以被壓縮為1M
存放在材質快取中, 從而在節約了快取的同時也提高了顯示效能. 後來的DXTC
FXT1
都是與S3TC
類似的技術, 它們分別是微軟和3dfx
開發的紋理壓縮標準,FXT1
能提供比S3TC
更高的壓縮比, 達到8:1
, 同時它也在3DFX
新版本的Glide
中得到支援。
DXTC
是1999
年微軟從S3
公司取得S3TC
的授權後更名而來的, 並在DirectX6
中提供了支援, 即使使用者的圖形硬體不能支援S3TC
, DirectX API
會自動解碼壓縮後的紋理貼圖. 壓縮紋理貼圖可以使用高品質的離線壓縮器, 不會造成載入程式時有很多延時, 而DDS
檔案就可以使用DXTC
方式壓縮或是儲存未壓縮的畫素格式。
簡單的說DDS
紋理的特性是佔用磁碟空間大,但其紋理壓縮格式的特性,可以節約快取使佔用記憶體大大降低,一些3D
DDS
貼圖,提高遊戲技能,順暢度也大幅提高。
2、載入 DDS格式的紋理
2.1、示例
示例
http://ithanmang.com/threeJs/home/201809/20180905/02-basic-texture-dds.html
效果
2.2、步驟
首先,需要引入DDS
格式紋理的載入器
<!--匯入 DDS 載入器-->
<script src="../../libs/examples/js/loaders/DDSLoader.js"></script>
建立例項,並載入檔案
let texture = new THREE.DDSLoader().load('../../textures/dds/' +imageUrl,function () {
......
});
3、完整程式碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="../../../three.png">
<title>基礎紋理-載入dds格式的紋理</title>
<style>
body {
margin: 0;
overflow: hidden; /* 溢位隱藏 */
}
#loading {
position: fixed;
top: 50%;
left: 50%;
color: #FFFFFF;
font-size: 20px;
margin-top: -30px;
margin-left: -40px;
}
</style>
<script src="../../libs/build/three-r93.js"></script>
<script src="../../libs/examples/js/Detector.js"></script>
<script src="../../libs/examples/js/libs/dat.gui.min.js"></script>
<script src="../../libs/examples/js/libs/stats.min.js"></script>
<script src="../../libs/examples/js/controls/OrbitControls.js"></script>
<!--匯入 DDS 載入器-->
<script src="../../libs/examples/js/loaders/DDSLoader.js"></script>
</head>
<body>
<p id="loading">loading......</p>
<script>
let scene, camera, renderer, controls, guiControls;
let stats = initStats();
/* 場景 */
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x050505);
}
/* 相機 */
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, -50);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
/* 渲染器 */
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/* 燈光 */
function initLight() {
scene.add(new THREE.AmbientLight(0x0c0c0c));
let spotLight1 = new THREE.SpotLight(0xffffff);
spotLight1.position.set(-400, -400, -400);
let spotLight2 = new THREE.SpotLight(0xffffff);
spotLight2.position.set(400, 400, 400);
scene.add(spotLight1);
scene.add(spotLight2);
}
/* 控制器 */
function initControls() {
/* 地圖控制元件 */
controls = new THREE.OrbitControls(camera, renderer.domElement);
/* 屬性引數 */
}
/* 除錯外掛 */
function initGui() {
guiControls = new function () {
};
let gui = new dat.GUI();
}
/* 場景中的內容 */
let sphere;
let box;
function initContent() {
sphere = createMesh(new THREE.SphereGeometry(5, 20, 20), 'seafloor.dds');
box = createMesh(new THREE.BoxGeometry(7, 7, 7), 'seafloor.dds');
box.translateX(7);
sphere.translateX(-7);
scene.add(sphere);
scene.add(box);
}
/* 移除載入元素 */
function removeLoading() {
document.getElementById('loading').style.display = 'none';
}
/* 建立帶有紋理的網格 */
function createMesh(geometry, imageUrl) {
let texture = new THREE.DDSLoader().load('../../textures/dds/'+imageUrl,function () {
removeLoading();
});
let material = new THREE.MeshPhongMaterial();
material.map = texture;
let mesh = new THREE.Mesh(geometry, material);
return mesh;
}
/* 效能外掛 */
function initStats() {
let stats = new Stats();
document.body.appendChild(stats.domElement);
return stats;
}
/* 視窗變動觸發 */
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/* 資料更新 */
function update() {
stats.update();
controls.update();
if (sphere) {
// sphere.rotationY
sphere.rotateY(0.01);
}
if (box) {
box.rotateY(0.01);
}
}
/* 初始化 */
function init() {
initScene();
initCamera();
initRender();
initLight();
initControls();
initContent();
initGui();
/* 監聽事件 */
window.addEventListener('resize', onWindowResize, false);
}
/* 迴圈渲染 */
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
update();
}
/* 初始載入 */
(function () {
console.log("three init start...");
init();
animate();
console.log("three init end...");
})();
</script>
</body>
</html>