Three-js 学习笔记(3)——材质

10 篇文章 0 订阅
6 篇文章 0 订阅

基于上一篇,创建一个正二十面体模型添加到场景中做材质和光照效果试验。

半透明效果

更改场景中的球体材质对象构造函数THREE.MeshLambertMaterial()的参数,添加opacitytransparent属性,opacity的值是0~1之间,transparent表示是否开启透明度效果, 默认是false表示透明度设置不起作用,值设置为true,网格模型就会呈现透明的效果,使用下面的代码替换原来的球体网格模型的材质, 刷新浏览器,通过鼠标旋转操作场景,可以看到半透明的球体和立方体颜色叠加融合的效果。材质对象的一些属性可以在构造函数参数中设置,也可以访问材质对象的属性设置。

        let material = new THREE.MeshNormalMaterial(
          {
            // 颜色
            color:0xff0000,
          }
        );
        material.opacity = 0.5;
        material.transparent = true;
        material.wireframe = false;

添加高光效果

处在光照条件下的物体表面会发生光的反射现象,不同的表面粗糙度不同,宏观上来看对光的综合反射效果,可以使用两个反射模型来概括,一个是漫反射,一个是镜面反射, 使用渲染软件或绘画的时候都会提到一个高光的概念,其实说的就是物理光学中镜面反射产生的局部高亮效果。实际生活中的物体都是镜面反射和漫反射同时存在,只是哪个占得比例大而已, 比如树皮的表面更多以漫反射为主基本没有体现出镜面反射,比如一辆轿车的外表面在阳光下你会看到局部高亮的效果,这很简单汽车表面经过抛光等表面处理粗糙度非常低, 镜面反射效果明显,对于three.js而言漫反射、镜面反射分别对应两个构造函数MeshLambertMaterial()MeshPhongMaterial()

        var sphereMaterial = new THREE.MeshPhongMaterial({
            color:0x00aaff,
            specular:0x4488ee,
            shininess:12
        });

        material = sphereMaterial;

常用的材质效果

材质类型功能
MeshBasicMaterial基础网格材质,不受光照影响的材质
MeshLambertMaterialLambert网格材质,与光照有反应,漫反射
MeshPhongMaterial高光Phong材质,与光照有反应
MeshStandardMaterialPBR物理材质,相比较高光Phong材质可以更好的模拟金属、玻璃等效果

光照效果设置

        // 点光源
        var point = new THREE.PointLight(0xffffff);
        // 点光源位置
        point.position.set(400, 200, 300); 
        // 点光源添加到场景中
        this.scene.add(point); 
        // 环境光
        var ambient = new THREE.AmbientLight(0x444444);
        this.scene.add(ambient);

常见光源类型

光源简介
AmbientLight环境光
PointLight点光源
DirectionalLight平行光,比如太阳光
SpotLight聚光源

完整代码:

<template>
  <div class="geometry_02">
    <button @click="upPage">返回</button>
    <div id="container"></div>
  </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
