最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

three.js利用卷積法如何實現(xiàn)物體描邊效果

 更新時間:2019年11月27日 10:19:07   作者:tengge  
這篇文章主要給大家介紹了關(guān)于three.js利用卷積法如何實現(xiàn)物體描邊效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用three.js具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

法線延展法

網(wǎng)上使用法線延展法實現(xiàn)物體描邊效果的文章比較多,這里不再描述。

但是這種方法有個缺點:當兩個面的法線夾角差別較大時,兩個面的描邊無法完美連接。如下圖所示:

卷積法

這里使用另一種方法卷積法實現(xiàn)物體描邊效果,一般機器學習使用該方法比較多。先看效果圖:

使用three.js具體的實現(xiàn)方法如下:

  1. 創(chuàng)建著色器材質(zhì),隱藏不需要描邊的物體進行渲染,將需要描邊的位置渲染成白色,其他位置渲染成黑色。
  2. 利用片源著色器計算卷積,白色是物體內(nèi)部,黑色是物體外部,灰色是邊框。
  3. 設(shè)置材質(zhì)透明、不融合,將邊框疊加到原圖上,可以使用FXAA抗鋸齒。

這三步就可以實現(xiàn)了,很簡單吧。下面我們將詳細介紹實現(xiàn)方法,不想看的可以直接去看完整實現(xiàn)代碼:

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

詳細的實現(xiàn)過程:

1. 使用three.js正常繪制場景,得到下圖,這里不介紹了。

2. 創(chuàng)建著色器材質(zhì),隱藏所有不需要描邊的物體。將需要描邊的物體繪制成白色,其他地方繪制成黑色。

隱藏不需要描邊的物體后,將整個場景材質(zhì)替換。

renderScene.overrideMaterial = this.maskMaterial;

著色器材質(zhì):

const maskMaterial = new THREE.ShaderMaterial({
 vertexShader: MaskVertex,
 fragmentShader: MaskFragment,
 depthTest: false
});

MaskVertex:

void main() {
 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

MaskFragment:

void main() {
 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

效果圖:

3. 創(chuàng)建著色器材質(zhì)進行卷積計算,每四個像素顏色求平均值得到一個像素。描邊物體內(nèi)部是白色,外部是黑色,物體邊緣處會得到灰色?;疑褪俏覀兯璧倪吙?。

const edgeMaterial = new THREE.ShaderMaterial({
 vertexShader: EdgeVertex,
 fragmentShader: EdgeFragment,
 uniforms: {
  maskTexture: {
   value: this.maskBuffer.texture
  },
  texSize: {
   value: new THREE.Vector2(width, height)
  },
  color: {
   value: selectedColor
  },
  thickness: {
   type: 'f',
   value: 4
  },
  transparent: true
 },
 depthTest: false
});

其中texSize是計算卷積的canvas寬度和高度,為了讓邊框更平滑,可以設(shè)置為原來canvas的兩倍。color是邊框顏色,thickness是邊框粗細。

注意,要將材質(zhì)transparent設(shè)置為true。

EdgeVertex:

varying vec2 vUv;

void main() {
 vUv = uv;
 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

EdgeFragment:

uniform sampler2D maskTexture;
uniform vec2 texSize;
uniform vec3 color;
uniform float thickness;

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 = length(vec2(diff1, diff2));
 gl_FragColor = d > 0.0 ? vec4(color, 1.0) : vec4(0.0, 0.0, 0.0, 0.0);
}

效果圖:

4. 創(chuàng)建著色器材質(zhì),將邊框疊加到原來的圖片上。由于FXAA比較復(fù)雜,這里使用簡單的疊加方法。

著色器材質(zhì):

const copyMaterial = new THREE.ShaderMaterial({
 vertexShader: CopyVertexShader,
 fragmentShader: CopyFragmentShader,
 uniforms: {
  tDiffuse: {
   value: edgeBuffer.texture
  },
  resolution: {
   value: new THREE.Vector2(1 / width, 1 / height)
  }
 },
 transparent: true,
 depthTest: false
});

注意,transparent要設(shè)置為true,否則會把原來的圖片覆蓋掉。

CopyVertexShader:

varying vec2 vUv;

void main() {
 vUv = uv;
 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

CopyFragmentShader:

uniform float opacity;

uniform sampler2D tDiffuse;

varying vec2 vUv;

void main() {
 vec4 texel = texture2D( tDiffuse, vUv );
 gl_FragColor = opacity * texel;
}

得到最終效果圖:

參考資料:

1. 描邊實現(xiàn)完整代碼:https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/helper/SelectHelper.js

2. 基于three.js的開源三維場景編輯器:https://github.com/tengge1/ShadowEditor

3. three.js后期處理描邊:https://threejs.org/examples/

4. 卷積工作原理:https://www.zhihu.com/question/39022858?sort=created

5. 法線延展法實現(xiàn)物體描邊:http://www.fzitv.net/article/175213.htm

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

相關(guān)文章

最新評論

栾川县| 聂荣县| 楚雄市| 涞源县| 鲁甸县| 海林市| 济宁市| 天津市| 松滋市| 文安县| 林州市| 延津县| 太康县| 余庆县| 河北区| 广南县| 扶风县| 隆林| 如东县| 浏阳市| 轮台县| 海兴县| 嘉兴市| 福州市| 马鞍山市| 磴口县| 北安市| 盐边县| 贡觉县| 莱西市| 阿城市| 从江县| 许昌县| 桐城市| 玉田县| 鹿泉市| 静宁县| 新野县| 台山市| 讷河市| 兴国县|