玩转WebGL(八)立方体纹理

463 阅读1分钟

纹理映射

步骤:

  • 准备纹理图像
  • 配置集合图形纹理映射方式
  • 加载和配置纹理图像
  • 从纹理中抽出纹素赋给片元

纹理坐标

就是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹素颜色,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);