From c6d7559218dfb8282070815649103b7b434e3c75 Mon Sep 17 00:00:00 2001 From: ligaofeng0901 Date: Tue, 11 Jan 2022 19:26:06 +0800 Subject: [PATCH] add bmap-three modification --- .gitignore | 4 +- bmap-three-all.sh | 27 +++ bmap-three-copy-only.sh | 10 + examples/webgl_materials_pmrem_dynamic.html | 255 ++++++++++++++++++++ src/extras/PMREMGenerator.js | 68 +++++- src/renderers/WebGLRenderer.js | 7 + src/renderers/webgl/WebGLProgram.js | 19 +- src/renderers/webgl/WebGLPrograms.js | 10 +- src/renderers/webgl/WebGLTextures.js | 2 +- 9 files changed, 395 insertions(+), 7 deletions(-) create mode 100644 bmap-three-all.sh create mode 100644 bmap-three-copy-only.sh create mode 100644 examples/webgl_materials_pmrem_dynamic.html diff --git a/.gitignore b/.gitignore index 50df59a8212b6c..88c7d74a645e34 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,6 @@ test/treeshake/stats.html test/e2e/chromium test/e2e/output-screenshots -**/node_modules \ No newline at end of file +**/node_modules + +bmap-three \ No newline at end of file diff --git a/bmap-three-all.sh b/bmap-three-all.sh new file mode 100644 index 00000000000000..8299efd6df7219 --- /dev/null +++ b/bmap-three-all.sh @@ -0,0 +1,27 @@ +cd `dirname $0` +# 如果bmap-three目录不存在,创建目录 +if [ ! -d "bmap-three" ]; then + mkdir bmap-three +fi + +# 复制src -> bmap-three +cp -r src bmap-three +cp -r package.json bmap-three + +# 如果不存在bmap-three/examples,则创建 +if [ ! -d "bmap-three/examples" ]; then + mkdir bmap-three/examples +fi + +cp -r examples/jsm bmap-three/examples +cp -r examples/fonts bmap-three/examples + +cp -r build bmap-three +# 进入bmap-three目录 +cd bmap-three + +# 修改package.json的name字段,重新覆盖原来的文件 +sed -i '' 's/"name": "three"/"name": "bmap-three"/g' package.json + +# 替换examples目录下所有js文件中的import声明中的three为bmap-three,包含只import部分模块的情况 +find examples -name "*.js" | xargs sed -i '' "s/from 'three';/from 'bmap-three';/g" \ No newline at end of file diff --git a/bmap-three-copy-only.sh b/bmap-three-copy-only.sh new file mode 100644 index 00000000000000..c077e30993d0e8 --- /dev/null +++ b/bmap-three-copy-only.sh @@ -0,0 +1,10 @@ +cd `dirname $0` + +npm run build + +# 如果bmap-three目录不存在,创建目录 +if [ ! -d "bmap-three" ]; then + mkdir bmap-three +fi + +cp -r build bmap-three diff --git a/examples/webgl_materials_pmrem_dynamic.html b/examples/webgl_materials_pmrem_dynamic.html new file mode 100644 index 00000000000000..3edd12405d4455 --- /dev/null +++ b/examples/webgl_materials_pmrem_dynamic.html @@ -0,0 +1,255 @@ + + + + three.js webgl - materials - dynamic cube reflection + + + + + + + +
three.js webgl - materials - dynamic cube reflection
Photo by Jón Ragnarsson.
+ + + + + diff --git a/src/extras/PMREMGenerator.js b/src/extras/PMREMGenerator.js index 73d52bee27339f..2d48e64d3f2b95 100644 --- a/src/extras/PMREMGenerator.js +++ b/src/extras/PMREMGenerator.js @@ -100,14 +100,24 @@ class PMREMGenerator { * and far planes ensure the scene is rendered in its entirety (the cubeCamera * is placed at the origin). */ - fromScene( scene, sigma = 0, near = 0.1, far = 100 ) { + fromScene( scene, sigma = 0, near = 0.1, far = 100, cubeUVRenderTarget = null, pingPongRenderTarget = null ) { _oldTarget = this._renderer.getRenderTarget(); this._setSize( 256 ); - const cubeUVRenderTarget = this._allocateTargets(); cubeUVRenderTarget.depthBuffer = true; + if ( ! cubeUVRenderTarget ) { + + cubeUVRenderTarget = this._allocateTargets(); + + } + + if ( pingPongRenderTarget ) { + + this._pingPongRenderTarget = pingPongRenderTarget; + + } this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); @@ -124,6 +134,48 @@ class PMREMGenerator { } + prepareForRenderTarget( cubeUVRenderTarget, pingPongRenderTarget = null, cubeSize = 256 ) { + + this._setSize( cubeSize ); + const { _lodMax } = this; + ( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) ); + const width = 3 * Math.max( this._cubeSize, 16 * 7 ); + const height = 4 * this._cubeSize; + this._blurMaterial = _getBlurShader( _lodMax, width, height ); + cubeUVRenderTarget.setSize( width, height ); + + if ( pingPongRenderTarget ) { + + pingPongRenderTarget.setSize( width, height); + + } + + } + + fromSceneToRenderTarget( scene, cubeUVRenderTarget, pingPongRenderTarget, sigma = 0, near = 0.1, far = 100 ) { + + _oldTarget = this._renderer.getRenderTarget(); + + this._pingPongRenderTarget = pingPongRenderTarget; + + + this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); + if ( sigma > 0 ) { + + this._blur( cubeUVRenderTarget, 0, 0, sigma ); + + } + + this._applyPMREM( cubeUVRenderTarget ); + + this._renderer.setRenderTarget( _oldTarget ); + cubeUVRenderTarget.scissorTest = false; + _setViewport( cubeUVRenderTarget, 0, 0, cubeUVRenderTarget.width, cubeUVRenderTarget.height ); + + return cubeUVRenderTarget; + + } + /** * Generates a PMREM from an equirectangular texture, which can be either LDR * or HDR. The ideal input image size is 1k (1024 x 512), @@ -847,6 +899,16 @@ function _getCommonVertexShader() { varying vec3 vOutputDirection; + mat3 getRotationMatrix(vec3 axis, float angle) { + axis = normalize(axis); + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + + return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c); + } // RH coordinate system; PMREM face-indexing convention vec3 getDirection( vec2 uv, float face ) { @@ -883,6 +945,8 @@ function _getCommonVertexShader() { } + mat3 rotationMatrix = getRotationMatrix(vec3(1.0, 0.0, 0.0), 1.57); + direction = rotationMatrix * direction; return direction; } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d494700cd0171c..acb38168b3b001 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1622,6 +1622,7 @@ class WebGLRenderer { materialProperties.vertexAlphas = parameters.vertexAlphas; materialProperties.vertexTangents = parameters.vertexTangents; materialProperties.toneMapping = parameters.toneMapping; + materialProperties.extraProgramCacheKey = parameters.extraProgramCacheKey; } @@ -1648,6 +1649,8 @@ class WebGLRenderer { const materialProperties = properties.get( material ); const lights = currentRenderState.state.lights; + const extraProgramCacheKey = _this.extraProgramCacheKey; + if ( _clippingEnabled === true ) { if ( _localClippingEnabled === true || camera !== _currentCamera ) { @@ -1737,6 +1740,10 @@ class WebGLRenderer { needsProgramChange = true; + } else if ( extraProgramCacheKey !== materialProperties.extraProgramCacheKey ) { + + needsProgramChange = true; + } } else { diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index c90064186f0a75..ea57023c38adf7 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -771,6 +771,14 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { } + if ( renderer.onShaderBeforeResolve ) { + + const ret = renderer.onShaderBeforeResolve( vertexShader, fragmentShader, parameters ); + vertexShader = ret.vertexShader; + fragmentShader = ret.fragmentShader; + + } + vertexShader = resolveIncludes( vertexShader ); vertexShader = replaceLightNums( vertexShader, parameters ); vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); @@ -813,9 +821,16 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { } - const vertexGlsl = versionString + prefixVertex + vertexShader; - const fragmentGlsl = versionString + prefixFragment + fragmentShader; + let vertexGlsl = versionString + prefixVertex + vertexShader; + let fragmentGlsl = versionString + prefixFragment + fragmentShader; + if ( renderer.onShaderBeforeCompile ) { + + const ret = renderer.onShaderBeforeCompile( vertexGlsl, fragmentGlsl, parameters ); + vertexGlsl = ret.vertexShader; + fragmentGlsl = ret.fragmentShader; + + } // console.log( '*VERTEX*', vertexGlsl ); // console.log( '*FRAGMENT*', fragmentGlsl ); diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index cf07ee3fc94656..03b07b087909f0 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -339,7 +339,9 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities rendererExtensionDrawBuffers: IS_WEBGL2 || extensions.has( 'WEBGL_draw_buffers' ), rendererExtensionShaderTextureLod: IS_WEBGL2 || extensions.has( 'EXT_shader_texture_lod' ), - customProgramCacheKey: material.customProgramCacheKey() + customProgramCacheKey: material.customProgramCacheKey(), + + extraProgramCacheKey: renderer.extraProgramCacheKey }; @@ -383,6 +385,12 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities array.push( parameters.customProgramCacheKey ); + if ( renderer.extraProgramCacheKey ) { + + array.push( renderer.extraProgramCacheKey ); + + } + return array.join(); } diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js index 11ba4c408631d0..62d21dcadafb30 100644 --- a/src/renderers/webgl/WebGLTextures.js +++ b/src/renderers/webgl/WebGLTextures.js @@ -1846,7 +1846,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( ignoreDepthValues === false ) { if ( renderTarget.depthBuffer ) mask |= _gl.DEPTH_BUFFER_BIT; - if ( renderTarget.stencilBuffer ) mask |= _gl.STENCIL_BUFFER_BIT; + // if ( renderTarget.stencilBuffer ) mask |= _gl.STENCIL_BUFFER_BIT; }