纹理映射
步骤:
- 准备纹理图像
- 配置集合图形纹理映射方式
- 加载和配置纹理图像
- 从纹理中抽出纹素赋给片元
纹理坐标
就是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹素颜色,webgl系统中的纹理坐标是二维的。
设置纹理坐标:
private texCoords = [
1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0
]
// uv
let texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.texCoords), gl.STATIC_DRAW);
gl.vertexAttribPointer(texcoordLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texcoordLoc);
顶点着色器
attribute vec4 a_position;
uniform mat4 u_worldViewProjection;
attribute vec4 aVertexColor;
//法向量的变量
attribute vec3 a_normal;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying lowp vec4 vColor;
//将法向量从顶点着色器传递到片元着色器的变量
varying lowp vec3 v_normal;
varying lowp vec3 v_fragpos;
attribute vec2 a_TexCoord;
varying vec2 v_TexCoord;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * a_position;
vColor = aVertexColor;
v_normal = mat3(uModelViewMatrix) * a_normal;
v_fragpos = vec3(uModelViewMatrix * a_position);
v_TexCoord = a_TexCoord;
}
片段着色器
precision mediump float;
varying lowp vec3 v_normal;
//方向光的方向
uniform lowp vec3 u_light;
//方向观察者的坐标
uniform lowp vec3 u_eyePos;
//方向光的颜色
uniform lowp vec3 u_lightColor;
varying lowp vec3 v_fragpos;
varying vec2 v_TexCoord;
uniform sampler2D u_Sampler;
void main() {
vec3 normal = normalize(v_normal);
gl_FragColor = texture2D(u_Sampler, v_TexCoord);
// 环境光照
vec3 ambientLight = gl_FragColor.rgb * u_lightColor * 0.4;
// 漫反射光照
float light = max(dot(normal, u_light), 0.0);
vec3 diffuseLight = gl_FragColor.rgb * light;
// 高光
float specularStrength = 0.8;
vec3 eyeDir = normalize(u_eyePos - v_fragpos);
vec3 reflectDir = reflect(-u_light, normal);
float spec = pow(max(dot(eyeDir, reflectDir), 0.0), 32.0);
vec3 specular = specularStrength * spec * u_lightColor;
vec3 specularLight = gl_FragColor.rgb * specular;
gl_FragColor.rgb = ambientLight + diffuseLight + specularLight;
}
创建纹理
let texcoordLoc = gl.getAttribLocation(program, "a_TexCoord")
let sampler = gl.getUniformLocation(program, 'u_Sampler');
// 纹理
let texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);// 绑定纹理对象到激活的纹理单元
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);// 纹理放大方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);// 纹理缩小方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);// 纹理水平填充方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);// 纹理垂直填充方式
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this._image);
gl.uniform1i(sampler, 0);