200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > threejs 纹理流动_Threejs多重纹理与过程纹理实现

threejs 纹理流动_Threejs多重纹理与过程纹理实现

时间:2020-01-18 02:38:27

相关推荐

threejs 纹理流动_Threejs多重纹理与过程纹理实现

Author--------------- Yen

多数时候同一图元是采用单一纹理,但是为了增强显示效果,会存在同一图元多个纹理图的情况,效果比如只有灯光照射的时候才会显示其他图案,其他没有被照射到的地方显示正常灰色,边缘区域是平滑过渡的。这样就为图案的显隐更加增添一丝神秘气息,效果如下:

1)对同一个图元采用多幅纹理图,这种技术称为多重纹理。

2)在多重纹理变化的边界根据某种规则进行平滑过渡效果,这种技术称为过程纹理。

这种平滑过渡在很多情况下都会用到,如有的时候白天黑夜不同图片的过渡,还有丘陵地形中根据不同海拔不同的纹理进行过渡。

具体实现核心代码如下:

自定义材质ShaderMaterial

var textureLoader = new THREE.TextureLoader();

// 需要增加的纹理贴图 var map = textureLoader.load( "textures/sprites/timg.jpg" );

// 自定义材质 var material = new THREE.ShaderMaterial({

uniforms: THREE.UniformsUtils.merge([

mon,

THREE.UniformsLib.specularmap,

THREE.UniformsLib.envmap,

THREE.UniformsLib.aomap,

THREE.UniformsLib.lightmap,

THREE.UniformsLib.emissivemap,

THREE.UniformsLib.bumpmap,

THREE.UniformsLib.normalmap,

THREE.UniformsLib.displacementmap,

THREE.UniformsLib.gradientmap,

THREE.UniformsLib.fog,

THREE.UniformsLib.lights,

{

emissive: { value: new THREE.Color( 0x000000 ) },

specular: { value: new THREE.Color( 0x111111 ) },

shininess: { value: 30 },

map: { value: undefined }

}

]),

vertexShader: THREE.ShaderChunk.meshphong_vert,

fragmentShader: THREE.ShaderChunk.meshphong_frag

});

material.lights = true;

material.uniforms.map.value = map;

var geometry = new THREE.PlaneBufferGeometry( 300, 200 );

var mesh = new THREE.Mesh( geometry, material );

其中比较重要的是修改THREE.ShaderChunk.meshphong_frag的源码(..src\renderers\shaders\ShaderLib\meshphong_frag.glsl.js),修改的核心代码:

// yen 增加的变量定义varying vec2 vUv; // 记得对应的顶点着色器中也要增加UVfloat vIntensity;

uniform sampler2D map;

......

// yen vec4 mapColor = texture2D(map, vec2(vUv.x, vUv.y));

if (vIntensity > 0.21) {

// 光照强度大于0.21时候显示添加的纹理 gl_FragColor = vec4( vec3(mapColor.r, mapColor.g, mapColor.b), diffuseColor.a );

} else if (vIntensity < 0.05) {

// 相对较暗的地方显示之前纹理 gl_FragColor = vec4( outgoingLight, diffuseColor.a );

} else {

// 过渡区域按照百分比进行过渡 float t = (vIntensity - 0.05) / 0.16;

vec3 fragColor = t*vec3(mapColor.r, mapColor.g, mapColor.b) + (1.0-t) * outgoingLight;

gl_FragColor = vec4( fragColor, diffuseColor.a );

}

spotlight光照强度的计算

..src\renderers\shaders\ShaderChunk\lights_fragment_begin.glsl.js

#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )

SpotLight spotLight;

#pragma unroll_loop

for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {

spotLight = spotLights[ i ];

// getSpotDirectLightIrradiance( spotLight, geometry, directLight ); // 计算光照强度 vIntensity = getSpotDirectLightIntensity( spotLight, geometry, directLight);

getSpotDirectLightIrradiance( spotLight, geometry, directLight );

#ifdef USE_SHADOWMAP

directLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;

#endif

RE_Direct( directLight, geometry, material, reflectedLight );

}

#endif

光照计算函数:

..src\renderers\shaders\ShaderChunk\lights_pars_begin.glsl.js

// yen 计算强度,参数是spotlight,还有方向光directLight float getSpotDirectLightIntensity( const in SpotLight spotLight, const in GeometricContext geometry, in IncidentLight directLight ) {

float intensity = 0.0;

vec3 lVector = spotLight.position - geometry.position;

directLight.direction = normalize( lVector );

float lightDistance = length( lVector );

float angleCos = dot( directLight.direction, spotLight.direction );

if ( angleCos > spotLight.coneCos ) {

float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );

intensity = spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );

}

return intensity;

}

这样就大功告成了。

参考文章:

OpenGL ES 3.x游戏开发 上卷 吴亚峰 Sample7_5

BIM树洞

做一个静谧的树洞君

用建筑的语言描述IT事物;

用IT的思维解决建筑问题;

共建BIM桥梁,聚合团队。

本学习分享资料不得用于商业用途,仅做学习交流!!如有侵权立即删除!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。