本文主要是介绍threejs-无限网格InfiniteGridHelper,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
源代码
// Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper)THREE.InfiniteGridHelper = function InfiniteGridHelper( size1, size2, color, distance, axes = 'xzy' ) {color = color || new THREE.Color( 'white' );size1 = size1 || 10;size2 = size2 || 100;distance = distance || 8000;const planeAxes = axes.substr( 0, 2 );const geometry = new THREE.PlaneBufferGeometry( 2, 2, 1, 1 );const material = new THREE.ShaderMaterial( {side: THREE.DoubleSide,uniforms: {uSize1: {value: size1},uSize2: {value: size2},uColor: {value: color},uDistance: {value: distance}},transparent: true,vertexShader: `varying vec3 worldPosition;void main() {vec3 pos = position.xzy * 1000.0;pos.xz += cameraPosition.xz;worldPosition = pos;gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);}`,fragmentShader: `varying vec3 worldPosition;float getGrid(float size) {vec2 r = worldPosition.xz / size;vec2 grid = abs(fract(r - 0.5) ) / (2.0*fwidth(r));float line = min(grid.x, grid.y);return 1.0 - min(line, 1.0);}void main() {float d = 1.0 - min(distance(cameraPosition.xz, worldPosition.xz) / 1000.0, 1.0);float g1 = getGrid(2.5);float g2 = getGrid(2.5);gl_FragColor = vec4(0.1843137254901961, 0.30980392156862746, 0.30980392156862746, mix(g2, g1, g1) * pow(d, 3.0));gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);if ( gl_FragColor.a <= 0.0 ) discard;}`,extensions: {derivatives: true}} );THREE.Mesh.call( this, geometry, material );this.frustumCulled = false;};THREE.InfiniteGridHelper.prototype = {...THREE.Mesh.prototype,...THREE.Object3D.prototype,...THREE.EventDispatcher.prototype
};if ( parseInt( THREE.REVISION ) > 126 ) {class InfiniteGridHelper extends THREE.Mesh {constructor ( size1, size2, color, distance, axes = 'xzy' ) {color = color || new THREE.Color( 'white' );size1 = size1 || 10;size2 = size2 || 100;distance = distance || 8000;const planeAxes = axes.substr( 0, 2 );const geometry = new THREE.PlaneBufferGeometry( 2, 2, 1, 1 );const material = new THREE.ShaderMaterial( {side: THREE.DoubleSide,uniforms: {uSize1: {value: size1},uSize2: {value: size2},uColor: {value: color},uDistance: {value: distance}},transparent: true,vertexShader: `varying vec3 worldPosition;uniform float uDistance;void main() {vec3 pos = position.${axes} * uDistance;pos.${planeAxes} += cameraPosition.${planeAxes};worldPosition = pos;gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);}`,fragmentShader: `varying vec3 worldPosition;uniform float uSize1;uniform float uSize2;uniform vec3 uColor;uniform float uDistance;float getGrid(float size) {vec2 r = worldPosition.${planeAxes} / size;vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);float line = min(grid.x, grid.y);return 1.0 - min(line, 1.0);}void main() {float d = 1.0 - min(distance(cameraPosition.${planeAxes}, worldPosition.${planeAxes}) / uDistance, 1.0);float g1 = getGrid(uSize1);float g2 = getGrid(uSize2);gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);if ( gl_FragColor.a <= 0.0 ) discard;}`,extensions: {derivatives: true}} );super( geometry, material );this.frustumCulled = false;}}Object.assign( InfiniteGridHelper.prototype, THREE.InfiniteGridHelper.prototype );THREE.InfiniteGridHelper = InfiniteGridHelper;}
使用
var gridHelper =new THREE.InfiniteGridHelper(1, 5, new THREE.Color(0x2F4F4F), 200);
scene.add(gridHelper);
效果图
解析
float getGrid(float size) {vec2 r = worldPosition.${planeAxes} / size;vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);float line = min(grid.x, grid.y);return 1.0 - min(line, 1.0);}
fract()函数是GLSL(OpenGL Shading Language)中一个内建函数,用于获取一个浮点数的小数部分。换句话说,它会返回一个数减去其整数部分之后的结果,且结果的范围总是从0(包含)到1(不包含),所以fract是一个周期性函数,周期为1。
因此
vec2 r = worldPosition.${planeAxes} / size;
vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth®;
可以用函数 f(x) = | fract(x/size - 0.5) - 0.5 | 表示
可得,f(x)的周期是size, f(x)函数相当于在fract(x)函数的基础上向右和向上平移了0.5个单位。
这篇关于threejs-无限网格InfiniteGridHelper的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!