|
@@ -19,7 +19,7 @@ let OutlinePass = function ( selectedObjects ) {
|
|
|
this.edgeStrength = 50;
|
|
|
this.downSampleRatio = 1//2; // 抗锯齿 值越低renderTarget size越大,抗锯齿越强,线条可越细(或许可以把模糊化去掉?)
|
|
|
this.pulsePeriod = 0;
|
|
|
-
|
|
|
+ this.showHiddenPart = false //是否判断被遮住的部分,以设置hiddenEdgeColor。一般不需要
|
|
|
Pass.call( this );
|
|
|
|
|
|
this.resolution = new THREE.Vector2( 256, 256 );
|
|
@@ -29,8 +29,7 @@ let OutlinePass = function ( selectedObjects ) {
|
|
|
var resx = Math.round( this.resolution.x / this.downSampleRatio );
|
|
|
var resy = Math.round( this.resolution.y / this.downSampleRatio );
|
|
|
|
|
|
- //this.maskBufferMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff } );
|
|
|
- //this.maskBufferMaterial.side = THREE.DoubleSide;
|
|
|
+
|
|
|
this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
|
|
this.renderTargetMaskBuffer.texture.name = "OutlinePass.mask";
|
|
|
this.renderTargetMaskBuffer.texture.generateMipmaps = false;
|
|
@@ -42,22 +41,13 @@ let OutlinePass = function ( selectedObjects ) {
|
|
|
|
|
|
this.prepareMaskMaterial = this.getPrepareMaskMaterial();
|
|
|
this.prepareMaskMaterial.side = THREE.DoubleSide;
|
|
|
- //this.replaceDepthToViewZ( viewer.mainViewport.camera /* camera */ );
|
|
|
+
|
|
|
|
|
|
this.renderTargetDepthBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
|
|
this.renderTargetDepthBuffer.texture.name = "OutlinePass.depth";
|
|
|
this.renderTargetDepthBuffer.texture.generateMipmaps = false;
|
|
|
|
|
|
- /* this.renderTargetMaskDownSampleBuffer = new THREE.WebGLRenderTarget( resx, resy, pars );
|
|
|
- this.renderTargetMaskDownSampleBuffer.texture.name = "OutlinePass.depthDownSample";
|
|
|
- this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;
|
|
|
-
|
|
|
- this.renderTargetBlurBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
|
|
|
- this.renderTargetBlurBuffer1.texture.name = "OutlinePass.blur1";
|
|
|
- this.renderTargetBlurBuffer1.texture.generateMipmaps = false;
|
|
|
- this.renderTargetBlurBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
|
|
|
- this.renderTargetBlurBuffer2.texture.name = "OutlinePass.blur2";
|
|
|
- this.renderTargetBlurBuffer2.texture.generateMipmaps = false; */
|
|
|
+
|
|
|
|
|
|
this.edgeDetectionMaterial = this.getEdgeDetectionMaterial(this.edgeStrength);
|
|
|
|
|
@@ -65,20 +55,7 @@ let OutlinePass = function ( selectedObjects ) {
|
|
|
this.renderTargetEdgeBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
|
|
|
this.renderTargetEdgeBuffer1.texture.name = "OutlinePass.edge1";
|
|
|
this.renderTargetEdgeBuffer1.texture.generateMipmaps = false;
|
|
|
- /* this.renderTargetEdgeBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
|
|
|
- this.renderTargetEdgeBuffer2.texture.name = "OutlinePass.edge2";
|
|
|
- this.renderTargetEdgeBuffer2.texture.generateMipmaps = false;
|
|
|
-
|
|
|
- var MAX_EDGE_THICKNESS = 4;
|
|
|
- var MAX_EDGE_GLOW = 4;
|
|
|
-
|
|
|
- this.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS );
|
|
|
- this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy );
|
|
|
- this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = 1;
|
|
|
- this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW );
|
|
|
- this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( Math.round( resx / 2 ), Math.round( resy / 2 ) );
|
|
|
- this.separableBlurMaterial2.uniforms[ "kernelRadius" ].value = MAX_EDGE_GLOW;
|
|
|
- */
|
|
|
+
|
|
|
// Overlay material
|
|
|
this.overlayMaterial = this.getOverlayMaterial();
|
|
|
|
|
@@ -96,12 +73,7 @@ let OutlinePass = function ( selectedObjects ) {
|
|
|
transparent: true
|
|
|
} );
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
|
|
|
|
|
|
this.enabled = true;
|
|
@@ -116,9 +88,7 @@ let OutlinePass = function ( selectedObjects ) {
|
|
|
this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
|
|
|
this.quad.frustumCulled = false; // Avoid getting clipped
|
|
|
this.scene.add( this.quad );
|
|
|
-
|
|
|
- /* this.tempPulseColor1 = new THREE.Color();
|
|
|
- this.tempPulseColor2 = new THREE.Color(); */
|
|
|
+
|
|
|
this.textureMatrix = new THREE.Matrix4();
|
|
|
|
|
|
|
|
@@ -136,7 +106,7 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
this.renderTargetDepthBuffer.dispose();
|
|
|
},
|
|
|
|
|
|
- replaceDepthToViewZ( camera ) {
|
|
|
+ replaceDepthToViewZ( camera ) {
|
|
|
var type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic';
|
|
|
if(type == this.lastCameraType )return
|
|
|
this.lastCameraType = type
|
|
@@ -276,21 +246,13 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
|
|
|
let render2 = (target, dontRenderRtEDL=true)=>{
|
|
|
if(renderFun){
|
|
|
- renderFun({target , dontRenderRtEDL})
|
|
|
+ renderFun({target , dontRenderRtEDL })
|
|
|
}else{
|
|
|
renderer.setRenderTarget(target)
|
|
|
renderer.clear()
|
|
|
scenes.forEach(scene=>renderer.render( scene, camera))
|
|
|
}
|
|
|
}
|
|
|
- viewports.forEach(e=>{
|
|
|
- e.oldBeforeRender = e.beforeRender
|
|
|
- e.beforeRender = ()=>{
|
|
|
- e.oldBeforeRender && e.oldBeforeRender()
|
|
|
- this.replaceDepthToViewZ( e.camera );
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
|
|
|
this.oldClearColor.copy( renderer.getClearColor(new THREE.Color) );
|
|
|
this.oldClearAlpha = renderer.getClearAlpha();
|
|
@@ -299,83 +261,108 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
renderer.autoClear = false;
|
|
|
|
|
|
if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST );
|
|
|
+ renderer.setClearColor( 0xffffff, 1 );
|
|
|
|
|
|
- renderer.setClearColor( 0xffffff, 1 );
|
|
|
+ let oldBG = viewer.background, oldBgOpacity = viewer.backgroundOpacity
|
|
|
+ viewer.background = new THREE.Color(1,1,1)
|
|
|
+ viewer.backgroundOpacity = 1;
|
|
|
|
|
|
- // Make selected objects invisible
|
|
|
- this.changeVisibilityOfSelectedObjects( false );
|
|
|
-
|
|
|
- scenes.forEach(scene=>{
|
|
|
- scene.currentBackground = scene.background;
|
|
|
- scene.background = null;
|
|
|
- // 1. Draw Non Selected objects in the depth buffer
|
|
|
- scene.overrideMaterial = this.depthMaterial;
|
|
|
- })
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- render2(this.renderTargetDepthBuffer)
|
|
|
- //renderer.setRenderTarget(this.renderTargetDepthBuffer)
|
|
|
- //renderer.clear()
|
|
|
- //renderer.render( scene, camera/* , this.renderTargetDepthBuffer, true */);
|
|
|
-
|
|
|
- // Make selected objects visible
|
|
|
- this.changeVisibilityOfSelectedObjects( true );
|
|
|
-
|
|
|
-
|
|
|
- viewports.forEach(e=>{
|
|
|
- e.beforeRender = ()=>{
|
|
|
- e.oldBeforeRender && e.oldBeforeRender()
|
|
|
- // Update Texture Matrix for Depth compare
|
|
|
- this.updateTextureMatrix(e.camera);
|
|
|
- this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( e.camera.near, e.camera.far );
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ if(this.showHiddenPart){ //几乎不会使用
|
|
|
+ viewports.forEach(e=>{
|
|
|
+ e.oldBeforeRender = e.beforeRender
|
|
|
+ e.beforeRender = ()=>{
|
|
|
+ e.oldBeforeRender && e.oldBeforeRender()
|
|
|
+ this.replaceDepthToViewZ( e.camera );
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // Make selected objects invisible
|
|
|
+ this.changeVisibilityOfSelectedObjects( false );
|
|
|
+
|
|
|
+ scenes.forEach(scene=>{
|
|
|
+ scene.currentBackground = scene.background;
|
|
|
+ scene.background = null;
|
|
|
+ // 1. Draw Non Selected objects in the depth buffer
|
|
|
+ scene.overrideMaterial = this.depthMaterial;
|
|
|
+ })
|
|
|
+
|
|
|
+ render2(this.renderTargetDepthBuffer)
|
|
|
+
|
|
|
+ // Make selected objects visible
|
|
|
+ this.changeVisibilityOfSelectedObjects( true );
|
|
|
|
|
|
- // Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects
|
|
|
- this.changeVisibilityOfNonSelectedObjects( false , scenes);
|
|
|
-
|
|
|
-
|
|
|
- scenes.forEach(scene=>{
|
|
|
- scene.overrideMaterial = this.prepareMaskMaterial;
|
|
|
- })
|
|
|
-
|
|
|
-
|
|
|
- this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture;
|
|
|
- this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix;
|
|
|
-
|
|
|
- //renderer.setRenderTarget(this.renderTargetMaskBuffer)
|
|
|
- //renderer.clear()
|
|
|
- //renderer.render( scene, camera/* , this.renderTargetMaskBuffer, true */ );
|
|
|
+
|
|
|
+ viewports.forEach(e=>{
|
|
|
+ e.beforeRender = ()=>{
|
|
|
+ e.oldBeforeRender && e.oldBeforeRender()
|
|
|
+ // Update Texture Matrix for Depth compare
|
|
|
+ this.updateTextureMatrix(e.camera);
|
|
|
+ this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( e.camera.near, e.camera.far );
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ }else{
|
|
|
+ //不渲染背景
|
|
|
+ scenes.forEach(scene=>{
|
|
|
+ scene.currentBackground = scene.background;
|
|
|
+ scene.background = null;
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
- viewer.scene.pointclouds.forEach(e=>{ //先将点云透明度变为1,因为点云透明度莫名其妙会影响其r值
|
|
|
- e.material._oldOpa = e.material.opacity
|
|
|
- e.material.opacity = 1
|
|
|
- })
|
|
|
+ let colorType, colors = new Map() , opas = new Map()
|
|
|
+ {//绘制选中部分
|
|
|
+ // Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects
|
|
|
+ this.changeVisibilityOfNonSelectedObjects( false , scenes);
|
|
|
+
|
|
|
+ scenes.forEach(scene=>{
|
|
|
+ scene.overrideMaterial = this.prepareMaskMaterial;
|
|
|
+ })
|
|
|
+
|
|
|
+ if(this.showHiddenPart){
|
|
|
+ this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture;
|
|
|
+ this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix;
|
|
|
+ }
|
|
|
+
|
|
|
+ //因为点云不受prepareMaskMaterial作用,所以手动将他们变为黑色不透明
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{ //先将点云透明度变为1,因为点云透明度莫名其妙会影响其r值//
|
|
|
+ colorType = e.material.activeAttributeName
|
|
|
+ e.material.activeAttributeName = 'color'
|
|
|
+
|
|
|
+ colors.set(e, e.material.color)
|
|
|
+ e.material.color = '#000000';
|
|
|
+
|
|
|
+ opas.set(e, e.material.opacity)
|
|
|
+ e.material.opacity = 1
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
render2(this.renderTargetMaskBuffer)
|
|
|
|
|
|
- viewer.scene.pointclouds.forEach(e=>{//恢复
|
|
|
- e.material.opacity = e.material._oldOpa
|
|
|
- delete e.material._oldOpa
|
|
|
- })
|
|
|
-
|
|
|
- viewports.forEach((e)=>{e.beforeRender = e.oldBeforeRender})
|
|
|
-
|
|
|
- this.changeVisibilityOfNonSelectedObjects( true , scenes);
|
|
|
|
|
|
-
|
|
|
- scenes.forEach(scene=>{
|
|
|
- scene.overrideMaterial = null;
|
|
|
- scene.background = scene.currentBackground
|
|
|
- })
|
|
|
-
|
|
|
+ {//恢复
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{
|
|
|
+ e.material.activeAttributeName = colorType
|
|
|
+ e.material.color = colors.get(e)
|
|
|
+ e.material.opacity = opas.get(e)
|
|
|
+ })
|
|
|
+
|
|
|
+ if(this.showHiddenPart){
|
|
|
+ viewports.forEach((e)=>{e.beforeRender = e.oldBeforeRender})
|
|
|
+ }
|
|
|
+
|
|
|
+ scenes.forEach(scene=>{
|
|
|
+ scene.overrideMaterial = null;
|
|
|
+ scene.background = scene.currentBackground
|
|
|
+ })
|
|
|
+ viewer.background = oldBG
|
|
|
+ viewer.backgroundOpacity = oldBgOpacity
|
|
|
+
|
|
|
+ this.changeVisibilityOfNonSelectedObjects( true , scenes);
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
|
|
|
+ //检测边缘并绘制
|
|
|
// 3. Apply Edge Detection Pass
|
|
|
this.quad.material = this.edgeDetectionMaterial;
|
|
|
this.edgeDetectionMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskBuffer.texture;//this.renderTargetMaskDownSampleBuffer.texture;
|
|
@@ -387,14 +374,15 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.hiddenEdgeColor //this.tempPulseColor2;
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
- let buffer = readBuffer
|
|
|
+ let buffer
|
|
|
if ( this.renderToScreen ) {
|
|
|
this.quad.material.transparent = true
|
|
|
|
|
|
buffer = null
|
|
|
renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
|
|
|
- render2(null,false)
|
|
|
+ render2(null,false) //普通绘制原场景
|
|
|
|
|
|
//绘制到全屏
|
|
|
let renderSize = renderer.getSize(new THREE.Vector2()); //是client大小
|
|
@@ -402,98 +390,71 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
renderer.setScissorTest( false );
|
|
|
|
|
|
}else{
|
|
|
+ buffer = readBuffer
|
|
|
renderer.setClearColor( 0x000000, 0 );
|
|
|
renderer.clear()
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- renderer.setRenderTarget(buffer/* this.renderTargetEdgeBuffer1 */)
|
|
|
-
|
|
|
- renderer.render( this.scene, this.camera/* , this.renderTargetEdgeBuffer1, true */);
|
|
|
+
|
|
|
+ renderer.setRenderTarget( buffer )
|
|
|
+ renderer.render( this.scene, this.camera ); //将边缘覆盖上去
|
|
|
|
|
|
-
|
|
|
- //这次删掉
|
|
|
- /* // Blend it additively over the input texture
|
|
|
- this.quad.material = this.overlayMaterial;
|
|
|
- //this.overlayMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskBuffer.texture;
|
|
|
- this.overlayMaterial.uniforms[ "edgeTexture1" ].value = this.renderTargetEdgeBuffer1.texture;
|
|
|
- //this.overlayMaterial.uniforms[ "edgeTexture2" ].value = this.renderTargetEdgeBuffer2.texture;
|
|
|
- //this.overlayMaterial.uniforms[ "patternTexture" ].value = this.patternTexture;
|
|
|
- this.overlayMaterial.uniforms[ "edgeStrength" ].value = this.edgeStrength;
|
|
|
- //this.overlayMaterial.uniforms[ "edgeGlow" ].value = this.edgeGlow;
|
|
|
- //this.overlayMaterial.uniforms[ "usePatternTexture" ].value = this.usePatternTexture;
|
|
|
|
|
|
-
|
|
|
- if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
|
|
|
- //renderer.render( this.scene, camera, readBuffer, false );
|
|
|
-
|
|
|
- //改:清空readBuffer, 仅绘制出outline的部分
|
|
|
-
|
|
|
- renderer.setClearColor( 0x000000, 0 );
|
|
|
- renderer.setRenderTarget(readBuffer)
|
|
|
- renderer.clear()
|
|
|
- renderer.render( this.scene, this.camera );
|
|
|
- */
|
|
|
+
|
|
|
+
|
|
|
renderer.setRenderTarget(oldTarget)
|
|
|
renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
|
|
|
renderer.autoClear = oldAutoClear;
|
|
|
return true
|
|
|
}
|
|
|
-
|
|
|
- /* if ( this.renderToScreen ) {
|
|
|
-
|
|
|
- this.quad.material = this.materialCopy;
|
|
|
- this.copyUniforms[ "tDiffuse" ].value = readBuffer.texture;
|
|
|
- renderer.render( this.scene , this.camera );
|
|
|
-
|
|
|
- } */
|
|
|
+
|
|
|
|
|
|
},
|
|
|
|
|
|
getPrepareMaskMaterial: function () {
|
|
|
-
|
|
|
- return new THREE.ShaderMaterial( {
|
|
|
-
|
|
|
- uniforms: {
|
|
|
- "depthTexture": { value: null },
|
|
|
- "cameraNearFar": { value: new THREE.Vector2( 0.5, 0.5 ) },
|
|
|
- "textureMatrix": { value: new THREE.Matrix4() }
|
|
|
- },
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
- 'varying vec4 projTexCoord;',
|
|
|
- 'varying vec4 vPosition;',
|
|
|
- 'uniform mat4 textureMatrix;',
|
|
|
-
|
|
|
- 'void main() {',
|
|
|
-
|
|
|
- ' vPosition = modelViewMatrix * vec4( position, 1.0 );',
|
|
|
- ' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
|
|
|
- ' projTexCoord = textureMatrix * worldPosition;',
|
|
|
- ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
|
|
|
-
|
|
|
- '}'
|
|
|
- ].join( '\n' ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
- '#include <packing>',
|
|
|
- 'varying vec4 vPosition;',
|
|
|
- 'varying vec4 projTexCoord;',
|
|
|
- 'uniform sampler2D depthTexture;',
|
|
|
- 'uniform vec2 cameraNearFar;',
|
|
|
-
|
|
|
- 'void main() {',
|
|
|
-
|
|
|
- ' float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));',
|
|
|
- ' float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );',
|
|
|
- ' float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;',
|
|
|
- ' gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);',
|
|
|
-
|
|
|
- '}'
|
|
|
- ].join( '\n' )
|
|
|
- //scene.overrideMaterial
|
|
|
- //为什么画出来红色通道不为0,且depthTest似乎会改变红色通道的值
|
|
|
- } );
|
|
|
+ if(this.showHiddenPart){
|
|
|
+ return new THREE.ShaderMaterial( {
|
|
|
+
|
|
|
+ uniforms: {
|
|
|
+ "depthTexture": { value: null },
|
|
|
+ "cameraNearFar": { value: new THREE.Vector2( 0.5, 0.5 ) },
|
|
|
+ "textureMatrix": { value: new THREE.Matrix4() }
|
|
|
+ },
|
|
|
+
|
|
|
+ vertexShader: [
|
|
|
+ 'varying vec4 projTexCoord;',
|
|
|
+ 'varying vec4 vPosition;',
|
|
|
+ 'uniform mat4 textureMatrix;',
|
|
|
+
|
|
|
+ 'void main() {',
|
|
|
+
|
|
|
+ ' vPosition = modelViewMatrix * vec4( position, 1.0 );',
|
|
|
+ ' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
|
|
|
+ ' projTexCoord = textureMatrix * worldPosition;',
|
|
|
+ ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
|
|
|
+
|
|
|
+ '}'
|
|
|
+ ].join( '\n' ),
|
|
|
+
|
|
|
+ fragmentShader: [
|
|
|
+ '#include <packing>',
|
|
|
+ 'varying vec4 vPosition;',
|
|
|
+ 'varying vec4 projTexCoord;',
|
|
|
+ 'uniform sampler2D depthTexture;',
|
|
|
+ 'uniform vec2 cameraNearFar;',
|
|
|
+
|
|
|
+ 'void main() {',
|
|
|
+
|
|
|
+ ' float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));',
|
|
|
+ ' float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );',
|
|
|
+ ' float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;', //决定是否为hiddenPart
|
|
|
+ ' gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);',
|
|
|
+
|
|
|
+ '}'
|
|
|
+ ].join( '\n' )
|
|
|
+ } );//没有绘制部分的颜色是clearColor,255
|
|
|
+ }else{
|
|
|
+ return new THREE.MeshBasicMaterial({color:'#000000'}) //不检测深度,不判断遮挡
|
|
|
+ }
|
|
|
|
|
|
},
|
|
|
|
|
@@ -560,7 +521,7 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
float d = length( vec2(diff1, diff2) ) * edgeStrength;
|
|
|
float a1 = min(c1.g, c2.g);
|
|
|
float a2 = min(c3.g, c4.g);
|
|
|
- float visibilityFactor = min(a1, a2);
|
|
|
+ float visibilityFactor = min(a1, a2); //检测深度值,是否被遮挡
|
|
|
vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;
|
|
|
//gl_FragColor = vec4(0.0,1.0,0.0,1.0);
|
|
|
gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);
|
|
@@ -624,7 +585,7 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
|
|
|
},
|
|
|
|
|
|
- getOverlayMaterial: function () {
|
|
|
+ getOverlayMaterial: function () {//对边缘线进一步处理,已被废弃
|
|
|
|
|
|
return new THREE.ShaderMaterial( {
|
|
|
|
|
@@ -688,4 +649,37 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
|
|
|
OutlinePass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );
|
|
|
OutlinePass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );
|
|
|
|
|
|
-export default OutlinePass
|
|
|
+export default OutlinePass
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+
|
|
|
+
|
|
|
+渲染步骤:(没有showHiddenPart时)
|
|
|
+
|
|
|
+仅绘制选中部分,材质为普通的单色材质,颜色是黑色不透明。未绘制部分的clearColor是白色不透明。
|
|
|
+(详见prepareMaskMaterial,输出的r要为0)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+然后在上面绘制的图中,根据r的差值,得到边缘线。
|
|
|
+
|
|
|
+
|
|
|
+正常绘制场景之后,将上面的边缘线覆盖于其上。
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+(如果showHiddenPart,最开始还要先隐藏选中部分,这是为了得到非选中部分的深度值,然后再绘制选中部分时去比较选中和非选中部分之间的深度差异。以判断是否被遮挡。)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ */
|