export default {
  data() {
    return {
      // 相机
      camera: null,
      // 场景
      scene: null,
      // 渲染器
      renderer: null,
      // 材质对象
      mesh: null,
      // 控件
      controls: null,
    };
  },
  mounted() {
    this.init();
    this.animate();
  },
  methods: {
    //初始化
    init: function () {
        // 创建场景对象Scene
        this.scene = new THREE.Scene();
        // 网格模型添加到场景中
        // 正二十面体
        var geometry = new THREE.IcosahedronGeometry(50); 

        let material = null;
        // // 1 点材质
        // material = new THREE.PointsMaterial({
        //   color: 0x0000ff, //颜色
        //   size: 3, //点渲染尺寸
        // });
        // //点模型对象  参数:几何体  点材质
        // var pt = new THREE.Points(geometry, material);
        // this.scene.add(pt); //网格模型添加到场景中

        // // 2 直线基础材质对象
        // material = new THREE.LineBasicMaterial({
        //   color: 0x0000ff
        // });
        // var line = new THREE.Line(geometry, material); //线模型对象
        // this.scene.add(line); //点模型添加到场景中

        // // 3 虚线材质对象:产生虚线效果
        // material = new THREE.LineDashedMaterial({
        //   color: 0x0000ff,
        //   dashSize: 10,//显示线段的大小。默认为3。
        //   gapSize: 5,//间隙的大小。默认为1
        // });
        // var line = new THREE.Line(geometry, material);
        // //  computeLineDistances方法  计算LineDashedMaterial所需的距离数组
        // line.computeLineDistances();
        // this.scene.add(line);

        // // 4 网格材质-将法线向量映射到 RGB 颜色的材质。
        // material = new THREE.MeshNormalMaterial();
        // material.color = 0xff0000;
        // material.opacity = 0.5;
        // material.transparent = true;
        // material.wireframe = false;

        // // 5 网格材质-高光Phong材质,与光照有反应
        // material = new THREE.MeshPhongMaterial({
        //     color:0x00aaff,
        //     specular:0x4488ee,
        //     shininess:12
        // });

        // // 6 网格材质-Lambert网格材质,与光照有反应,漫反射
        // material = new THREE.MeshLambertMaterial({
        //   color: 0x00aaff,
        // });

        // // 7 网格材质-基础网格材质,不受光照影响的材质
        // material = new THREE.MeshBasicMaterial({
        //   color: 0x0000ff,
        // })

        // // 8 按深度绘制几何图形的材料。深度基于相机近平面和远平面。白色最近,黑色最远
        // material = new THREE.MeshDepthMaterial({})

        // // 9 在内部用于使用PointLight实现阴影映射
        // const texture = new THREE.CanvasTexture( this.generateTexture() );
        // texture.magFilter = THREE.NearestFilter;
        // texture.wrapT = THREE.RepeatWrapping;
        // texture.wrapS = THREE.RepeatWrapping;
        // texture.repeat.set( 1, 4.5 );
        // material = new THREE.MeshPhongMaterial( {
				// 		side: THREE.DoubleSide,
				// 		alphaMap: texture,
				// 		alphaTest: 0.5
				// 	} );
        // let sphere = new THREE.Mesh( geometry, material );
        // sphere.castShadow = true;
        // sphere.receiveShadow = true;
        
        // const distanceMaterial = new THREE.MeshDistanceMaterial( {
        //   alphaMap: material.alphaMap,
        //   alphaTest: material.alphaTest
        // } );
        // sphere.customDistanceMaterial = distanceMaterial;

        // // 10 不响应光照,因为 matcap 图像文件对烘焙光照进行编码。它会将阴影投射到接收阴影的对象上(并且阴影剪切有效),但它不会自身阴影或接收阴影。
        // material = new THREE.MeshMatcapMaterial({})

        // // 11 MeshStandardMaterial	PBR物理材质,相比较高光Phong材质可以更好的模拟金属、玻璃等效果,使用 Metallic-Roughness 工作流程
        // material = new THREE.MeshStandardMaterial(
        //   {
        //     color:0xCAA83F
        //   }
        // );

        // // 12 MeshStandardMaterial 的扩展,提供更高级的基于物理的渲染属性。opacity的一个限制是高度透明的材料反射率较低。基于物理的.transmission 为玻璃等薄而透明的表面提供了更逼真的选择。非金属材料的反射率更灵活。
        // const numberOfSphersPerSide = 2;
        // const stepSize = 1.0 / numberOfSphersPerSide;
        // for ( let alpha = 0; alpha <= 1.0; alpha += stepSize ) {
        //   for ( let beta = 0; beta <= 1.0; beta += stepSize ) {
        //     for ( let gamma = 0; gamma <= 1.0; gamma += stepSize ) {
        //       const diffuseColor = new THREE.Color().setHSL( alpha, 0.5, 0.25 );
        //       material = new THREE.MeshPhysicalMaterial( {
        //         color: diffuseColor,
        //         metalness: 0,
        //         roughness: 0.5,
        //         clearcoat: 1.0 - alpha,
        //         clearcoatRoughness: 1.0 - beta,
        //         reflectivity: 1.0 - gamma
        //       } );
        //       const mesh = new THREE.Mesh( geometry, material );
        //       mesh.position.x = alpha * 400 - 200;
        //       mesh.position.y = beta * 400 - 200;
        //       mesh.position.z = gamma * 400 - 200;
        //       this.scene.add( mesh );
        //     }
        //   }
        // }

        // 13 MeshToonMaterial 卡通着色的材料
        // material = new THREE.MeshToonMaterial(
        //   {
        //     color:0x05588F
        //   }
        // );

        // // 14 阴影材质 这种材质可以接收阴影,但除此之外是完全透明的
        // material = new THREE.ShadowMaterial();
        // material.opacity = 0.5;

        // const plane = new THREE.Mesh( geometry, material );
        // plane.position.y = -200;
        // plane.receiveShadow = true;
        // this.scene.add( plane );

        const map = new THREE.TextureLoader().load('../../../assets/img/ag-4.png');
        material = new THREE.SpriteMaterial( { map: map, color: 0xffffff } );
        const sprite = new THREE.Sprite( material );
        sprite.scale.set(200, 200, 1)
        this.scene.add( sprite );

        this.mesh = new THREE.Mesh(geometry, material);
        this.mesh.position.set(0,0,0);
        this.scene.add(this.mesh);

        // 点光源
        var point = new THREE.PointLight(0xffffff);
        // 点光源位置
        point.position.set(200, 300, 300); 
        //
        // point.add( sphere );
        // 点光源添加到场景中
        this.scene.add(point); 
        // 环境光
        var ambient = new THREE.AmbientLight(0x444444);
        this.scene.add(ambient);

        // 相机设置
        let container = document.getElementById("container");
        // 窗口宽度
        let width = window.innerWidth; 
        // 窗口高度
        let height = window.innerHeight; 
        // 窗口宽高比
        let k = width / height; 
        // 三维场景显示范围控制系数,系数越大,显示的范围越大
        let s = 100; 
        this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 0.1, 1000);
        // 透视相机(视场角度,长宽比,近面,远面)
        // this.camera = new THREE.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 10);
        this.camera.position.set(200, 300, 200); 
        this.camera.lookAt(this.scene.position); 

        // 创建渲染器对象
        this.renderer = new THREE.WebGLRenderer({ antialias: true });
        this.renderer.setSize(container.clientWidth, container.clientHeight);
        this.renderer.setClearColor(0x000, 1);
        container.appendChild(this.renderer.domElement);
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    },

    // 动画
    animate: function () {
      requestAnimationFrame(this.animate);
      this.renderer.render(this.scene, this.camera);
    },
    
    //
    generateTexture: function() {
      const canvas = document.createElement( 'canvas' );
      canvas.width = 2;
      canvas.height = 2;
      const context = canvas.getContext( '2d' );
      context.fillStyle = 'white';
      context.fillRect( 0, 1, 2, 1 );
      return canvas;
    },

    upPage() {
      this.$router.go(-1);
    },

  },
};
</script>

<style>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

外码斯迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值