# 1. 变换前物体的绘制

``````float box(vec3 st){
float right = 0.15;
float top = 0.1;
float blur = 0.002;//边缘模糊系数

//通过右上角绘制原点对称的四边形
vec2 bl = 1.0-smoothstep(vec2(right,top)-blur,vec2(right,top)+blur,abs(st.xy));
float pct = bl.x * bl.y;
return pct;
}
``````

# 2. 物体旋转的实现

`````` mat3 rotate2d(float _angle){
return mat3(cos(angle),-sin(angle),0.0,
sin(angle),cos(angle),0.0,
0.0,0.0,1.0
);
}
``````

``````void main( void ) {

//窗口坐标调整为[-1,1],坐标原点在屏幕中心
vec2 _st = (gl_FragCoord.xy * 2. - u_resolution) / u_resolution.y;

vec3 line_color = vec3(1.0,1.0,0.0);
vec3 color = vec3(0.6);//背景色
float pct = 0.0;

//将屏幕坐标转为三维坐标，使之在和矩阵相乘时相匹配
vec3 st = vec3(_st,1.0);

//使用旋转矩阵使矩形顺时针旋转10度
st *= rotate2d(10.0);

pct = box(st);
color = mix(color,line_color,pct);

gl_FragColor = vec4(color, 1);
}
``````

``````st *= rotate2d(-10.0);
``````

``````st *= rotate2d(u_time*30.0);
``````

# 3. 物体缩放的实现

``````mat3 scale2d(vec2 scale){
//缩放矩阵作用于坐标系，所以放大和缩小刚好相反，为了使用习惯，缩放参数取倒数
return mat3(1.0/scale.x,0.0,0.0,
0.0,1.0/scale.y,0.0,
0.0,0.0,1.0
);
}
``````

``````st *= scale2d(vec2(2.0,4.0));
``````

# 4. 物体平移的实现

``````mat3 translation2d(vec2 translate){
//平移矩阵作用于坐标系，所以平移的方向相反，为了使用习惯，缩放参数取负
return mat3(1.0,0.0,-translate.x,
0.0,1.0,-translate.y,
0.0,0.0,1.0
);
}
``````

``````st *= translation2d(vec2(0.2,0.4));
``````

``````st *= translation2d(vec2(0.0,sin(u_time)*0.5));
``````

``````st *= translation2d(vec2(cos(u_time)*0.5,sin(u_time)*0.5));
``````

``````st *= rotate2d(u_time*30.0);
st *= translation2d(vec2(cos(u_time)*0.5,sin(u_time)*0.5));
``````

# 5. 平移与缩放另外一种实现方式

``````//非矩阵的放大缩小方式
//st *=3.0;//屏幕坐标放大3倍，相当于物体缩小3倍
//st /=3.0;//屏幕坐标缩小3倍，相当于物体放大3倍

//非矩阵的平移方式
//st.x -=0.2;//物体向右移0.2个单位
//st -=0.4;//物体向右向上移0.4个单位
//st.x +=0.3;//物体向左移0.3个单位
``````

# 6. 所有示例代码

``````<body>
<div id="container"></div>
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
<script>
var container;
var camera, scene, renderer;
var uniforms;
void main() {
gl_Position = vec4( position, 1.0 );
}
`
#ifdef GL_ES
precision mediump float;
#define sat(x) clamp(x, 0.0, 1.0)
#endif
uniform float u_time;
uniform vec2 u_mouse;
uniform vec2 u_resolution;

mat3 rotate2d(float _angle){
return mat3(cos(angle),-sin(angle),0.0,
sin(angle),cos(angle),0.0,
0.0,0.0,1.0
);
}

mat3 scale2d(vec2 scale){
//缩放矩阵作用于坐标系，所以放大和缩小刚好相反，为了使用习惯，缩放参数取倒数
return mat3(1.0/scale.x,0.0,0.0,
0.0,1.0/scale.y,0.0,
0.0,0.0,1.0
);
}

mat3 translation2d(vec2 translate){
//平移矩阵作用于坐标系，所以平移的方向相反，为了使用习惯，缩放参数取负
return mat3(1.0,0.0,-translate.x,
0.0,1.0,-translate.y,
0.0,0.0,1.0
);
}

float box(vec3 st){
float right = 0.15;
float top = 0.1;
float blur = 0.002;//边缘模糊系数

//通过右上角绘制原点对称的四边形
vec2 bl = 1.0-smoothstep(vec2(right,top)-blur,vec2(right,top)+blur,abs(st.xy));
float pct = bl.x * bl.y;
return pct;
}

void main( void ) {

//窗口坐标调整为[-1,1],坐标原点在屏幕中心
vec2 _st = (gl_FragCoord.xy * 2. - u_resolution) / u_resolution.y;

//窗口坐标调整为[0,1],坐标原点在屏幕左下角
//vec2 st = gl_FragCoord.xy/u_resolution;

vec3 line_color = vec3(1.0,1.0,0.0);
vec3 color = vec3(0.6);//背景色
float pct = 0.0;

//将屏幕坐标转为三维坐标，使之在和矩阵相乘时相匹配
vec3 st = vec3(_st,1.0);

//使用旋转矩阵使矩形顺时针旋转10度
//st *= rotate2d(10.0);

//st *= rotate2d(u_time*30.0);

//缩放
//st *= scale2d(vec2(2.0,4.0));

//平移
//st *= translation2d(vec2(0.2,0.4));
//st *= translation2d(vec2(0.0,sin(u_time)*0.5));
//st *= translation2d(vec2(cos(u_time)*0.5,sin(u_time)*0.5));

//非矩阵的放大缩小方式
//st *=3.0;//屏幕坐标放大3倍，相当于物体缩小3倍
//st /=3.0;//屏幕坐标缩小3倍，相当于物体放大3倍

//非矩阵的平移方式
//st.x -=0.2;//物体向右移0.2个单位
//st -=0.4;//物体向右向上移0.4个单位
//st.x +=0.3;//物体向左移0.3个单位

pct = box(st);
color = mix(color,line_color,pct);

gl_FragColor = vec4(color, 1);
}
`

init();
animate();

function init() {
container = document.getElementById('container');

camera = new THREE.Camera();
camera.position.z = 1;

scene = new THREE.Scene();

var geometry = new THREE.PlaneBufferGeometry(2, 2);

uniforms = {
u_time: {
type: "f",
value: 1.0
},
u_resolution: {
type: "v2",
value: new THREE.Vector2()
},
u_mouse: {
type: "v2",
value: new THREE.Vector2()
}
};

uniforms: uniforms,
});

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

renderer = new THREE.WebGLRenderer();
//renderer.setPixelRatio(window.devicePixelRatio);

container.appendChild(renderer.domElement);

onWindowResize();

document.onmousemove = function (e) {
uniforms.u_mouse.value.x = e.pageX
uniforms.u_mouse.value.y = e.pageY
}
}

function onWindowResize(event) {
renderer.setSize(800, 800);
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}

function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
uniforms.u_time.value += 0.02;
renderer.render(scene, camera);
}
</script>
</body>
``````