THREE.Sprite详解
问题背景
因为之前想修改sprite使得可以不面向屏幕,正常立起来和3D文字一样,对此研究了下THREE对这块的实现原理。
1.sprite_vert.glsl解析
uniform float rotation;
uniform vec2 center;//默认0.5,0.5
#include <common>
#include <uv_pars_vertex>
#include <fog_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
vec2 scale;
// modelMatrix is matrixWorld
//因为矩阵左上角到右下角是模型对象的scale控制参数
//这里拿到模型视图矩阵里面的scale.x
scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
//这里拿到模型视图矩阵里面的scale.y
scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
#ifndef USE_SIZEATTENUATION
bool isPerspective = isPerspectiveMatrix( projectionMatrix );
if ( isPerspective ) scale *= - mvPosition.z;
#endif
//计算得到sprite包括中心点,其他点的坐标(相对的),下面才计算才最终坐标
//center默认传的是0.5,0.5
// position坐标是下面的结构,一个半径0.5的正方形
//var float32Array = new Float32Array( [
// - 0.5, - 0.5, 0, 0, 0,
// 0.5, - 0.5, 0, 1, 0,
// 0.5, 0.5, 0, 1, 1,
// - 0.5, 0.5, 0, 0, 1
//] );
vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;
// 下面是利用传入的uniform float rotation进行旋转变换
vec2 rotatedPosition;
rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y; //默认rotation=0,坐标还是alignedPosition.x
rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y; ////默认是alignedPosition.y
mvPosition.xy += rotatedPosition;//计算得到所有点的相机空间坐标
gl_Position = projectionMatrix * mvPosition; //投影坐标系坐标
}