我是webgl的新手,我一直在尝试使用variant将属性传递给片段着色器,以将所有三角形更改为随机颜色,如下所示:
但是现在,所有的三角形都只是白色,我不确定是哪里做错了。另外,如何使三角形适合画布?请帮助,谢谢。
// Application info.
var app = app || {};
var nbTriangles = 20;
function getContextGL(canvasElement) {
var can = document.getElementById(canvasElement);
if (can == null) {
return [null, null];
}
var gl = can.getContext("webgl");
return [can, gl];
}
function createShaderFromElement(gl, id) {
// Grab the script element.
var scriptElt = document.getElementById(id);
if (!scriptElt) {
return null;
}
// Retrieve the source.
var scriptSource = scriptElt.textContent;
// Identify shader type based on element type.
var shaderObj;
if (scriptElt.type == "x-shader/x-fragment") {
shaderObj = gl.createShader(gl.FRAGMENT_SHADER);
}
else if (scriptElt.type == "x-shader/x-vertex") {
shaderObj = gl.createShader(gl.VERTEX_SHADER);
}
else {
return null;
}
// Compile and check status.
gl.shaderSource(shaderObj, scriptSource);
gl.compileShader(shaderObj);
var ok = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS);
if (!ok) {
var msgError = gl.getShaderInfoLog(shaderObj);
alert(msgError);
gl.deleteShader(shader);
return null;
}
return shaderObj;
}
function buildProgram(gl, vertexShader, fragmentShader) {
if (!vertexShader || !fragmentShader) {
return null;
}
var progObject = gl.createProgram();
if (!progObject) {
alert("Can't create program object.");
return;
}
gl.attachShader(progObject, vertexShader);
gl.attachShader(progObject, fragmentShader);
gl.linkProgram(progObject);
var ok = gl.getProgramParameter(progObject, gl.LINK_STATUS);
if (!ok) {
var msgError = gl.getProgramInfoLog(progObject);
alert(msgError);
gl.deleteProgram(progObject);
return null;
}
return progObject;
}
function initGL() {
app.gl.viewport(0, 0, app.can.width, app.can.height);
app.gl.clearColor(0., 0., 0., 1.0);
app.gl.clear(app.gl.COLOR_BUFFER_BIT);
var vs = createShaderFromElement(app.gl, "vs");
var fs = createShaderFromElement(app.gl, "fs");
app.progObject = buildProgram(app.gl, vs, fs);
app.gl.useProgram(app.progObject);
}
function initScene() {
var gl = app.gl;
// Creer le buffer de geometrie (vertex)
//
var positions = [];
for (var i = 0; i < nbTriangles; ++i) {
var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
var scale = Math.random() * 0.2;
var Trans = [Math.random() * 1.6, Math.random() * 1.6];
var P0 = [
orig[0] * scale + Trans[0],
orig[1] * scale + Trans[1],
];
var P1 = [
orig[2] * scale + Trans[0],
orig[3] * scale + Trans[1],
];
var P2 = [
orig[4] * scale + Trans[0],
orig[5] * scale + Trans[1],
];
positions.push(...P0, ...P1, ...P2);
}
var colors = [];
for (var i = 0; i < nbTriangles; ++i) {
var newColor = [Math.random() * 256, Math.random() * 256, Math.random() * 256, 1.0];
colors.push(...newColor);
}
// Creer un nouveau buffer vide.
var posBuffer = gl.createBuffer();
var colorBuffer = gl.createBuffer();
// Ref sur l'attribut "pos" dans le vertex shader.
var posLocation = gl.getAttribLocation(app.progObject, "pos");
var colorLocation = gl.getAttribLocation(app.progObject, "color");
// Activer le buffer. Toute operation sur buffer
// sera appliquer a posBuffer (il est actif!).
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
gl.enableVertexAttribArray(posLocation);
gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false /*no normalization*/, 0 /*stride*/, 0 /*offset*/);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorLocation);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
}
function render() {
var gl = app.gl;
gl.clear(gl.COLOR_BUFFER_BIT)
// Dessiner le buffer.
gl.drawArrays(gl.TRIANGLES, 0, 3 * nbTriangles);
}
function init() {
[app.can, app.gl] = getContextGL('can');
if (app.can == null || app.gl == null) {
alert("Can't init canvas or context");
return;
}
app.can.width = app.can.height * (app.can.clientWidth / app.can.clientHeight);
var rect = app.can.getBoundingClientRect();
app.scaleX = app.can.width / rect.width;
app.scaleY = app.can.height / rect.height;
initGL();
initScene();
render();
}
div
{
}
#main-div
{
display:inline-block;
}
#viewport, #manager
{
float: left;
margin: auto;
}
.color
{
width:100px;
height:50px;
}
.blue{
background:#0f0;
}
#viewport
{
width: 600px;
height:700px;
}
#can
{
width: 600px;
height: 500px;
border:1px solid orange;
}
#manager
{
width: 200px;
height:300px;
padding: 0 0 0 5px;
}
#obj-list
{
width: 200px;
}
<!DOCTYPE html>
<html>
<head>
<title>Colored Quad</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="colored_quad.js"></script>
<script id="vs" type="x-shader/x-vertex">
precision mediump float;
attribute vec2 pos;
attribute vec4 color;
varying vec4 fcolor;
void main()
{
vec4 pt = vec4(pos, 0.0, 1.0);
gl_Position = pt;
fcolor=color;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fcolor;
void main()
{
vec4 color= fcolor;
gl_FragColor = color;
}
</script>
</head>
<body onload="init();">
<div id="main-div">
<div id="viewport">
<canvas id="can" >Your browser doesn't seem to support canvas!</canvas>
</div>
</div>
</body>
</html>
答案 0 :(得分:1)
color属性具有浮点类型:
attribute vec4 color;
gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
因此,颜色值必须在[0.0,1.0]而不是[0,256]范围内指定:
var newColor = [Math.random() * 256, Math.random() * 256, Math.random() * 256, 1.0];
var newColor = [Math.random(), Math.random(), Math.random(), 1.0];
此外,每个三角形都有3个顶点(角)。每个顶点坐标必须与一个单独的颜色属性关联。因此,每个三角形也必须具有3种颜色属性:
var colors = [];
for (var i = 0; i < nbTriangles; ++i) {
var newColor = [Math.random(), Math.random(), Math.random(), 1.0];
colors.push(...newColor);
colors.push(...newColor);
colors.push(...newColor);
}
// Application info.
var app = app || {};
var nbTriangles = 20;
function getContextGL(canvasElement) {
var can = document.getElementById(canvasElement);
if (can == null) {
return [null, null];
}
var gl = can.getContext("webgl");
return [can, gl];
}
function createShaderFromElement(gl, id) {
// Grab the script element.
var scriptElt = document.getElementById(id);
if (!scriptElt) {
return null;
}
// Retrieve the source.
var scriptSource = scriptElt.textContent;
// Identify shader type based on element type.
var shaderObj;
if (scriptElt.type == "x-shader/x-fragment") {
shaderObj = gl.createShader(gl.FRAGMENT_SHADER);
}
else if (scriptElt.type == "x-shader/x-vertex") {
shaderObj = gl.createShader(gl.VERTEX_SHADER);
}
else {
return null;
}
// Compile and check status.
gl.shaderSource(shaderObj, scriptSource);
gl.compileShader(shaderObj);
var ok = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS);
if (!ok) {
var msgError = gl.getShaderInfoLog(shaderObj);
alert(msgError);
gl.deleteShader(shader);
return null;
}
return shaderObj;
}
function buildProgram(gl, vertexShader, fragmentShader) {
if (!vertexShader || !fragmentShader) {
return null;
}
var progObject = gl.createProgram();
if (!progObject) {
alert("Can't create program object.");
return;
}
gl.attachShader(progObject, vertexShader);
gl.attachShader(progObject, fragmentShader);
gl.linkProgram(progObject);
var ok = gl.getProgramParameter(progObject, gl.LINK_STATUS);
if (!ok) {
var msgError = gl.getProgramInfoLog(progObject);
alert(msgError);
gl.deleteProgram(progObject);
return null;
}
return progObject;
}
function initGL() {
app.gl.viewport(0, 0, app.can.width, app.can.height);
app.gl.clearColor(0., 0., 0., 1.0);
app.gl.clear(app.gl.COLOR_BUFFER_BIT);
var vs = createShaderFromElement(app.gl, "vs");
var fs = createShaderFromElement(app.gl, "fs");
app.progObject = buildProgram(app.gl, vs, fs);
app.gl.useProgram(app.progObject);
}
function initScene() {
var gl = app.gl;
// Creer le buffer de geometrie (vertex)
//
var positions = [];
for (var i = 0; i < nbTriangles; ++i) {
var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
var scale = Math.random() * 0.2;
var Trans = [Math.random() * 1.6, Math.random() * 1.6];
var P0 = [
orig[0] * scale + Trans[0],
orig[1] * scale + Trans[1],
];
var P1 = [
orig[2] * scale + Trans[0],
orig[3] * scale + Trans[1],
];
var P2 = [
orig[4] * scale + Trans[0],
orig[5] * scale + Trans[1],
];
positions.push(...P0, ...P1, ...P2);
}
var colors = [];
for (var i = 0; i < nbTriangles; ++i) {
var newColor = [Math.random(), Math.random(), Math.random(), 1.0];
colors.push(...newColor);
colors.push(...newColor);
colors.push(...newColor);
}
// Creer un nouveau buffer vide.
var posBuffer = gl.createBuffer();
var colorBuffer = gl.createBuffer();
// Ref sur l'attribut "pos" dans le vertex shader.
var posLocation = gl.getAttribLocation(app.progObject, "pos");
var colorLocation = gl.getAttribLocation(app.progObject, "color");
// Activer le buffer. Toute operation sur buffer
// sera appliquer a posBuffer (il est actif!).
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
gl.enableVertexAttribArray(posLocation);
gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false /*no normalization*/, 0 /*stride*/, 0 /*offset*/);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorLocation);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
}
function render() {
var gl = app.gl;
gl.clear(gl.COLOR_BUFFER_BIT)
// Dessiner le buffer.
gl.drawArrays(gl.TRIANGLES, 0, 3 * nbTriangles);
}
function init() {
[app.can, app.gl] = getContextGL('can');
if (app.can == null || app.gl == null) {
alert("Can't init canvas or context");
return;
}
app.can.width = app.can.height * (app.can.clientWidth / app.can.clientHeight);
var rect = app.can.getBoundingClientRect();
app.scaleX = app.can.width / rect.width;
app.scaleY = app.can.height / rect.height;
initGL();
initScene();
render();
}
div
{
}
#main-div
{
display:inline-block;
}
#viewport, #manager
{
float: left;
margin: auto;
}
.color
{
width:100px;
height:50px;
}
.blue{
background:#0f0;
}
#viewport
{
width: 600px;
height:700px;
}
#can
{
width: 600px;
height: 500px;
border:1px solid orange;
}
#manager
{
width: 200px;
height:300px;
padding: 0 0 0 5px;
}
#obj-list
{
width: 200px;
}
<!DOCTYPE html>
<html>
<head>
<title>Colored Quad</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="colored_quad.js"></script>
<script id="vs" type="x-shader/x-vertex">
precision mediump float;
attribute vec2 pos;
attribute vec4 color;
varying vec4 fcolor;
void main()
{
vec4 pt = vec4(pos, 0.0, 1.0);
gl_Position = pt;
fcolor=color;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fcolor;
void main()
{
vec4 color= fcolor;
gl_FragColor = color;
}
</script>
</head>
<body onload="init();">
<div id="main-div">
<div id="viewport">
<canvas id="can" >Your browser doesn't seem to support canvas!</canvas>
</div>
</div>
</body>
</html>