Appearance
材质对光的反应
可以将设置颜色和纹理材质应用到网格上面,并且需要有光源才能显示出来。一种材质可以用于任意数量的模型网格。
通过不同的方法设置材质的颜色和纹理,会出现不同的反应。
1、Diffuse - 漫反射 - 在光下面观察到的材质的基本颜色或者纹理
2、Specular - 高光 - 光线给材质的高亮点
3、Emissive - 自发光 - 材质的颜色和纹理,自身的亮光
4、Ambient - 环境 - 由环境背景照明点亮的材质的颜色或纹理
注意:
漫反射和高光的设置需要场景内有光源才可显示出效果。
设置环境颜色或者环境纹理时,需要首先给场景设置环境颜色。
javascript
scene.ambientColor = new BABYLON.Color3(1, 1, 1)使用 diffuseColor,specularColor,emissiveColor 和 ambientColor 中的一个或多个设置材质颜色。注意,ambientColor 只有才场景设置了环境颜色才有效果。
javascript
let myMaterial = new BABYLON.StandardMaterial('myMaterial', scene)
myMaterial.diffuseColor = new BABYLON.Color3(1, 0, 1)
myMaterial.specularColor = new BABYLON.Color3(0.5, 0.6, 0.87)
myMaterial.emissiveColor = new BABYLON.Color3(1, 1, 1)
myMaterial.ambientColor = new BABYLON.Color3(0.23, 0.98, 0.53)
mesh.material = myMaterial设置透明材质
javascript
myMaterial.alpha = 0.5设置纹理
可以在材质上面使用图片设置纹理。
javascript
// 首先创建一个材质
let myMaterial = new BABYLON.StandardMaterial('myMaterial', scene)
// 通过设置diffuseTexture,specularTexture,emissiveTexture和ambientTexture中的一个或多个属性设置相关纹理。同样,ambientTexture也只在设置场景环境色时有效。
let myMaterial = new BABYLON.StandardMaterial('myMaterial', scene)
myMaterial.diffuseTexture = new BABYLON.Texture('图片路径', scene)
myMaterial.specularTexture = new BABYLON.Texture('图片路径', scene)
myMaterial.emissiveTexture = new BABYLON.Texture('图片路径', scene)
myMaterial.ambientTexture = new BABYLON.Texture('图片路径', scene)
mesh.material = myMaterial动态纹理
书写文字的参数:
参数 1、text:字符串,要写入的单词。
参数 2、x:数字,距左侧边缘的距离。
参数 3、y:数字,与顶部或底部边缘的距离,取决于 invertY。
参数 4、font:字符串,字体定义形式为 font-style、font-size、font_name。
参数 5、invertY:布尔值,默认为 true,此时 y 是到顶部的距离,当为 false 时,y 是到底部的距离并且字母反转。
参数 6、update:布尔值,默认为 true,动态纹理会立即更新。
javascript
let dynamicTexture = new BABYLON.DynamicTexture(
'test',
{ width: 100, height: 100 },
scene
)
dynamicTexture.drawText(
'something',
50,
50,
'Times New Roman',
'green',
'red',
true,
true
)
sphereMaterial.diffuseTexture = dynamicTexture
sphere.material = sphereMaterial通过动态纹理获取画布对象
javascript
let dynamicTexture = new BABYLON.DynamicTexture(
'test',
{ width: 100, height: 100 },
scene
)
dynamicTexture.drawText(
'something',
50,
50,
'Times New Roman',
'green',
'white',
true,
true
)
sphereMaterial.diffuseTexture = dynamicTexture
// sphere.material=sphereMaterial
// 获取画布对象
let ctx = dynamicTexture.getContext()
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(100, 100)
ctx.lineTo(50, 100)
ctx.lineTo(50, 50)
ctx.fillStyle = 'red'
ctx.fill()
ctx.stroke()
// 更新纹理
dynamicTexture.update()通过动态纹理加载图像
javascript
let dynamicTexture = new BABYLON.DynamicTexture(
'test',
{ width: 100, height: 100 },
scene
)
sphereMaterial.diffuseTexture = dynamicTexture
//sphere.material=sphereMaterial
//获取画布对象
let ctx = dynamicTexture.getContext()
let img = new Image()
img.src = '../img/10.png'
//注意此处不能使用箭头函数
img.onload = function () {
// ctx.drawImage(this, img_start_x, img_start_y,img_w, img_h, can_x, can_y, destination_w, destination_h);
ctx.drawImage(this, 0, 0, 1000, 1000, 0, 0, 100, 100)
dynamicTexture.update()
}设置透明纹理
对于颜色材质,通过设置 alpha 属性的值来设置透明度。
如果图片是有透明度的纹理,比如使用了一张具有透明区域的 png 的图片。如果只是想让它透明的区域显示透明,这种情况下,需要将纹理的 hasAlpha 属性设置为 true。
javascript
myMaterial.diffuseTexture.hasAlpha = true背景剔除
在正常渲染时,通常不会绘制物体的背面,因为它在正常情况下会被证明遮挡。但是如果当使用的是透明纹理时,并且将图片透明,将能够透明场景的证明查看到背面,但是背面是默认剔除掉了,所以无法查看到。
如果需要查看到背部,需要将 backFaceCulling 属性设置为 false,即禁止掉背景剔除。
javascript
myMaterial.backFaceCulling = false显示线框
可以通过设置材质的 wireframe 属性来查看当前模型网格的线框。
javascript
materialSphere1.wireframe = trueRenderTargetTexture
RenderTargetTexture 在 Babylon.js 中的作用主要有以下几点:
1、离屏渲染:RenderTargetTexture 允许将场景或者场景的一部分渲染到一个纹理中,这个过程是在屏幕之外进行的,不会直接影响到主画布的内容。
2、创建特效:通过将渲染结果存储在纹理中,可以对这些纹理进行进一步的处理,比如应用后处理效果,或者将多个渲染结果合成在一起,从而创建复杂的视觉效果。
3、性能优化:在某些情况下,直接在屏幕上渲染复杂的场景可能会导致性能问题。使用 RenderTargetTexture 可以先将复杂场景渲染到纹理中,然后将这个纹理应用到一个简单的平面或者模型上,这样可以减少渲染的复杂度,提高性能。
4、动态纹理:RenderTargetTexture 可以动态更新,这意味着可以在每一帧或者根据需要更新纹理的内容,这在创建动态背景或者反射效果时非常有用。
5、后处理:可以将 RenderTargetTexture 作为后处理效果的输入,例如,可以先渲染一个场景到纹理中,然后使用这个纹理作为输入,应用模糊、色彩校正等效果。
6、反射和折射:在创建反射和折射效果时,RenderTargetTexture 非常有用。可以渲染场景到一个纹理中,然后将这个纹理用作另一个物体的反射或折射贴图。
7、多渲染目标:RenderTargetTexture 支持多个渲染目标(MRT),这意味着可以在一次渲染过程中将不同的数据渲染到多个纹理中,这在创建复杂的光照效果时非常有用。
8、纹理缓存:在某些情况下,渲染一个复杂的场景可能需要大量的计算资源。通过将渲染结果存储在 RenderTargetTexture 中,可以在需要时重复使用这个纹理,而不需要每次都重新渲染。
9、创建环境贴图:RenderTargetTexture 可以用来创建环境贴图(如立方体贴图),这些贴图可以用于环境光遮蔽或者反射效果。
把sphere渲染到plane中
javascript
const canvas = document.getElementById('renderCanvas')
const engine = new BABYLON.Engine(canvas, true)
const createScene = function() {
const scene = new BABYLON.Scene(engine)
const camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 10, BABYLON.Vector3.Zero(), scene)
camera.attachControl(canvas, true)
camera.setPosition(new BABYLON.Vector3(0, 0, -20))
new BABYLON.MeshBuilder.CreateLines(
'axisX', {
colors: [new BABYLON.Color4(1, 0, 0, 1), new BABYLON.Color4(1, 0, 0, 1)],
points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(2000, 0, 0)]
}, scene
)
new BABYLON.MeshBuilder.CreateLines(
'axisY', {
colors: [new BABYLON.Color4(0, 1, 0, 1), new BABYLON.Color4(0, 1, 0, 1)],
points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 2000, 0)]
}, scene
)
new BABYLON.MeshBuilder.CreateLines(
'axisZ', {
colors: [new BABYLON.Color4(0, 0, 1, 1), new BABYLON.Color4(0, 0, 1, 1)],
points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 0, 2000)]
}, scene
)
const light = new BABYLON.DirectionalLight('dir01', new BABYLON.Vector3(0, 0, 1), scene)
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: 3 }, scene)
const mat = new BABYLON.StandardMaterial('mat', scene)
mat.emissiveColor = new BABYLON.Color3(0.2, 0.3, 0.4)
sphere.material = mat
const rtCamera = new BABYLON.ArcRotateCamera('rtCamera', 0, 0, 10, BABYLON.Vector3.Zero(), scene)
rtCamera.setTarget(BABYLON.Vector3.Zero())
rtCamera.setPosition(new BABYLON.Vector3(0, 0, -20))
const renderTargetTexture = new BABYLON.RenderTargetTexture('renderTargetTexture', 512, scene)
renderTargetTexture.renderList.push(sphere)
renderTargetTexture.camera = rtCamera
scene.customRenderTargets.push(renderTargetTexture)
const m = new BABYLON.StandardMaterial('m', scene)
m.diffuseTexture = renderTargetTexture
m.backFaceCulling = false // 确保双面渲染
const plane = BABYLON.MeshBuilder.CreatePlane('plane', { size: 5 }, scene)
plane.material = m
plane.position = new BABYLON.Vector3(0, 4, 0)
return scene
}
const scene = createScene()
engine.runRenderLoop(function() {
scene.render()
})
window.addEventListener('resize', function() {
engine.resize()
})