本例来源于官方案例
立方体贴图
全景贴图
① 创建场景和相机
②创建物体
③ 创建渲染器
④创建GUI
Title
import * as THREE from "./js/three.module.js";
import {OrbitControls} from "./js/OrbitControls.js";
import { GUI } from './js/dat.gui.module.js';
import Stats from './js/stats.module.js';
let renderer,scene,camera,spotLight,status,cameraCube,sceneCube,cubeMesh,SphereMaterial;
action();
function action() {
onload();
run();
}
function onload(){
}
function run()
{
}
function onResize()
{
}
onload函数中
let container=document.getElementById("container");//获取container
scene=new THREE.Scene();//创建场景(主)
camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,10000);
camera.position.set(0, 0, 1000);//创建相机并设置位置
sceneCube = new THREE.Scene();//创建立方体场景(副)
cameraCube=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,10000);
onload函数中
let ambientLight=new THREE.AmbientLight();//添加环境光
scene.add(ambientLight);
spotLight=new THREE.SpotLight(0xffffff);//添加点光源
spotLight.position.set(-600, 300,300);
spotLight.intensity=3;
scene.add(spotLight);
let spotLightMesh=new THREE.Mesh(new THREE.SphereGeometry(15,20,20),new THREE.MeshBasicMaterial());
spotLight.add(spotLightMesh);
let gridHelper=new THREE.GridHelper(30,20);
scene.add(gridHelper);
//立方体贴图
let textureCube=new THREE.CubeTextureLoader().setPath("img/").load(["posx.jpg", "negx.jpg","posy.jpg","negy.jpg","posz.jpg","negz.jpg"]);
textureCube.encoding=THREE.sRGBEncoding;//在导入材质时,会默认将贴图编码格式定义为Three.LinearEncoding,故需将带颜色信息的贴图(baseColorTexture, emissiveTexture, 和 specularGlossinessTexture)手动指定为Three.sRGBEncoding
textureCube.mapping=THREE.CubeReflectionMapping;//立方体反映射①
textureCube.format=THREE.RGBFormat;//默认THREE.RGBAFormat,对于JPG会自动设置为THREE.RGBFormat ②
// console.log(textureCube);
let SphereGeometry=new THREE.SphereBufferGeometry(300.0, 48, 24);
SphereMaterial=new THREE.MeshLambertMaterial({envMap:textureCube});
let SphereMesh=new THREE.Mesh(SphereGeometry,SphereMaterial);
scene.add(SphereMesh);
let cubeShader=THREE.ShaderLib["cube"];
console.log(THREE.ShaderLib);
let cubeMaterial=new THREE.ShaderMaterial({
fragmentShader:cubeShader.fragmentShader,
vertexShader:cubeShader.vertexShader,
uniforms:cubeShader.uniforms,
depthWrite:false,
side: THREE.BackSide
});
cubeMaterial.uniforms["tCube"].value=textureCube;
console.log(cubeMaterial);
//全景贴图
let panorama=new THREE.TextureLoader().load("./img/2294472375_24a3b8ef46_o.jpg");
panorama.mapping = THREE.EquirectangularReflectionMapping;
panorama.magFilter = THREE.LinearFilter;//③
panorama.minFilter = THREE.LinearMipmapLinearFilter;//④
panorama.encoding = THREE.sRGBEncoding;
let panoramaShader=THREE.ShaderLib["equirect"];
let panoramaMaterial=new THREE.ShaderMaterial({
fragmentShader:panoramaShader.fragmentShader,
vertexShader: panoramaShader.vertexShader,
uniforms:panoramaShader.uniforms,
depthWrite: false,
side: THREE.BackSide
});
panoramaMaterial.uniforms["tEquirect"].value=panorama;
cubeMesh=new THREE.Mesh(new THREE.BoxBufferGeometry( 10, 100, 100 ),cubeMaterial);
sceneCube.add(cubeMesh);
解释
①:textureCube.mapping:就是UV贴图的类型,它的取值如下
THREE.CubeReflectionMapping:立方体反射映射
THREE.CubeRefractionMapping:立方体折射映射
THREE.EquirectangularReflectionMapping:圆柱反射映射
THREE.EquirectangularRefractionMapping:圆柱折射映射
THREE.SphericalReflectionMapping:球面反t射映射
② :textureCube.format
缺省纹理格式为THREE.RGBAFormat。其他格式有:
THREE.AlphaFormat:对应于GL_ALPHA。Alpha 值
THREE.RGBFormat:Red, Green, Blue 三原色值
THREE.RGBAFormat:Red, Green, Blue 和 Alpha 值
THREE.LuminanceFormat:灰度值
THREE.LuminanceAlphaFormat:灰度值和 Alpha 值
THREE.RGBEFormat
③ panorama.magFilter
该属性定义当一个纹理单元(texel)覆盖多个像素点时纹理如何采样。缺省为 THREE.LinearFilter,表示获取4个最近的纹理单元执行双向线性插值计算(显示效果好)。另外的选项是 THREE.NearestFilter, 表示使用最近的texel(性能优)
④:panorama.minFilter
该属性定义当一个纹理单元(texel)不足以覆盖单个像素点时纹理如何采样。缺省为 THREE.LinearMipMapLinearFilter, 表示使用多级纹理贴图(mipmapping)以及一个三线性滤波器。
其他选项是:
THREE.NearestFilter:最近滤镜。在纹理基层上执行最邻近过滤。
THREE.NearestMipMapNearestFilter:选择最临近的mip层,并执行最临近的过滤。
THREE.NearestMipMapLinearFilter:在mip层之间执行线性插补,并执行最临近的过滤。
THREE.LinearFilter:在纹理基层上执行线性过滤。
THREE.LinearMipMapNearestFilter:选择最临近的mip层,并执行线性过滤。
THREE.LinearMipMapLinearFilter:在mip层之间执行线性插补,并执行线性过滤。
参考博客 Three.js Texture纹理属性详解
THREE.ShaderMaterial 参考博客Three.js高级材质THREE.ShaderMaterial
onload函数中
renderer=new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.autoClear=false;
renderer.gammaInput=true;
renderer.gammaOutput=true;//inear转gamma
renderer.setSize(window.innerWidth,window.innerHeight);
container.appendChild(renderer.domElement);
status=new Stats();//创建频率显示
container.appendChild(status.dom);//频率挂到左上角
let contorl=new OrbitControls(camera,renderer.domElement);//添加鼠标滚动缩放,旋转对象
window.addEventListener('resize',onResize,false);//浏览器大小改变监听
onResize函数中
function onResize() {
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
cameraCube.aspect = window.innerWidth / window.innerHeight;
cameraCube.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
run函数中
function run() {
requestAnimationFrame(run);
camera.lookAt(scene.position);
cameraCube.rotation.copy(camera.rotation);//赋值相机的位置
renderer.render(sceneCube,cameraCube);
renderer.render(scene,camera);
status.update();
}
onload函数中
let guiControls=new function(){
this.Cube=function () {
cubeMesh.material = cubeMaterial;
cubeMesh.visible = true;
SphereMaterial.envMap = textureCube;
SphereMaterial.needsUpdate = true;
};
this.Equirectangular=function () {
cubeMesh.material = panoramaMaterial;
cubeMesh.visible = true;
SphereMaterial.envMap=panorama;
SphereMaterial.needsUpdate = true;
}
};
let gui=new GUI();//创建gui
gui.add(guiControls,'Cube');
gui.add(guiControls,'Equirectangular');
Title