gpt4 book ai didi

javascript - 支持着色和纹理的 GLSL 着色器

转载 作者:行者123 更新时间:2023-11-30 11:48:25 30 4
gpt4 key购买 nike

我正在尝试编写一个同时支持颜色和纹理的着色器。
出于某种原因,我可以让它工作。
没有抛出任何错误,并且它们中的每一个都可以完美地单独工作,

获取位置:

shaderProgram.useTextureUniform = gl.getUniformLocation(shaderProgram, "uUseTexture");

绘制时我会像这样更改值:

    var uUseTexture=false;
gl.uniform1f(shaderProgram.useTextureUniform, uUseTexture);

还有 GLSL 本身:

片段:

precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
varying vec4 vColor;
uniform bool uUseTexture;
void main(void) {
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
vec4 texColor = vec4(textureColor.rgb, textureColor.a);
vec4 vertexColor = vColor;
if (!uUseTexture){
gl_FragColor = vertexColor;
}
else{
gl_FragColor = texColor;
}
}

顶点:

    attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
attribute vec4 aVertexColor;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;

varying vec2 vTextureCoord;
varying vec4 vColor;


void main(void){
vec4 mvPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * mvPosition;
vTextureCoord = aTextureCoord;
vColor = aVertexColor;}

最佳答案

在我告诉你如何让你的着色器工作之前,你可能不应该那样做。你应该

  1. 制作 2 个着色器

    制作一个使用纹理的着色器和一个使用顶点颜色的不同着色器。这几乎是所有专业游戏引擎都会做的。

  2. 制作一个将两种颜色相乘并将一种颜色设置为白色的着色器

    如果你有

    gl_FragColor = vertexColor * textureColor;

    然后如果 textureColor1,1,1,1 那意味着你要乘以 1所以结果就是 vertexColor。同样,如果 vertexColor1,1,1,1 然后你乘以 1 所以结果就是纹理颜色

    只需制作一个像素的白色纹理就可以获得白色纹理

    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA,
    gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255, 255]));

    然后任何时候你只希望顶点颜色将该纹理绑定(bind)到纹理单位并告诉采样器你把它放在哪个单位

    您可能还想关闭纹理坐标

    gl.disableVertexAttribArray(texcoordLocation);

    当你只想要纹理颜色时,你可以这样做

    // turn off the attribute
    gl.disableVertexAttribArray(aVertexColorLocation);

    // set the attribute's constant value
    gl.vertexAttrib4f(aVertexColorLocation, 1, 1, 1, 1);

    此方法还有一个额外的好处,即您还可以同时使用纹理颜色和顶点颜色来修改纹理颜色或为纹理颜色着色。许多游戏引擎也会专门这样做,以利用这种混合颜色的能力。

  3. Pauli 提到了另一种选择,即使用 mix

    uniform float u_mixAmount;

    gl_FragColor = mix(textureColor, vertexColor, u_mixAmount);

    这也可行,因为您可以在需要时将 u_mixAmount 设置为 0.0textureColor 和 1.0 当你想要 vertexColor 但不像你的 bool 示例,您还可以在具有值的 2 种颜色之间淡入淡出在 0.0 和 1.0 之间。例如 0.3 是 vertexColor 的 30% 和 70%textureColor

一些其他的东西

这一行

vec4 texColor = vec4(textureColor.rgb, textureColor.a);

没有什么不同

vec4 texColor = textureColor;

只是尝试您的着色器,它似乎按原样工作,这表明问题不是您的着色器,而是您代码的其他部分。

var gl = document.querySelector("canvas").getContext("webgl");
var m4 = twgl.m4;

var arrays = {
aVertexPosition: [
-1, -1, 0,
1, -1, 0,
-1, 1, 0,
1, 1, 0,
],
aVertexNormal: [
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
],
aTextureCoord: [
0, 0,
1, 0,
0, 1,
1, 1,
],
aVertexColor: [
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
1, 0, 1, 1,
],
indices: [
0, 1, 2,
2, 1, 3,
],
};

var tex = twgl.createTexture(gl, {
format: gl.LUMINANCE,
mag: gl.NEAREST,
src: [224, 64, 128, 192],
});
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
var programInfo = twgl.createProgramInfo(gl, ['vs', 'fs']);
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
for (var i = 0; i < 2; ++i) {
twgl.setUniforms(programInfo, {
uMVMatrix: m4.identity(),
uPMatrix: m4.scale(m4.translation([i === 0 ? -0.5 : 0.5, 0, 0]), [0.5, 1, 1]),
uNMatrix: m4.identity(),
uSampler: tex,
uUseTexture: i === 1,
});
twgl.drawBufferInfo(gl, bufferInfo);
}
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/2.x/twgl-full.min.js"></script>
<script id="fs" type="not-js">
precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
varying vec4 vColor;
uniform bool uUseTexture;
void main(void) {
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
vec4 texColor = vec4(textureColor.rgb, textureColor.a);
vec4 vertexColor = vColor;
if (!uUseTexture){
gl_FragColor = vertexColor;
}
else{
gl_FragColor = texColor;
}
}
</script>
<script id="vs" type="not-js">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
attribute vec4 aVertexColor;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;

varying vec2 vTextureCoord;
varying vec4 vColor;


void main(void){
vec4 mvPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * mvPosition;
vTextureCoord = aTextureCoord;
vColor = aVertexColor;}
</script>
<canvas></canvas>

关于javascript - 支持着色和纹理的 GLSL 着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40202354/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com