WebGL颜色与纹理

WEBGL中的着色器变量包括以下种类:

  • 属性变量(Attribute Variables):这些变量用于接收从应用程序中传递的顶点数据,比如顶点位置和颜色,是只读的不可修改。
  • 统一变量(Uniform Variables):这些变量是着色器中的全局变量,用于接收从应用程序中传递的值,比如投影矩阵,旋转矩阵等。
  • 纹理坐标变量(Texture Coordinate Variables):这些变量用于指定在纹理图像中采样的位置。
  • 法线向量变量(Normal Vector Variables):这些变量用于计算光照效果,用于标识几何体表面的法向量。
  • 输出变量(Output Variables):这些变量用于将着色器的输出传递给渲染管线的下一阶段,比如像素着色器的颜色值。

一、varying变量

1.varying变量定义

在WebGL中,varying变量是在顶点着色器和片元着色器之间传递数据的一种特殊类型的变量。它们被用于在顶点着色器和片元着色器之间传递信息,以便在渲染过程中进行插值。在顶点着色器中,varying变量的值被计算并传递到片元着色器中,然后在片元着色器中进行插值,然后被用来确定要绘制的像素的颜色。

Varying变量通常被用于将光照和纹理坐标等信息从顶点着色器传递到片元着色器中。由于它们是在渲染过程中插值的,所以它们可以用来创建平滑的过渡,使得渲染出来的图像更加真实和细腻。

例如,如果你想在三角形中使用纹理映射,那么你需要将纹理坐标从顶点着色器传递到片元着色器中。你可以通过定义一个varying变量来传递这个纹理坐标,然后在片元着色器中使用它来获取纹理的颜色,从而创建一个真实的纹理映射效果。

2.varying执行流程

在WebGL中,varying变量用于在顶点着色器和片元着色器之间传递数据。它们的执行原理如下:

  1. 在顶点着色器中声明一个varying变量,并对其进行赋值。
  2. 这个varying变量的值会被传递到片元着色器中。
  3. 在片元着色器中,可以通过读取这个varying变量的值来进行后续的计算。
  4. 由于每个像素都会执行片元着色器,因此varying变量的值也会被相应地插值,以便在不同像素之间进行平滑的过渡。
  5. 最终的像素颜色将由片元着色器中的计算结果和其他因素(如光照)共同决定。

varying变量的执行原理是通过在顶点着色器和片元着色器之间传递数据,使得像素颜色可以根据这些数据进行计算。
在这里插入图片描述

