小编给大家分享一下三人。js利用卷积法实现物体描边效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
<强>法线延展法强>
网上使用法线延展法实现物体描边效果的文章比较多,这里不再描述。
但是这种方法有个缺点:当两个面的法线夹角差别较大时,两个面的描边无法完美连接。如下图所示:
<强>卷积法强>
这里使用另一种方法卷积法实现物体描边效果,一般机器学习使用该方法比较多。先看效果图:
<强>使用三个。js具体的实现方法如下:强>
- <李>
创建着色器材质,隐藏不需要描边的物体进行渲染,将需要描边的位置渲染成白色,其他位置渲染成黑色。
李> <李>利用片源着色器计算卷积,白色是物体内部,黑色是物体外部,灰色是边框。
李> <李>设置材质透明,不融合,将边框叠加到原图上,可以使用FXAA抗锯齿。
李>这三步就可以实现了,很简单吧。下面我们将详细介绍实现方法,不想看的可以直接去看完整实现代码:
完整代码:https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/helper/SelectHelper.js
<强>详细的实现过程:强>
1。使用三个。js正常绘制场景,得到下图,这里不介绍了。
2。创建着色器材质,隐藏所有不需要描边的物体。将需要描边的物体绘制成白色,其他地方绘制成黑色。
隐藏不需要描边的物体后,将整个场景材质替换。
renderScene.overrideMaterial =, this.maskMaterial;
着色器材质:
const maskMaterial =, new THREE.ShaderMaterial ({ ,vertexShader: MaskVertex, ,fragmentShader: MaskFragment, ,depthTest:假的 });
MaskVertex:
void 主要(),{=,,gl_Position  projectionMatrix *, modelViewMatrix *, vec4(,位置,1.0,); }
MaskFragment:
void 主要(),{=,,gl_FragColor  vec4 (1.0, 1.0, 1.0,, 1.0); }
效果图:
3。创建着色器材质进行卷积计算,每四个像素颜色求平均值得到一个像素。描边物体内部是白色,外部是黑色,物体边缘处会得到灰色。灰色就是我们所需的边框。
const edgeMaterial =, new THREE.ShaderMaterial ({ ,vertexShader: EdgeVertex, ,fragmentShader: EdgeFragment, ,制服:{ ,,maskTexture: { ,,,的值:this.maskBuffer.texture ,,}, ,,texSize: { ,,,的值:new THREE.Vector2(宽度,高度) ,,}, ,,颜色:{ ,,,的值:selectedColor ,,}, ,,厚度:{ ,,,类型:& # 39;f # 39; ,,,的值:4 ,,}, 透明的才能:真实 }, ,depthTest:假的 });
其中texSize是计算卷积的帆布宽度和高度,为了让边框更平滑,可以设置为原来画布的两倍.color是边框颜色,厚度是边框粗细。
注意,要将材质透明设置为真的。
EdgeVertex:
varying vec2 vUv; void main (), {=,vUv 紫外线;=,,gl_Position  projectionMatrix *, modelViewMatrix *, vec4(,位置,1.0,); }
EdgeFragment:
uniform sampler2D maskTexture; uniform vec2  texSize; uniform vec3 颜色; uniform float 厚度; varying vec2  vUv; void main (), { ,vec2 invSize =, thickness /, texSize; ,vec4 uvOffset =, vec4 (1.0, 0.0, 0.0, 1.0), *, vec4 (invSize invSize也); ,vec4 c1 =, texture2D (maskTexture的不同之处是,vUv +, uvOffset.xy); ,vec4 c2 =, texture2D (maskTexture的不同之处是,vUv 作用;uvOffset.xy); ,vec4 c3 =, texture2D (maskTexture的不同之处是,vUv +, uvOffset.yw); ,vec4 c4 =, texture2D (maskTexture的不同之处是,vUv 作用;uvOffset.yw); , ,float diff1 =, (c1.r 作用;c2.r) * 0.5; ,float diff2 =, (c3.r 作用;c4.r) * 0.5; , ,float d =,长度(vec2 (diff1, diff2));=,,gl_FragColor  d 祝辞,0.0,?,vec4(颜色,,1.0),:,vec4 (0.0, 0.0, 0.0,, 0.0); }three.js利用卷积法实现物体描边效果