gpt4 book ai didi

javascript - 从 Javascript 将颜色传递给片段着色器

转载 作者:行者123 更新时间:2023-12-02 09:36:05 25 4
gpt4 key购买 nike

我目前正在学习 webgl 并且有一个问题。我正在尝试制作一个三 Angular 形并将颜色信息从 js 文件传递​​到片段着色器。以下是我的js代码:

var VSHADER_SOURCE = 
'attribute vec4 a_Position;\n'+
'attribute vec4 a_Color;\n'+
'varying vec4 v_Color;\n'+
'void main(){\n'+
'gl_Position = a_Position;\n'+
'v_Color = a_Color;\n'+
'}\n';


var FSHADER_SOURCE =
'precision highp float;\n'+
'varying vec4 v_Color;\n'+
'void main() {\n'+
'gl_FragColor = v_Color;\n'+
'}\n';

function main(){
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
if(!gl){
console.log('Error!');
return;
}
//Init shaders.
if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)){
console.log('Error!');
return;
}
var vertices = new Float32Array([-0.8, -0.8, 0.8, -0.8, 0.0, 0.8]);
var color = new Float32Array([0.0, 0.0, 1.0, 1.0]);
var buffer_object = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_object);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

var color_object = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, color_object);
gl.bufferData(gl.ARRAY_BUFFER, color, gl.STATIC_DRAW);
var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Color);

gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);


return 0;
}

这必须创建一个蓝色三 Angular 形,但我唯一看到的是一个充满黑色的 Canvas 。谁能告诉我缺少什么??我创建了两个缓冲区对象,一个用于顶点,另一个用于颜色。

最佳答案

你的例子有很多问题,但是......具体问题。

您只为第一个顶点提供颜色。

你有 3 个顶点,但只有 1 种颜色。你应该得到一个错误。您是否检查过 JavaScript 控制台是否有错误?

你有 3 个选项来解决这个问题

  1. 为每个顶点提供颜色

    new Float32Array([
    0.0, 0.0, 1.0, 1.0,
    0.0, 0.0, 1.0, 1.0,
    0.0, 0.0, 1.0, 1.0,
    ]);
  2. 关闭 a_Color 属性并提供一个常量值

    gl.disableVertexAtttibArray(a_Color);
    gl.vertexAttrib4f(a_Color, 0, 0, 1, 1);
  3. 使用统一而不是属性+变化

    删除所有对 a_Colorv_color 的引用,取而代之的是你的片段着色器是

    precision highp float;
    uniform vec4 u_Color;
    void main() {
    gl_FragColor = u_Color;
    }

    现在你可以设置颜色

    在初始化时

    // Lookup the location
    var u_colorLocation = gl.getUniformLocation(program, "u_Color");

    在渲染时

    // Set the uniform
    gl.uniform4f(u_colorLocation, 0, 0, 1, 1);

如果您选择 #2,您可能会遇到另一个问题,即您会收到一条警告,指出 attirbute 0 未启用,因为至少在我的计算机上,a_Color 已分配给属性 0 . 关闭它意味着必须模拟它,这很慢。解决方案是通过调用 gl.bindAttribLocation 链接程序来确保 a_Position 位于属性 0 中。

其他问题:

您的 initShader 函数显然正在创建一个程序并将其附加到 WebGLRenderContext (gl.program)。大多数 WebGL 项目都有许多着色器程序,因此最好只返回程序。换句话说,而不是

initShader(...);
gl.getAttribLocation(gl.program, ...)

你可能想要

var program = initShader(...);
gl.getAttribLocation(program, ...)

您需要修复 initShader,以便它返回创建的程序,而不是将其破解到 WebGLRenderingContext。

您还使用了 precision highp float。这在很多手机上都行不通。除非您确定需要 highp,否则最好使用 mediump

关于javascript - 从 Javascript 将颜色传递给片段着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26134077/

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