我正在尝试创建3D webgl渲染,但我不知道为什么它不起作用。我正在使用webgl和glm。
我在c ++上有类似的代码,但是我试图在webGL上做同样的事情。
有人可以指导我解决这个问题吗?我没有任何错误,但是没有在画布内渲染。
这是我的.js文件,而我的html仅包含画布。
var gl; //
var canvas;
var gfx;
function start() {
canvas = document.getElementById("glcanvas");
gl = canvas.getContext('webgl2');
gfx = make_gfx();
gl.clearColor(0.9,0.9,0.8,1);
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.drawArrays(gl.LINES, 0, 6);
render();
//draw_text(0,0,0,"asd",0,0,0,0,0,0);
//gl.drawArrays(gl.TRIANGLES, 0, 3);
draw_line(10,10,10,100,100,100,0,0,255);
}
function make_gfx() {
var gfx = new GraphicState();
gfx.ctx = gl;
gfx.window = canvas;
gfx.shader = gl.createProgram();
// var vtx_shader = make_shader(gl.VERTEX_SHADER, "#version 330 es layout (location = 0) in vec3 pos;layout (location = 1) in vec2 tex_coord;out float _alpha;uniform mat4 model;uniform mat4 view;uniform mat4 projection;uniform int line;uniform float player_y;uniform float obj_y;void main(){if (line > 0) {gl_Position = projection * view * vec4(pos, 1.0f);_alpha = line / 255.0f;} else {gl_Position = projection * view * model * vec4(pos, 1.0f);_alpha = abs(player_y - obj_y) >= 3.0f ? 0.25f : 1.0f;}}");
// var pixel_shader = make_shader(gl.FRAGMENT_SHADER, "#version 330 es out vec4 FragColor; in float _alpha; uniform vec3 color; void main(){FragColor = vec4(color, _alpha);}");
var vtx_shader = make_shader(gl.VERTEX_SHADER, " #version 300 es \n" +
"\n" +
" " +
"in vec3 pos;\n" +
"in vec2 tex_coord;\n" +
"\n" +
" out float _alpha;\n" +
"\n" +
" uniform mat4 model;\n" +
" uniform mat4 view;\n" +
" uniform mat4 projection;\n" +
" uniform int line;\n" +
" uniform float player_y;\n" +
" uniform float obj_y;\n" +
"\n" +
" void main()\n" +
" {\n" +
" if (line > 0)\n" +
" {\n" +
" gl_Position = projection * view * vec4(pos, 1.0f);\n" +
" _alpha = float(line) / 255.0f;\n" +
" }\n" +
" else\n" +
" {\n" +
" gl_Position = projection * view * model * vec4(pos, 1.0f);\n" +
" _alpha = abs(player_y - obj_y) >= 3.0f ? 0.25f : 1.0f;\n" +
" }\n" +
" }"
);
var pixel_shader = make_shader(gl.FRAGMENT_SHADER,"#version 300 es\n" +
"\n" +
"precision highp float;\n " +
"out vec4 FragColor;\n" +
" in float _alpha;\n" +
" uniform vec3 color;\n" +
"\n" +
" void main()\n" +
" {\n" +
" FragColor = vec4(color, _alpha);\n" +
" }"
);
gl.attachShader(gfx.shader, vtx_shader);
gl.attachShader(gfx.shader, pixel_shader);
gl.linkProgram(gfx.shader);
if ( !gl.getProgramParameter( gfx.shader, gl.LINK_STATUS) ) {
var info = gl.getProgramInfoLog(gfx.shader);
alert('Could not compile WebGL program. \n\n' + info);
}
var vertices = [
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
0.5, -0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 0.0, 1.0,
0.5, -0.5, 0.5, 0.0, 0.0,
0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 1.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 1.0
];
gfx.vao = gl.createVertexArray();
gfx.vbo = gl.createBuffer();
gl.bindVertexArray(gfx.vao);
gl.bindBuffer(gl.ARRAY_BUFFER, gfx.vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(0,3,gl.FLOAT, false,5*4,0);
gl.vertexAttribPointer(1,2,gl.FLOAT, false,5*4,3*4);
gl.enableVertexAttribArray(0);
gl.enableVertexAttribArray(1);
gfx.line_vao = gl.createVertexArray();
gfx.line_vbo = gl.createBuffer();
gl.bindVertexArray(gfx.line_vao);
gl.bindBuffer(gl.ARRAY_BUFFER, gfx.line_vbo);
gl.vertexAttribPointer(0,3,gl.FLOAT, false,3*4,0);
gl.enableVertexAttribArray(0);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
var width = canvas.width;
var height = canvas.height;
resize_gfx(gfx, width, height);
return gfx;
}
function make_shader(type, shader) {
var handle = gl.createShader(type);
gl.shaderSource(handle, shader);
gl.compileShader(handle);
var success = gl.getShaderParameter(handle, gl.COMPILE_STATUS);
if (!success) {
var info = gl.getShaderInfoLog(handle);
alert(info);
}
return handle;
}
function resize_gfx(state,width,height) {
gl.viewport(0,0,width,height);
state.width = width;
state.height = height;
}
function GraphicState() {
var ctx;
var window;
var shader;
var vao;
var vbo;
var line_vao;
var line_vbo;
var width;
var height;
}
/*function draw_text(x, y, z , scale, txt, r, g, b, a, view, proj) {
var text = glt.createText();
glt.setText(text, txt);
glt.beginDraw();
glt.color(r/255.0,g/255.0,b/255.0,a/255.0);
glt.drawText3D(text, x, y, z, scale, view, proj);
glt.endDraw();
glt.deleteText(text);
}*/
function draw_line (x, y, z, to_x, to_y, to_z, r, g, b, a) {
var vertices = [
x,y,z,
to_x,to_y,to_z
];
gl.useProgram(gfx.shader);
gl.uniform1i(gl.getUniformLocation(gfx.shader, "line"), a);
gl.uniform3f(gl.getUniformLocation(gfx.shader,"color"),r/255.0,g/255.0,b/255.0);
gl.bindBuffer(gl.ARRAY_BUFFER,gfx.line_vbo);
gl.bindVertexArray(gfx.line_vao);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STREAM_DRAW);
gl.drawArrays(gl.LINES, 0, 2);
}
function get_forward_vec(pitch, yaw, pos) {
var elevation = glm.radians(-pitch);
var heading = glm.radians(yaw);
var forward_vec = glm.vec3(Math.cos(elevation) * Math.sin(heading), Math.sin(elevation), Math.cos(elevation) * Math.cos(heading));
return forward_vec;
}
function render() {
var projection = glm.perspective(glm.radians(75.0), gfx.width / gfx.height, 0.1, 2000.0);
projection = glm.scale(projection, glm.vec3(-1.0, 1.0, 1.0));
var player_y = 0.0;
var player_forward_vec;
//TODO get Player
player_y = 0;
var pitch = 0;
var yaw = 0;
var cam_at = glm.vec3(0, 0 + 1.5, 0);
player_forward_vec = get_forward_vec(pitch, yaw, cam_at);
//var cam_look = glm.vec3(11, 11 + 1.5, 11) + get_forward_vec(pitch, yaw, cam_at);
var sumx = cam_at.x + player_forward_vec.x;
var sumy = cam_at.y + player_forward_vec.y;
var sumz = cam_at.z + player_forward_vec.z;
var cam_look = glm.vec3(sumx,sumy,sumz);
var ls = glm.vec3(0.0, 1.0, 0.0);
var view = glm.lookAt(cam_at, cam_look, ls);
gl.useProgram(gfx.shader);
gl.uniform1f(gl.getUniformLocation(gfx.shader, "player_y"), player_y);
gl.uniformMatrix4fv(gl.getUniformLocation(gfx.shader, "projection"), false,projection.array);
gl.uniformMatrix4fv(gl.getUniformLocation(gfx.shader, "view"), false, view.array);
var at = glm.vec3(3, 2, 1);
var look = at + (get_forward_vec(0, 0, at) * 50.0);
look.y += 1.5;
draw_line(at.x, at.y, at.z, look.x, look.y, look.z, 0, 255, 0, 255);
}
function get_alpha_for_y (y1,y2) {
return Math.abs(y1 - y2) >= 3.0 ? 63 : 255;
}
start();
<canvas id="glcanvas"></canvas>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/glm-js.min.js"></script>
主要问题是此行
var look = at + (get_forward_vec(0, 0, at) * 50.0);
JavaScript不支持运算符重载。 glm-js表示要这样做[]
var look = at['+'](get_forward_vec(0, 0, at)['*='](50.0));
老实的glm-js对于JavaScript尤其是对于perf来说看起来非常可怕。
第二个问题是您没有查找属性位置,也没有分配任何属性,因此如果运行它,很幸运pos出现在位置0,颜色出现在位置1
也multiline template literals是你的朋友
此外,在询问调试问题时,还需要将代码制作为[[minimal
。有20到30行与您的问题无关的注释掉的代码而且,此外,制作2个着色器比拥有1个具有条件的着色器更常见var gl; //
var canvas;
var gfx;
function start() {
canvas = document.getElementById("glcanvas");
gl = canvas.getContext('webgl2');
gfx = make_gfx();
gl.clearColor(0.9,0.9,0.8,1);
gl.clear(gl.COLOR_BUFFER_BIT);
render();
draw_line(10,10,10,100,100,100,0,0,255);
}
function make_gfx() {
var gfx = new GraphicState();
gfx.ctx = gl;
gfx.window = canvas;
gfx.shader = gl.createProgram();
var vtx_shader = make_shader(gl.VERTEX_SHADER, `#version 300 es
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 tex_coord;
out float _alpha;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform int line;
uniform float player_y;
uniform float obj_y;
void main()
{
if (line > 0)
{
gl_Position = projection * view * vec4(pos, 1.0f);
_alpha = float(line) / 255.0f;
}
else
{
gl_Position = projection * view * model * vec4(pos, 1.0f);
_alpha = abs(player_y - obj_y) >= 3.0f ? 0.25f : 1.0f;
}
}
`);
var pixel_shader = make_shader(gl.FRAGMENT_SHADER,`#version 300 es
precision highp float;
out vec4 FragColor;
in float _alpha;
uniform vec3 color;
void main()
{
FragColor = vec4(color, _alpha);
}
`);
gl.attachShader(gfx.shader, vtx_shader);
gl.attachShader(gfx.shader, pixel_shader);
gl.linkProgram(gfx.shader);
if ( !gl.getProgramParameter( gfx.shader, gl.LINK_STATUS) ) {
var info = gl.getProgramInfoLog(gfx.shader);
alert('Could not compile WebGL program. \n\n' + info);
}
var vertices = [
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
0.5, -0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 0.0, 1.0,
0.5, -0.5, 0.5, 0.0, 0.0,
0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 1.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 1.0
];
gfx.vao = gl.createVertexArray();
gfx.vbo = gl.createBuffer();
gl.bindVertexArray(gfx.vao);
gl.bindBuffer(gl.ARRAY_BUFFER, gfx.vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(0,3,gl.FLOAT, false,5*4,0);
gl.vertexAttribPointer(1,2,gl.FLOAT, false,5*4,3*4);
gl.enableVertexAttribArray(0);
gl.enableVertexAttribArray(1);
gfx.line_vao = gl.createVertexArray();
gfx.line_vbo = gl.createBuffer();
gl.bindVertexArray(gfx.line_vao);
gl.bindBuffer(gl.ARRAY_BUFFER, gfx.line_vbo);
gl.vertexAttribPointer(0,3,gl.FLOAT, false,3*4,0);
gl.enableVertexAttribArray(0);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
var width = canvas.width;
var height = canvas.height;
resize_gfx(gfx, width, height);
return gfx;
}
function make_shader(type, shader) {
var handle = gl.createShader(type);
gl.shaderSource(handle, shader);
gl.compileShader(handle);
var success = gl.getShaderParameter(handle, gl.COMPILE_STATUS);
if (!success) {
var info = gl.getShaderInfoLog(handle);
alert(info);
}
return handle;
}
function resize_gfx(state,width,height) {
gl.viewport(0,0,width,height);
state.width = width;
state.height = height;
}
function GraphicState() {
var ctx;
var window;
var shader;
var vao;
var vbo;
var line_vao;
var line_vbo;
var width;
var height;
}
function draw_line (x, y, z, to_x, to_y, to_z, r, g, b, a) {
var vertices = [
x,y,z,
to_x,to_y,to_z
];
gl.useProgram(gfx.shader);
gl.uniform1i(gl.getUniformLocation(gfx.shader, "line"), a);
gl.uniform3f(gl.getUniformLocation(gfx.shader,"color"),r/255.0,g/255.0,b/255.0);
gl.bindBuffer(gl.ARRAY_BUFFER,gfx.line_vbo);
gl.bindVertexArray(gfx.line_vao);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STREAM_DRAW);
gl.drawArrays(gl.LINES, 0, 2);
}
function get_forward_vec(pitch, yaw, pos) {
var elevation = glm.radians(-pitch);
var heading = glm.radians(yaw);
var forward_vec = glm.vec3(Math.cos(elevation) * Math.sin(heading), Math.sin(elevation), Math.cos(elevation) * Math.cos(heading));
return forward_vec;
}
function render() {
var projection = glm.perspective(glm.radians(75.0), gfx.width / gfx.height, 0.1, 2000.0);
projection = glm.scale(projection, glm.vec3(-1.0, 1.0, 1.0));
var player_y = 0.0;
var player_forward_vec;
//TODO get Player
player_y = 0;
var pitch = 0;
var yaw = 0;
var cam_at = glm.vec3(0, 0 + 1.5, 0);
player_forward_vec = get_forward_vec(pitch, yaw, cam_at);
//var cam_look = glm.vec3(11, 11 + 1.5, 11) + get_forward_vec(pitch, yaw, cam_at);
var sumx = cam_at.x + player_forward_vec.x;
var sumy = cam_at.y + player_forward_vec.y;
var sumz = cam_at.z + player_forward_vec.z;
var cam_look = glm.vec3(sumx,sumy,sumz);
var ls = glm.vec3(0.0, 1.0, 0.0);
var view = glm.lookAt(cam_at, cam_look, ls);
gl.useProgram(gfx.shader);
gl.uniform1f(gl.getUniformLocation(gfx.shader, "player_y"), player_y);
gl.uniformMatrix4fv(gl.getUniformLocation(gfx.shader, "projection"), false,projection.array);
gl.uniformMatrix4fv(gl.getUniformLocation(gfx.shader, "view"), false, view.array);
var at = glm.vec3(3, 2, 1);
var look = at['+'](get_forward_vec(0, 0, at)['*='](50.0));
look.y += 1.5;
draw_line(at.x, at.y, at.z, look.x, look.y, look.z, 0, 255, 0, 255);
}
function get_alpha_for_y (y1,y2) {
return Math.abs(y1 - y2) >= 3.0 ? 63 : 255;
}
start();
<canvas id="glcanvas"></canvas>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/glm-js.min.js"></script>