bytev-charts
Version:
基于echarts和JavaScript及ES6封装的一个可以直接调用的图表组件库,内置主题设计,简单快捷,且支持用户自定义配置; npm 安装方式: npm install bytev-charts 若启动提示还需额外install插件,则运行 npm install @babel/runtime-corejs2 即可;
132 lines (104 loc) • 6.88 kB
JavaScript
/**
* This class generates custom mipmaps for a roughness map by encoding the lost variation in the
* normal map mip levels as increased roughness in the corresponding roughness mip levels. This
* helps with rendering accuracy for MeshStandardMaterial, and also helps with anti-aliasing when
* using PMREM. If the normal map is larger than the roughness map, the roughness map will be
* enlarged to match the dimensions of the normal map.
*/
import { LinearMipMapLinearFilter, MathUtils, Mesh, NoBlending, OrthographicCamera, PlaneBufferGeometry, RawShaderMaterial, Vector2, WebGLRenderTarget } from "../../../build/three.module.js";
var _mipmapMaterial = _getMipmapMaterial();
var _mesh = new Mesh(new PlaneBufferGeometry(2, 2), _mipmapMaterial);
var _flatCamera = new OrthographicCamera(0, 1, 0, 1, 0, 1);
var _tempTarget = null;
var _renderer = null;
function RoughnessMipmapper(renderer) {
_renderer = renderer;
_renderer.compile(_mesh, _flatCamera);
}
RoughnessMipmapper.prototype = {
constructor: RoughnessMipmapper,
generateMipmaps: function generateMipmaps(material) {
var roughnessMap = material.roughnessMap,
normalMap = material.normalMap;
if (roughnessMap == null || normalMap == null || !roughnessMap.generateMipmaps || material.userData.roughnessUpdated) return;
material.userData.roughnessUpdated = true;
var width = Math.max(roughnessMap.image.width, normalMap.image.width);
var height = Math.max(roughnessMap.image.height, normalMap.image.height);
if (!MathUtils.isPowerOfTwo(width) || !MathUtils.isPowerOfTwo(height)) return;
var oldTarget = _renderer.getRenderTarget();
var autoClear = _renderer.autoClear;
_renderer.autoClear = false;
if (_tempTarget == null || _tempTarget.width !== width || _tempTarget.height !== height) {
if (_tempTarget != null) _tempTarget.dispose();
_tempTarget = new WebGLRenderTarget(width, height, {
depthBuffer: false,
stencilBuffer: false
});
_tempTarget.scissorTest = true;
}
if (width !== roughnessMap.image.width || height !== roughnessMap.image.height) {
var newRoughnessTarget = new WebGLRenderTarget(width, height, {
minFilter: LinearMipMapLinearFilter,
depthBuffer: false,
stencilBuffer: false
});
newRoughnessTarget.texture.generateMipmaps = true; // Setting the render target causes the memory to be allocated.
_renderer.setRenderTarget(newRoughnessTarget);
material.roughnessMap = newRoughnessTarget.texture;
if (material.metalnessMap == roughnessMap) material.metalnessMap = material.roughnessMap;
if (material.aoMap == roughnessMap) material.aoMap = material.roughnessMap;
}
_mipmapMaterial.uniforms.roughnessMap.value = roughnessMap;
_mipmapMaterial.uniforms.normalMap.value = normalMap;
var position = new Vector2(0, 0);
var texelSize = _mipmapMaterial.uniforms.texelSize.value;
for (var mip = 0; width >= 1 && height >= 1; ++mip, width /= 2, height /= 2) {
// Rendering to a mip level is not allowed in webGL1. Instead we must set
// up a secondary texture to write the result to, then copy it back to the
// proper mipmap level.
texelSize.set(1.0 / width, 1.0 / height);
if (mip == 0) texelSize.set(0.0, 0.0);
_tempTarget.viewport.set(position.x, position.y, width, height);
_tempTarget.scissor.set(position.x, position.y, width, height);
_renderer.setRenderTarget(_tempTarget);
_renderer.render(_mesh, _flatCamera);
_renderer.copyFramebufferToTexture(position, material.roughnessMap, mip);
_mipmapMaterial.uniforms.roughnessMap.value = material.roughnessMap;
}
if (roughnessMap !== material.roughnessMap) roughnessMap.dispose();
_renderer.setRenderTarget(oldTarget);
_renderer.autoClear = autoClear;
},
dispose: function dispose() {
_mipmapMaterial.dispose();
_mesh.geometry.dispose();
if (_tempTarget != null) _tempTarget.dispose();
}
};
function _getMipmapMaterial() {
var shaderMaterial = new RawShaderMaterial({
uniforms: {
roughnessMap: {
value: null
},
normalMap: {
value: null
},
texelSize: {
value: new Vector2(1, 1)
}
},
vertexShader:
/* glsl */
"\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\t\t\tattribute vec3 position;\n\t\t\tattribute vec2 uv;\n\t\t\tvarying vec2 vUv;\n\t\t\tvoid main() {\n\t\t\t\tvUv = uv;\n\t\t\t\tgl_Position = vec4( position, 1.0 );\n\t\t\t}\n\t\t",
fragmentShader:
/* glsl */
"\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\t\t\tvarying vec2 vUv;\n\t\t\tuniform sampler2D roughnessMap;\n\t\t\tuniform sampler2D normalMap;\n\t\t\tuniform vec2 texelSize;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\tvec4 envMapTexelToLinear(vec4 a){return a;}\n\t\t\t#include <cube_uv_reflection_fragment>\n\n\t\t\tfloat roughnessToVariance(float roughness) {\n\t\t\t\tfloat variance = 0.0;\n\t\t\t\tif (roughness >= r1) {\n\t\t\t\t\tvariance = (r0 - roughness) * (v1 - v0) / (r0 - r1) + v0;\n\t\t\t\t} else if (roughness >= r4) {\n\t\t\t\t\tvariance = (r1 - roughness) * (v4 - v1) / (r1 - r4) + v1;\n\t\t\t\t} else if (roughness >= r5) {\n\t\t\t\t\tvariance = (r4 - roughness) * (v5 - v4) / (r4 - r5) + v4;\n\t\t\t\t} else {\n\t\t\t\t\tfloat roughness2 = roughness * roughness;\n\t\t\t\t\tvariance = 1.79 * roughness2 * roughness2;\n\t\t\t\t}\n\t\t\t\treturn variance;\n\t\t\t}\n\t\t\tfloat varianceToRoughness(float variance) {\n\t\t\t\tfloat roughness = 0.0;\n\t\t\t\tif (variance >= v1) {\n\t\t\t\t\troughness = (v0 - variance) * (r1 - r0) / (v0 - v1) + r0;\n\t\t\t\t} else if (variance >= v4) {\n\t\t\t\t\troughness = (v1 - variance) * (r4 - r1) / (v1 - v4) + r1;\n\t\t\t\t} else if (variance >= v5) {\n\t\t\t\t\troughness = (v4 - variance) * (r5 - r4) / (v4 - v5) + r4;\n\t\t\t\t} else {\n\t\t\t\t\troughness = pow(0.559 * variance, 0.25);// 0.559 = 1.0 / 1.79\n\t\t\t\t}\n\t\t\t\treturn roughness;\n\t\t\t}\n\n\t\t\tvoid main() {\n\t\t\t\tgl_FragColor = texture2D(roughnessMap, vUv, -1.0);\n\t\t\t\tif (texelSize.x == 0.0) return;\n\t\t\t\tfloat roughness = gl_FragColor.g;\n\t\t\t\tfloat variance = roughnessToVariance(roughness);\n\t\t\t\tvec3 avgNormal;\n\t\t\t\tfor (float x = -1.0; x < 2.0; x += 2.0) {\n\t\t\t\t\tfor (float y = -1.0; y < 2.0; y += 2.0) {\n\t\t\t\t\t\tvec2 uv = vUv + vec2(x, y) * 0.25 * texelSize;\n\t\t\t\t\t\tavgNormal += normalize(texture2D(normalMap, uv, -1.0).xyz - 0.5);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvariance += 1.0 - 0.25 * length(avgNormal);\n\t\t\t\tgl_FragColor.g = varianceToRoughness(variance);\n\t\t\t}\n\t\t",
blending: NoBlending,
depthTest: false,
depthWrite: false
});
shaderMaterial.type = 'RoughnessMipmapper';
return shaderMaterial;
}
export { RoughnessMipmapper };