【WebGL与Graphics的学习之路05】材质与纹理

前言:

这几天又把纹理的知识看了看,突然发现edge浏览器能实现纹理图片的加载(把我激动坏了,还以为必须要配置个本地服务器来解决跨域呢),后来看了其他人的opengl的笔记,了解到了材质这个功能,发现从纹理到材质的变化比较容易理解,于是我就决定把材质和纹理这两个功能放在一起写。

先上效果:

这个是贴上纹理并且把纹理所返回的rgb作为材质来影响三种光的效果。

两种坐标系统的对应关系:

首先是顶点着色器:

attribute vec2 a_TexCoord;
varying vec2 v_TexCoord;
 void main(void){
    v_TexCoord = a_TexCoord;    
}

片元着色器:

uniform sampler2D u_Sampler;
varying vec2 v_TexCoord;

    void main(void){
        ...
            float spec=0.0;
                if(nDotL >0.0){
                    spec=pow(dot(normal,halfvector),u_shininess);//镜面光强
                }
                vec3 specular = u_shininessColor * (spec * vec3(texture2D(u_Sampler, v_TexCoord)));
                vec3 diffuse = u_LightColor * nDotL * vec3(texture2D(u_Sampler, v_TexCoord));
                vec3 ambient = u_AmbientLight * vec3(texture2D(u_Sampler, v_TexCoord));
                gl_FragColor = vec4(diffuse + ambient + specular,1.0);
}

顶点着色器用来接受来自缓冲区的纹理坐标,通过varying传递,片元着色器接收内插后的纹理坐标。texture2D()获取纹理像素颜色

u_Sampler即为纹理图像

缓冲区设置纹理坐标(注意要与顶点坐标相对应):

//纹理坐标
    var texCoords = new Float32Array([
        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,1.0,0.0,0.0,0.0,0.0,1.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,
    ]);

配置和加载纹理:

function initTextures(gl){
    let texture = gl.createTexture();//创建纹理对象
    
    let u_Sampler = gl.getUniformLocation(gl.program,'u_Sampler');//拿到u_Sampler的存储位置
    
    let image = new Image();//new一个对象来放图片
    
    image.onload = function(){
        loadTexture(gl,texture,u_Sampler,image)
    } // 该步为异步加载图像
    image.src = './texture/砖墙.jpg';
    return true;
}

为WEBGL配置纹理:

function loadTexture(gl,texture,u_Sampler,image){
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);  // 反转Y轴,因为图片坐标系Y轴向下
    // 激活纹理
    gl.activeTexture(gl.TEXTURE0);
    // 绑定纹理
    gl.bindTexture(gl.TEXTURE_2D, texture);
    
    // 设置纹理参数
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    // 将纹理图像分配给纹理对象
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
    
    //把0号纹理单元传递给片元着色器
    gl.uniform1i(u_Sampler, 0);
}

关于纹理参数的设置内容这里不涉及

接下来是关于材质的内容了。现在回看一下片元着色器中三种光的设置,以纹理做为材质

    vec3 specular = u_shininessColor * (spec * vec3(texture2D(u_Sampler, v_TexCoord)));
    vec3 diffuse = u_LightColor * nDotL * vec3(texture2D(u_Sampler, v_TexCoord));
    vec3 ambient = u_AmbientLight * vec3(texture2D(u_Sampler, v_TexCoord));

单材质:

     vec3 specular = u_shininessColor * (spec * material.specular);
     vec3 diffuse = u_LightColor * nDotL * material.diffuse;
     vec3 ambient = u_AmbientLight * material.ambient;

对比一下你就明白了。这里的材质可以理解为就是用光照来设置物体的颜色。实际是对不同物体表面材质来设置三种光的效果。

翡翠材质效果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值