Three.js 材质对象Material对应的着色器Shader代码

  • 点材质PointsMaterial:顶点着色器文件points_vert.glsl、片元着色器文件points_frag.glsl
  • 基础网格材质MeshBasicMaterial:顶点着色器文件meshbasic_vert.glsl、片元着色器文件meshbasic_frag.glsl
  • 高光网格材质MeshPhongMaterial:顶点着色器文件meshphong_vert.glsl、片元着色器文件meshphong_frag.glsl

材质对象封装

通过材质对象的.type属性,可以判断材质对象是哪种材质对象,一个材质对象具有一个惟一的type类型。

JavaScript语法

把字符串作为属性名访问对象的属性。

  var shaderIDs = {
  MeshBasicMaterial: 'basic',
  MeshLambertMaterial: 'lambert',
  MeshPhongMaterial: 'phong',
  };
  // 查看shaderIDs对象MeshBasicMaterial属性的值
  console.log(shaderIDs.MeshBasicMaterial);
  console.log('查看属性值',shaderIDs[ 'MeshBasicMaterial' ]);

 

shaders目录简介

着色器代码文件目录是three.js-master\src\renderers\shaders,shaders目录下有两个着色器代码的文件ShaderChunk和ShaderLib。

ShaderChunk目录下的着色器代码文件.glsl都是具有特定功能的模块,ShaderLib目录下的着色器文件会通过#include <ShaderChunk中着色器文件名>调用ShaderChunk目录下特定功能的着色器代码块构建出来具有具有特定功能的顶点着色器文件和片元着色器文件。

  • 点材质PointsMaterial:顶点着色器文件points_vert.glsl、片元着色器文件points_frag.glsl
  • 基础网格材质MeshBasicMaterial:顶点着色器文件meshbasic_vert.glsl、片元着色器文件meshbasic_frag.glsl
  • 高光网格材质MeshPhongMaterial:顶点着色器文件meshphong_vert.glsl、片元着色器文件meshphong_frag.glsl
  1. ShaderChunk.js:用来获得ShaderChunk和ShaderLib文件中的着色器代码
  2. ShaderLib.js:设置好点、线、网格材质对应的uniforms变量值、顶点着色器代码、片元着色器代码
  3. UniformsLib.js、UniformsUtils.js:着色器中uniform变量对应的值

WebGLRenderer.js

通过WebGLPrograms对象的方法.getParameters()返回一个parameters对象,返回的parameters对象的shaderID属性保留了材质对象类型type的信息,通过材质对象信息可以在ShaderLib对象中获得材质对象对应的着色器代码。

import {ShaderLib} from './shaders/ShaderLib.js';
import {WebGLPrograms} from './webgl/WebGLPrograms.js';
programCache = new WebGLPrograms(_this, extensions, capabilities);

function initMaterial(material, fog, object) {

  // 返回一个parameters对象,具有shaderID属性,通过shaderID的属性值可以获得材质对象对应的着色器代码。
  var parameters = programCache.getParameters(material, lights.state, shadowsArray, ...object);

  // 通过shaderID键对应的值,作为ShaderLib对象的键名获得相应的值,uniforms对象、定点着色器代码、片元着色器代码
  var shader = ShaderLib[parameters.shaderID];

  materialProperties.shader = {
  name: material.type,
  uniforms: UniformsUtils.clone(shader.uniforms),
  vertexShader: shader.vertexShader,
  fragmentShader: shader.fragmentShader
  };
  // 处理着色器代码、编译着色器代码、返回程序对象program
  program = programCache.acquireProgram(material, materialProperties.shader, parameters, code);
}

 WebGLPrograms.js

构造函数WebGLPrograms封装了.getParameters().getProgramCode().acquireProgram()等方法和.programs属性。

function WebGLPrograms( renderer, extensions, capabilities ) {
  var shaderIDs = {
  MeshDepthMaterial: 'depth',
  MeshDistanceMaterial: 'distanceRGBA',
  MeshNormalMaterial: 'normal',
  MeshBasicMaterial: 'basic',
  MeshLambertMaterial: 'lambert',
  MeshPhongMaterial: 'phong',
  MeshToonMaterial: 'phong',
  MeshStandardMaterial: 'physical',
  MeshPhysicalMaterial: 'physical',
  LineBasicMaterial: 'basic',
  LineDashedMaterial: 'dashed',
  PointsMaterial: 'points',
  ShadowMaterial: 'shadow'
};
this.getParameters = function (material, lights,...){
  // 通过材质对象.type值,从shaderIDs提取相应的属性值
  var shaderID = shaderIDs[ material.type ];

  var parameters = {
// 该属性用于判断材质对象
  shaderID: shaderID,
  precision: precision,
  vertexColors: material.vertexColors,
  numSpotLights: lights.spot.length,
  numRectAreaLights: lights.rectArea.length,
  numHemiLights: lights.hemi.length,
  };

return parameters;
}
}

 

### 如何在 Three.js 中更换几何体的材质Three.js 中,更改几何体的材质可以通过重新设置其 `material` 属性实现。以下是具体的操作方式以及示例代码。 #### 创建并应用新材质 当需要替换现有几何体上的材质时,可以先创建一个新的材质对象(如 `MeshStandardMaterial` 或其他类型的材质),然后将其赋值给几何体的 `.material` 属性[^1]。需要注意的是,在某些情况下可能还需要更新渲染器以反映变化。 下面是一个简单的例子,演示如何将一个立方体从默认材质切换成带有颜色的新材质: ```javascript // 初始化场景、相机和渲染器... const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建一个立方体网格,并赋予初始材质 const geometry = new THREE.BoxGeometry(); // 定义立方体形状 const initialMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 初始绿色材料 const cube = new THREE.Mesh(geometry, initialMaterial); scene.add(cube); camera.position.z = 5; function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); // 动态改变材质为红色的标准材质 setTimeout(() => { const newMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 }); cube.material = new Material; // 这里应改为 cube.material = newMaterial; }, 2000); ``` 注意上述代码中的错误部分已修正:最后一行原本试图分配未定义变量 `new Material` 而不是实际创建好的 `newMaterial` 实例[^2]。 #### 使用 Line 材质 如果目标是线框结构而非实体表面,则可考虑采用 `LineBasicMaterial` 或者虚线形式的 `LineDashedMaterial` 类型作为替代方案[^4]。此类操作同样遵循前述逻辑流程——实例化相应类别的材质之后再绑定至对应组件之上即可完成转换过程。 #### 高级定制与性能优化建议 对于更为复杂的模型或者追求更高效率的应用场合而言,利用缓冲区几何(Buffer Geometry)能够显著提升数据处理速度;与此同时配合着色器(shader),开发者还可以进一步深入控制视觉效果呈现细节层次达到极致个性化需求满足程度[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

山楂树の

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

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

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

打赏作者

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

抵扣说明:

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

余额充值