返回

在 GLSL 中使用纹理和颜色进行纹理颜色调和

IOS





### 纹理颜色调和
在上一节中,我们讨论了如何使用纹理来给模型填充纹理。但是,在许多场景中,纹理并不是单调的,而是需要结合模型本身的固有颜色进行渲染。这就是纹理颜色调和所要达到的目标。

纹理颜色调和是将纹理和模型本身的颜色结合起来形成最终的颜色。可以通过在片段着色器中进行如下计算来轻松地进行纹理颜色调和:

finalColor = textureColor * baseColor;


`baseColor` 表示模型本身的固有颜色,`finalColor` 表示最终的颜色。

### GLSL 着色器示例
**顶点着色器** 

attribute vec4 a_position;
attribute vec2 a_texCoord;
uniform mat4 u_MVPMatrix;

varying vec2 v_texCoord;

void main() {
gl_Position = u_MVPMatrix * a_position;
v_texCoord = a_texCoord;
}


**片段着色器** 

precision mediump float;
uniform vec4 u_baseColor;
uniform bool u_blendEnable;
uniform bool u_invertColor;

uniform sampler2D u_sampler;

varying vec2 v_texCoord;

void main() {
vec4 texColor = texture2D(u_sampler, v_texCoord);
if (u_blendEnable == false) {
texColor.a = 1.0;
}
if (u_invertColor == true) {
texColor = vec4(1.0, 1.0, 1.0, 1.0) - texColor;
}
gl_FragColor = texColor * u_baseColor;
}


**在 Java 代码中使用** 

int baseColorLocation = GLES20.glGetUniformLocation(mProgram, "u_baseColor");
int colorBlendLocation = GLES20.glGetUniformLocation(mProgram, "u_blendEnable");
int invertColorLocation = GLES20.glGetUniformLocation(mProgram, "u_invertColor");

// 设置固有颜色
GLES20.glUniform4f(baseColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);

// 禁用纹理透明度,只使用颜色
GLES20.glUniform1i(colorBlendLocation, 0);

// 激活颜色反转
GLES20.glUniform1i(invertColorLocation, 1);


### 实际案例:多彩球体
我们使用一个带有丰富纹理的球体模型来演示纹理颜色调和的效果。球体模型是由经纬度生成的,并赋予其颜色属性。

**纹理加载** 

mSphere.setTexture(new Texture("res/raw/images/earth.png"));


**渲染片段** 

GLES20.glActiveProgram(mProgram);
...
mSphere.drawSelf(mModelMatrix);
...
GLES20.glFlush();


### 效果预览
在移动图形编程中,经常需要结合纹理和模型固有颜色来产生更加逼真和丰富的视觉表现。纹理颜色调和是这项技术的关键部分,可以通过在片段着色器中进行颜色插值计算来轻松地进行纹理颜色调和。

掌握纹理颜色调和技巧,可以为移动图形编程中的场景渲染带来无限可能性,创造出更加丰富、引人入胜的视觉体验。