3.使用varying绘制彩色三角形

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>varying变量</title>
    <script src="../../lib/index.js"></script>
    <style>
        * {
     
     
            margin: 0;
            padding: 0;
        }

        canvas {
     
     
            margin: 50px auto 0;
            display: block;
            background: yellow;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="400" height="400">
        此浏览器不支持webGL
    </canvas>
</body>
</html>

<script>
    const ctx = document.getElementById('canvas')

    const gl = ctx.getContext('webgl');

    //着色器
    //创建着色器源码
    const VERTEX_SHADER_SOURCE = `
        attribute vec4 aPosition;
        //需要同时在顶点和片元着色器中声明,将数据从顶点着色器传递到片元着色器
        varying vec4 vColor;
        void main(){
            vColor = aPosition;
            //要绘制的坐标
            gl_Position = aPosition;
            //要绘制的大小(着色器变量使用的是浮点型)
            gl_PointSize = 10.0;
        }
    `; //顶点着色器

    const FRAGMENT_SHADER_SOURCE = `
        precision lowp float;
        varying vec4 vColor;
        void main(){
            //要绘制的颜色
            gl_FragColor = vColor;
        }
    `; //片元着色器

    const program =  initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
    const aPosition = gl.getAttribLocation(program, 'aPosition')

    
    const points = new Float32Array([
        -0.5,-0.5,
        0.5
<think>我们正在讨论WebGL中的纹理坐标使用方法。纹理坐标是用于将纹理映射到几何图形上的2D坐标系统。在WebGL中,纹理坐标通常表示为(s,t),其中s和t的范围是0.0到1.0。纹理坐标的原点(0,0)在纹理图像的左下角,而(1,1)在右上角(注意:在WebGL中,默认纹理坐标原点在左下角,但图像数据加载时可能会被翻转,因为图像数据的原点通常在左上角,因此有时需要调整)。纹理坐标通常在顶点着色器中为每个顶点指定,然后在片段着色器中进行插值,以确定每个片段(像素)在纹理上的位置。步骤:1.创建纹理:使用WebGLAPI创建纹理对象并设置参数(如过滤方式、环绕模式等)。2.加载图像数据:将图像数据加载到纹理对象中。3.指定纹理坐标:在顶点数据中,除了位置坐标,还需要为每个顶点指定纹理坐标。4.在着色器中使用:顶点着色器接收纹理坐标并传递给片段着色器,片段着色器使用纹理坐标从纹理中采样颜色。下面是一个简单的示例,展示如何在WebGL中使用纹理坐标绘制一个带有纹理的矩形。首先,我们定义顶点数据(位置和纹理坐标):```javascript//顶点位置和纹理坐标constvertices=newFloat32Array([//位置坐标(x,y)纹理坐标(s,t)-0.5,-0.5,0.0,0.0,//左下角0.5,-0.5,1.0,0.0,//右下角-0.5,0.5,0.0,1.0,//左上角0.5,0.5,1.0,1.0//右上角]);```然后,创建缓冲区并绑定数据。在顶点着色器中,我们接收位置和纹理坐标,并将纹理坐标传递给片段着色器:```glslattributevec4a_position;attributevec2a_texCoord;varyingvec2v_texCoord;voidmain(){gl_Position=a_position;v_texCoord=a_texCoord;}```在片段着色器中,我们使用纹理坐标从纹理中采样:```glslprecisionmediumpfloat;uniformsampler2Du_texture;varyingvec2v_texCoord;voidmain(){gl_FragColor=texture2D(u_texture,v_texCoord);}```在JavaScript中,我们需要设置纹理:```javascript//创建纹理consttexture=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,texture);//设置纹理参数(环绕和过滤方式)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.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);//加载图像constimage=newImage();image.onload=function(){gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,image);//在图像加载完成后进行绘制render();};image.src='texture.jpg';```注意:由于图像加载是异步的,所以需要在图像加载完成后进行绘制。另外,关于纹理坐标的方向问题:图像数据在内存中通常是从上到下存储的(即第一行在顶部),而WebGL纹理坐标默认原点在左下角。因此,如果直接使用,图像会上下颠倒。有两种解决方法:1.在加载纹理时翻转图像的Y轴:使用`gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);`在调用`texImage2D`之前。2.在纹理坐标中翻转t坐标(例如,使用1.0-t)。通常,第一种方法更常见。以上是WebGL纹理坐标的基本使用方法。相关问题:1.如何在WebGL中处理纹理坐标的翻转问题?2.WebGL纹理的环绕模式有哪些,如何设置?3.如何实现多重纹理(使用多个纹理)?4.纹理过滤方式有哪些,它们有什么区别?5.如何为3D模型设置纹理坐标?</think>### WebGL纹理坐标使用方法详解 在WebGL中,纹理坐标是将2D纹理图像映射到3D几何体表面的关键机制。纹理坐标系统使用归一化的$(s, t)$坐标系(有时也称$(u, v)$),范围从$(0.0, 0.0)$到$(1.0, 1.0)$,其中: - $(0.0, 0.0)$ 对应纹理左下角 - $(1.0, 1.0)$ 对应纹理右上角 - $(0.5, 0.5)$ 对应纹理中心 #### 核心使用步骤: 1. **定义顶点纹理坐标** ```javascript // 矩形顶点数据:位置(x,y) + 纹理坐标(s,t) const vertices = new Float32Array([ // 左下角 -0.5, -0.5, 0.0, 0.0, // 右下角 0.5, -0.5, 1.0, 0.0, // 左上角 -0.5, 0.5, 0.0, 1.0, // 右上角 0.5, 0.5, 1.0, 1.0 ]); ``` 2. **顶点着色器传递坐标** ```glsl attribute vec4 a_position; attribute vec2 a_texCoord; varying vec2 v_texCoord; void main() { gl_Position = a_position; v_texCoord = a_texCoord; // 传递到片段着色器 } ``` 3. **片段着色器采样纹理** ```glsl precision mediump float; uniform sampler2D u_texture; varying vec2 v_texCoord; void main() { // 使用纹理坐标采样颜色 gl_FragColor = texture2D(u_texture, v_texCoord); } ``` 4. **JavaScript纹理设置** ```javascript // 创建纹理对象 const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); // 设置纹理参数 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); // 加载图像数据 const image = new Image(); image.onload = () => { gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); render(); }; image.src = "texture.jpg"; ``` #### 关键配置参数: 1. **环绕模式**: - `gl.REPEAT`:默认模式,超出部分重复纹理 - `gl.CLAMP_TO_EDGE`:超出部分拉伸边缘像素 - `gl.MIRRORED_REPEAT`:镜像重复 2. **过滤方式**: - `gl.NEAREST`:最近邻采样(像素化效果) - `gl.LINEAR`:双线性插值(平滑效果) - Mipmap模式:`gl.LINEAR_MIPMAP_LINEAR` #### 常见问题解决: - **图像翻转问题**:WebGL纹理坐标原点在左下角,而图片数据原点通常在左上角。解决方法: ```javascript gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // 垂直翻转图像 ``` - **非2次幂纹理**:非$2^n$尺寸纹理需设置: ```javascript 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.texSubImage2D`更新部分纹理 - **渲染到纹理**:帧缓冲区对象(FBO)生成动态纹理 [^1]: WebGL中`gl_FragCoord`内置变量提供标准化坐标信息 [^2]: WebGL纹理操作涉及`createTexture`, `texImage2D`等核心API
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上生花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值