three.js利用卷积法实现物体描边效果

  介绍

小编给大家分享一下三人。js利用卷积法实现物体描边效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!

<强>法线延展法

网上使用法线延展法实现物体描边效果的文章比较多,这里不再描述。

但是这种方法有个缺点:当两个面的法线夹角差别较大时,两个面的描边无法完美连接。如下图所示:

三。js利用卷积法实现物体描边效果

<强>卷积法

这里使用另一种方法卷积法实现物体描边效果,一般机器学习使用该方法比较多。先看效果图:

三。js利用卷积法实现物体描边效果 三。js利用卷积法实现物体描边效果  three.js利用卷积法实现物体描边效果

<强>使用三个。js具体的实现方法如下:

<李>

创建着色器材质,隐藏不需要描边的物体进行渲染,将需要描边的位置渲染成白色,其他位置渲染成黑色。

<李>

利用片源着色器计算卷积,白色是物体内部,黑色是物体外部,灰色是边框。

<李>

设置材质透明,不融合,将边框叠加到原图上,可以使用FXAA抗锯齿。

这三步就可以实现了,很简单吧。下面我们将详细介绍实现方法,不想看的可以直接去看完整实现代码:

完整代码:https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/helper/SelectHelper.js

<强>详细的实现过程:

1。使用三个。js正常绘制场景,得到下图,这里不介绍了。

 three.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);   }

效果图:

 three.js利用卷积法实现物体描边效果

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利用卷积法实现物体描边效果