使用vue学习three.js之渲染后期处理-使用BrightnessContrastShader定制效果调整页面的亮度与对比度
Posted 点燃火柴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用vue学习three.js之渲染后期处理-使用BrightnessContrastShader定制效果调整页面的亮度与对比度相关的知识,希望对你有一定的参考价值。
使用VignetteShader定制效果添加晕映效果
1.demo效果
如上图,为使用BrightnessContrastShader后期通道调整页面的亮度和对比度时的效果
2. 知识要点
2.1 BrightnessContrastShader介绍
通过使用BrightnessContrastShader的后期处理可以调整页面的亮度和对比度,它支持输入两个参数brightness和contrast分别表示要调整的亮度和对比度
2.2 BrightnessContrastShader的使用步骤
BrightnessContrastShader的使用步骤和其他ShaderPass定制效果处理通道几乎一样,具体如下
- 创建效果组合器
- 添加renderPass后期处理通道
- 添加BrightnessContrastShader后期处理通道
使用three.js提供的 BrightnessContrastShader 创建ShaderPass后期处理通道,添加到效果组合器中 - 添加CopyShader后期处理通道
使用three.js提供的 CopyShader 创建ShaderPass的通道,添加到效果组合器中,该通道是为了将所有场景最终的结果复制到屏幕上 - render函数中更新darknesssh和offset属性
3. 实现要点
3.1 相关文件引入
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'
import { BrightnessContrastShader } from 'three/examples/jsm/shaders/BrightnessContrastShader.js'
3.2 创建效果组合器
首先创建效果组合器,然后创建renderPass、effectCopy、BrightnessContrastShader 处理通道并添加到效果组合器
createComposer() {
//使用场景和相机创建RenderPass通道
const renderPass = new RenderPass(this.scene, this.camera)
//创建CopyShader后期处理ShaderPass通道
const effectCopy = new ShaderPass(CopyShader)
effectCopy.renderToScreen = true
//创建BrightnessContrastShader后期处理ShaderPass通道
this.brightness = new ShaderPass(BrightnessContrastShader)
this.brightness.enabled = false
//创建效果组合器
this.composer = new EffectComposer(this.renderer)
//将创建的通道添加到EffectComposer(效果组合器)对象中
this.composer.addPass(renderPass)
this.composer.addPass(effectCopy)
this.composer.addPass(this.brightness)
}
3.3 render中更新
在render函数中更新定制通道属性和效果组合器
//更新是否开启BrightnessContrastShader和它的属性
this.brightness.enabled = this.properties.isBrightnessContrastShader
this.brightness.uniforms.brightness.value = this.properties.brightness.value
this.brightness.uniforms.contrast.value = this.properties.contrast.value
this.renderer.render(this.scene, this.camera)
/********** 更新效果组合器一定要在渲染器更新后,否则通道无法产生效果************/
this.composer.render(delta) //效果组合器更新
4. demo代码
<template>
<div>
<div id="container" />
<div class="controls-box">
<section>
<el-row>
<el-checkbox v-model="properties.isBrightnessContrastShader">
是否开启BrightnessContrastShader
</el-checkbox>
</el-row>
<el-row>
<div v-for="(item,key) in properties" :key="key">
<div v-if="item&&item.name!=undefined">
<el-col :span="8">
<span class="vertice-span">{{ item.name }}</span>
</el-col>
<el-col :span="13">
<el-slider v-model="item.value" :min="item.min" :max="item.max" :step="item.step" :format-tooltip="formatTooltip" />
</el-col>
<el-col :span="3">
<span class="vertice-span">{{ item.value }}</span>
</el-col>
</div>
</div>
</el-row>
</section>
</div>
</div>
</template>
<script>
import * as THREE from 'three'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'
import { BrightnessContrastShader } from 'three/examples/jsm/shaders/BrightnessContrastShader.js'
export default {
data() {
return {
camera: null,
scene: null,
renderer: null,
orbitControls: null,
clock: null,
composer: null,
brightness: null,
properties: {
isBrightnessContrastShader: false,
brightness: {
name: 'brightness',
value: 0.01,
min: -1,
max: 1,
step: 0.001
},
contrast: {
name: 'contrast',
value: 0.01,
min: -1,
max: 1,
step: 0.001
}
}
}
},
mounted() {
this.init()
},
methods: {
formatTooltip(val) {
return val
},
// 初始化
init() {
this.createScene() // 创建场景
this.createModels() // 创建模型
this.createLight() // 创建光源
this.createCamera() // 创建相机
this.createRender() // 创建渲染器
this.createControls() // 创建控件对象
this.createComposer()
this.render() // 渲染
},
// 创建场景
createScene() {
this.scene = new THREE.Scene()
},
// 创建模型
createModels() {
this.createCubes()
this.loadModel()
},
createCubes() {
const publicPath = process.env.BASE_URL
const plane = new THREE.BoxGeometry(1600, 1600, 0.1, 40, 40)
const planeMesh = new THREE.Mesh(
plane,
new THREE.MeshPhongMaterial({
color: 0xffffff,
map: new THREE.TextureLoader().load(
`${publicPath}textures/general/plaster-diffuse.jpg`
),
normalMap: new THREE.TextureLoader().load(
`${publicPath}textures/general/plaster-normal.jpg`
),
normalScale: new THREE.Vector2(0.6, 0.6)
})
)
planeMesh.material.map.wrapS = THREE.RepeatWrapping
planeMesh.material.map.wrapT = THREE.RepeatWrapping
planeMesh.material.normalMap.wrapS = THREE.RepeatWrapping
planeMesh.material.normalMap.wrapT = THREE.RepeatWrapping
planeMesh.rotation.x = Math.PI / 2
planeMesh.material.map.repeat.set(80, 80)
planeMesh.receiveShadow = true
planeMesh.position.z = -150
planeMesh.position.x = -150
this.scene.add(planeMesh)
const cube1 = new THREE.Mesh(
new THREE.BoxGeometry(30, 10, 2),
new THREE.MeshPhongMaterial({ color: 0xff0000 })
)
cube1.position.x = -15
cube1.position.y = 5
cube1.position.z = 15
cube1.castShadow = true
this.scene.add(cube1)
const cube2 = cube1.clone()
cube2.material = cube1.material.clone()
cube2.material.color = new THREE.Color(0x00ff00)
cube2.position.z = 5
cube2.position.x = -20
this.scene.add(cube2)
const cube3 = cube1.clone()
cube3.material = cube1.material.clone()
cube3.material.color = new THREE.Color(0x0000ff)
cube3.position.z = -8
cube3.position.x = -25
this.scene.add(cube3)
},
loadModel() {
const publicPath = process.env.BASE_URL
const mtlLoader = new MTLLoader()
const objLoader = new OBJLoader()
const THIS = this
mtlLoader.load(
`${THIS.publicPath}models/sol/libertStatue.mtl`,
loadMaterials => {
loadMaterials.preload()
const objLoader = new OBJLoader()
objLoader.setMaterials(loadMaterials)
objLoader.load(`${publicPath}models/sol/libertStatue.obj`, object => {
object.children[0].material = new THREE.MeshPhongMaterial({
color: 0x545a5f
})
const geom = object.children[0].geometry
object.children.forEach(child => {
child.castShadow = true
child.geometry.computeVertexNormals()
})
object.scale.set(20, 20, 20)
object.position.set(10, 0, 0)
THIS.scene.add(object)
})
}
)
},
// 创建光源
createLight() {
const ambientLight = new THREE.AmbientLight(0x444444) // 创建环境光
this.scene.add(ambientLight) // 将环境光添加到场景
const spotLight = new THREE.SpotLight(0xffffff)
spotLight.castShadow = true
spotLight.position.set(0, 60, 50)
spotLight.intensity = 1
spotLight.shadow.mapSize.width = 2048
spotLight.shadow.mapSize.height = 2048
spotLight.shadow.camera.fov = 120
spotLight.shadow.camera.near = 1
spotLight.shadow.camera.far = 1000
this.scene.add(spotLight)
},
// 创建相机
createCamera() {
const element = document.getElementById('container')
const width = element.clientWidth // 窗口宽度
const height = element.clientHeight // 窗口高度
const k = width / height // 窗口宽高比
// PerspectiveCamera( fov, aspect, near, far )
this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)
this.camera.position.set(20, 30, 40) // 设置相机位置
this.camera.lookAt(new THREE.Vector3(-15, -10, -25)) // 设置相机方向
},
// 创建渲染器
createRender() {
const element = document.getElementById('container')
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
this.renderer.shadowMap.enabled = true // 显示阴影
this.renderer.setClearColor(0x000000, 1) // 设置背景颜色
element.appendChild(this.renderer.domElement)
},
createComposer() {
//使用场景和相机创建RenderPass通道
const renderPass = new RenderPass(this.scene, this.camera)
//创建CopyShader后期处理ShaderPass通道
const effectCopy = new ShaderPass(CopyShader)
effectCopy.renderToScreen = true
//创建BrightnessContrastShader后期处理ShaderPass通道
this.brightness = new ShaderPass(BrightnessContrastShader)
this.brightness.enabled = false
//创建效果组合器
this.composer = new EffectComposer(this.renderer)
//将创建的通道添加到EffectComposer(效果组合器)对象中
this.composer.addPass(renderPass)
this.composer.addPass(effectCopy)
this.composer.addPass(this.brightness)
},
render() {
const delta = this.clock.getDelta() // 获取自上次调用的时间差
this.orbitControls.update(delta) // 相机控制更新
//更新是否开启BrightnessContrastShader和它的属性
this.brightness.enabled = this.properties.isBrightnessContrastShader
this.brightness.uniforms.brightness.value = this.properties.brightness.value
this.brightness.uniforms.contrast.value = this.properties.contrast.value
this.renderer.render(this.scene, this.camera)
/********** 更新效果组合器一定要在渲染器更新后,否则通道无法产生效果************/
this.composer.render(delta) //效果组合器更新
requestAnimationFrame(this.render)
},
// 创建控件对象
createControls() {
this.clock = new THREE.Clock() // 创建THREE.Clock对象,用于计算上次调用经过的时间
this.orbitControls = new OrbitControls(
this.camera,
this.renderer.domElement
)
}
}
}
</script>
<style>
#container {
position: absolute;
width: 100%;
height: 100%;
}
.controls-box {
position: absolute;
right: 5px;
top: 5px使用vue学习three.js之渲染后期处理-使用HueSaturationShader定制效果调整颜色的色调和饱和度
使用vue学习three.js之渲染后期处理-使用ColorifyShader定制效果在屏幕上蒙上一层颜色
使用vue学习three.js之渲染后期处理-使用SepiaShader定制效果创建出类似乌贼墨的效果
使用vue学习three.js之渲染后期处理-使用UnrealBloomPass通道在场景中添加泛光效果,三维物体表面发光效果
使用vue学习three.js之渲染后期处理-简单的后期处理通道FilmPass(类似电视效果)DotScreenPass(将场景输出成点集)GlitchPass(电磁风暴效果)
使用vue学习three.js之渲染后期处理-使用VignetteShader定制效果添加晕映效果,在图片周围显示黑色边框