本文主要是介绍threejs边缘暗角shader,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
边缘暗角以及锯齿处理
- 效果
- 引入库
- shader
- 窗口监测里添加
- 添加效果合成器
- 处理模型边缘锯齿
- 渲染
- 后续
效果
引入库
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader'
shader
var DarkMaskShader = {uniforms: {'tDiffuse': {value: null},'maskColor': {value: new THREE.Color(0x000000)},'maskAlpha': {value: 1.0},'markRadius': {value: 0.15},'smoothSize': {value: 0.5}},vertexShader: ['varying vec2 vUv;','void main() {',' vUv = uv;',' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );','}'].join('\n'),fragmentShader: ['uniform float maskAlpha;','uniform vec3 maskColor;','uniform float markRadius;','uniform float smoothSize;','uniform sampler2D tDiffuse;','varying vec2 vUv;','float sdfCircle(vec2 coord, vec2 center, float radius)','{',' vec2 offset = coord - center;',' return sqrt((offset.x * offset.x) + (offset.y * offset.y)) - radius;','}','void main() {',' vec4 texel = texture2D( tDiffuse, vUv );',' float sdfValue = sdfCircle(vUv, vec2(0.5, 0.5), markRadius);',' if (sdfValue < 0.0){',' gl_FragColor = texel;',' }else{',' float a = smoothstep(0.0, smoothSize, sdfValue);',' gl_FragColor = mix(texel, vec4(maskColor, maskAlpha), a);',' }','}'].join('\n')
}
窗口监测里添加
function onWindowResize() {camera.aspect = document.getElementById('threecanvas').offsetWidth / document.getElementById('threecanvas').offsetHeightcamera.updateProjectionMatrix()/*********************************************************************/// 暗角范围composer.setSize(document.getElementById('threecanvas').offsetWidth, document.getElementById('threecanvas').offsetHeight) // 暗角renderer.setSize(document.getElementById('threecanvas').offsetWidth, document.getElementById('threecanvas').offsetHeight)
}
添加效果合成器
function initEffectComposer() {// 处理模型闪烁问题【优化展示网格闪烁】const parameters = { format: THREE.RGBFormat }const size = renderer.getDrawingBufferSize(new THREE.Vector2())const renderTarget = new THREE.WebGLMultisampleRenderTarget(size.width, size.height, parameters)/******************************************边缘暗角****************************************/renderScene = new RenderPass(scene, camera)renderScene.clear = trueconst effectDarkMask = new ShaderPass(DarkMaskShader)composeraj = new EffectComposer(renderer, renderTarget)composeraj.addPass(renderScene)composeraj.addPass(effectDarkMask)// 开启圆形暗角,需要处理模型边缘失真
}
处理模型边缘锯齿
添加特效合成器后,会出现模型边缘锯齿
推荐使用 FXAA 处理
具体请到:
// 效果合成器,shader渲染使用
function initEffectComposer() {// 处理模型闪烁问题【优化展示网格闪烁】const parameters = { format: THREE.RGBFormat }const size = renderer.getDrawingBufferSize(new THREE.Vector2())const renderTarget = new THREE.WebGLMultisampleRenderTarget(size.width, size.height, parameters)/******************************************边缘暗角****************************************/renderScene = new RenderPass(scene, camera)renderScene.clear = trueconst effectDarkMask = new ShaderPass(DarkMaskShader)composeraj = new EffectComposer(renderer, renderTarget)composeraj.addPass(renderScene)composeraj.addPass(effectDarkMask)// 开启圆形暗角,需要处理模型边缘失真/*********************************************特效锯齿处理****************************************/// 增加fxaashader处理模型边缘锯齿,开启EffectComposer后才能生效【开启特效合成之后的展示优化】var FXAAShaderPass = new ShaderPass(FXAAShader)const pixelRatio = renderer.getPixelRatio()const width = document.getElementById('threecanvas').offsetWidthconst height = document.getElementById('threecanvas').offsetHeightFXAAShaderPass.uniforms['resolution'].value.set(1 / (width * pixelRatio), 1 / (height * pixelRatio))FXAAShaderPass.renderToScreen = truecomposeraj.addPass(FXAAShaderPass)
}
渲染
渲染部分,如果添加了特效合成器,则要把传统的渲染方式替换为特效的通道
// 渲染
function render() {update()requestAnimationFrame(render)// 执行一个动画.并在动画执行后重新渲染// 传统渲染器,如果使用shader着色器,则注掉这个,增加效果合成器,增加通道渲染 // renderer.render(scene, camera)composeraj.render()
}
后续
这一部分特效也是参考了大部分其他知乎、博客、简书等等…
话说,找一个特效真难,搜到的好的特效后边都是两个字,买断 &T~T&,都拿去作商业用途了,如果一个小白从头开始,跟着three官网做一些基础的三维物体或基础场景还是可以的,那些进阶的东西,特效、动效什么的,真的是难找的要死,现在学个东西,自学还真是难啊,高级一点的接触都接触不到,像我这样的,自己扣一扣底层代码,然后往上一步一个坑真的难的一批,各种搜索,找一找成型的源码,自己对照着底层,硬理解,难搞。 想速成的话…多花钱,想按部就班的搞一搞,吃的透就要从简到繁,从底层到显示…一步一坑,从three进去,到webgl,再看OpenGL,对照底层封装three上的缺陷,然后完善,形成一套自己的基础引擎。
这篇关于threejs边缘暗角shader的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!