91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

three.js利用卷積法實現物體描邊效果

發布時間:2021-02-02 11:30:27 來源:億速云 閱讀:377 作者:小新 欄目:web開發

小編給大家分享一下three.js利用卷積法實現物體描邊效果,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

法線延展法

網上使用法線延展法實現物體描邊效果的文章比較多,這里不再描述。

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

three.js利用卷積法實現物體描邊效果

卷積法

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

three.js利用卷積法實現物體描邊效果three.js利用卷積法實現物體描邊效果three.js利用卷積法實現物體描邊效果

使用three.js具體的實現方法如下:

  1. 創建著色器材質,隱藏不需要描邊的物體進行渲染,將需要描邊的位置渲染成白色,其他位置渲染成黑色。

  2. 利用片源著色器計算卷積,白色是物體內部,黑色是物體外部,灰色是邊框。

  3. 設置材質透明、不融合,將邊框疊加到原圖上,可以使用FXAA抗鋸齒。

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

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

詳細的實現過程:

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

three.js利用卷積法實現物體描邊效果

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

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

renderScene.overrideMaterial = this.maskMaterial;

著色器材質:

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

效果圖:

three.js利用卷積法實現物體描邊效果

3. 創建著色器材質進行卷積計算,每四個像素顏色求平均值得到一個像素。描邊物體內部是白色,外部是黑色,物體邊緣處會得到灰色。灰色就是我們所需的邊框。

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寬度和高度,為了讓邊框更平滑,可以設置為原來canvas的兩倍。color是邊框顏色,thickness是邊框粗細。

注意,要將材質transparent設置為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);
}

效果圖:

three.js利用卷積法實現物體描邊效果

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

著色器材質:

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要設置為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;
}

得到最終效果圖:

three.js利用卷積法實現物體描邊效果

以上是“three.js利用卷積法實現物體描邊效果”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

基隆市| 太仆寺旗| 永修县| 禹城市| 新乡市| 合肥市| 鲁甸县| 昌乐县| 康平县| 稻城县| 深州市| 麻城市| 和田县| 清水河县| 天峨县| 晴隆县| 侯马市| 巢湖市| 长武县| 寿阳县| 广饶县| 昌邑市| 梁平县| 岳池县| 黎川县| 鄂伦春自治旗| 长汀县| 阜阳市| 阜宁县| 苏尼特右旗| 新绛县| 高台县| 上栗县| 六盘水市| 黄浦区| 陆良县| 永城市| 手机| 广州市| 邢台县| 克山县|