2014-11-25 64 views
0

我試圖在代碼執行時每生成一個隨機顏色並將其傳遞給片段着色器(繪製三角形)。 閱讀其他職位,我已經決定,最有效的解決方案似乎是:從javascript到片段着色器的單色

  • 在片段着色器設置統一的變量
  • 它鏈接到一個JavaScript變量
  • 寫片段着色器uniform4f提供的數據

試圖構造這個,我的代碼段不顯示三角形,但只有背景。如果我用 將所有處理該顏色的線都去掉,則該三角形再次出現。

var can = document.getElementById('cont'); 
var gl = can.getContext('experimental-webgl'); 
gl.clearColor(0.0, 0.1, 0.0, 1.0); 
gl.clear(gl.COLOR_BUFFER_BIT); 

red = Math.random(); 
green = Math.random(); 
blue = Math.random(); 
alpha = Math.random(); 
var vertices = [-1,-1,1,-1,0,0.5]; 
var colorData = [red,green,blue,alpha]; 

//Create color buffer 
var cbo = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER,cbo); 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colorData),gl.STATIC_DRAW); 

//Create vertex buffer  
var vbo = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER,vbo); 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW); 


//Shaders 
var vshaderCode = 'attribute vec2 pos;' + 'void main() {gl_Position = vec4 (pos,0.,1.);}'; 

var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor' + 'void main() {gl_FragColor = uColor;}'; 


function getShader(shaderSource,type) { 
var shad = gl.createShader(type); 
gl.shaderSource(shad,shaderSource); 
gl.compileShader(shad); 
return shad; 
} 

var vertexShader = getShader (vshaderCode,gl.VERTEX_SHADER); 
var fragmentShader = getShader (fshaderCode,gl.FRAGMENT_SHADER); 

//Create the program to link shaders 

var prog = gl.createProgram(); 
gl.attachShader(prog,vertexShader); 
gl.attachShader(prog,fragmentShader); 
gl.linkProgram(prog); 

var _position = gl.getAttribLocation(prog, "pos"); 
var u_ColorLocation = gl.getUniformLocation(prog, "uColor"); 

//Draw 
gl.enableVertexAttribArray(_position); 
gl.useProgram(prog); 
gl.vertexAttribPointer(_position, 2, gl.FLOAT, false, 0,0); 
gl.uniform4f(u_ColorLocation, colorData); 
gl.drawArrays(gl.TRIANGLES, 0, 3); 

控制檯說gl.uniform4f(u_ColorLocation, colorData);需要5個參數。這一點我不清楚。

即使我將該行更改爲諸如gl.uniform4f(u_colorLocation, 0, 0, 1, 1);之類的程序,該程序也不會鏈接。

如何通過我的值從JavaScript到GPU上的片段,以便我的三角形只有一個顏色,由JavaScript變量驅動?

回答

0

在你fragmentshader你錯過了你的制服背後聲明冒號:

var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor;' + 'void main() {gl_FragColor = uColor;}'; 

正如在下面的答案中提到的,檢查編譯狀態在這裏很有幫助,因爲在它自己的文件中寫入着色器是。對於設置制服,有統一的XX(即uniform4f)和uniformXXv(即uniform4fv)變體。 v代表矢量,當您提供像您的顏色一樣的數據矢量時需要使用該矢量。

所以你也想把它改成uniform4fv。

var can = document.getElementById('cont'); 
 
var gl = can.getContext('experimental-webgl'); 
 
gl.clearColor(0.0, 0.1, 0.0, 1.0); 
 
gl.clear(gl.COLOR_BUFFER_BIT); 
 

 
red = Math.random(); 
 
green = Math.random(); 
 
blue = Math.random(); 
 
alpha = Math.random(); 
 
var vertices = [-1,-1,1,-1,0,0.5]; 
 
var colorData = [red,green,blue,alpha]; 
 

 
//Create color buffer 
 
var cbo = gl.createBuffer(); 
 
gl.bindBuffer(gl.ARRAY_BUFFER,cbo); 
 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colorData),gl.STATIC_DRAW); 
 

 
//Create vertex buffer  
 
var vbo = gl.createBuffer(); 
 
gl.bindBuffer(gl.ARRAY_BUFFER,vbo); 
 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW); 
 

 

 
//Shaders 
 
var vshaderCode = 'attribute vec2 pos;' + 'void main() {gl_Position = vec4 (pos,0.,1.);}'; 
 

 
var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor;' + 'void main() {gl_FragColor = uColor;}'; 
 

 

 
function getShader(shaderSource,type) { 
 
var shad = gl.createShader(type); 
 
gl.shaderSource(shad,shaderSource); 
 
gl.compileShader(shad); 
 
return shad; 
 
} 
 

 
var vertexShader = getShader (vshaderCode,gl.VERTEX_SHADER); 
 
var fragmentShader = getShader (fshaderCode,gl.FRAGMENT_SHADER); 
 

 
//Create the program to link shaders 
 

 
var prog = gl.createProgram(); 
 
gl.attachShader(prog,vertexShader); 
 
gl.attachShader(prog,fragmentShader); 
 
gl.linkProgram(prog); 
 

 
var _position = gl.getAttribLocation(prog, "pos"); 
 
var u_ColorLocation = gl.getUniformLocation(prog, "uColor"); 
 

 
//Draw 
 
gl.enableVertexAttribArray(_position); 
 
gl.useProgram(prog); 
 
gl.vertexAttribPointer(_position, 2, gl.FLOAT, false, 0,0); 
 
gl.uniform4fv(u_ColorLocation, colorData); 
 
gl.drawArrays(gl.TRIANGLES, 0, 3);
<canvas id="cont"></canvas>

1

您錯過了一個;在你的fshaderCode着色器上,所以它不是編譯的。

閱讀着色器的COMPILE_STATUS可以幫助您計算出您是否有任何語法問題。

if (!gl.getShaderParameter(shad, gl.COMPILE_STATUS)) { 
    console.log("COMPILE_STATUS", gl.getShaderInfoLog(shad)); 
} 

更新後的代碼,以顯示隨機顏色的三角形

var can = document.getElementById('cont'); 
 
var gl = can.getContext('experimental-webgl'); 
 
gl.clearColor(0.0, 0.1, 0.0, 1.0); 
 
gl.clear(gl.COLOR_BUFFER_BIT); 
 

 
red = Math.random(); 
 
green = Math.random(); 
 
blue = Math.random(); 
 
alpha = Math.random(); 
 
var vertices = [-1,-1,1,-1,0,0.5]; 
 
var colorData = [red,green,blue,alpha]; 
 

 
//Create color buffer 
 
var cbo = gl.createBuffer(); 
 
gl.bindBuffer(gl.ARRAY_BUFFER,cbo); 
 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colorData),gl.STATIC_DRAW); 
 

 
//Create vertex buffer  
 
var vbo = gl.createBuffer(); 
 
gl.bindBuffer(gl.ARRAY_BUFFER,vbo); 
 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW); 
 

 

 
//Shaders 
 
var vshaderCode = 'attribute vec2 pos;' + 'void main()' + '{gl_Position = vec4 (pos,0.,1.);' + '}'; 
 

 
var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor;' + 'void main() {gl_FragColor = uColor;}'; 
 

 

 
function getShader(shaderSource,type) { 
 
var shad = gl.createShader(type); 
 
gl.shaderSource(shad,shaderSource); 
 
gl.compileShader(shad); 
 
    
 
if (!gl.getShaderParameter(shad, gl.COMPILE_STATUS)) { 
 
    console.log("COMPILE_STATUS", gl.getShaderInfoLog(shad)); 
 
} 
 
    
 
return shad; 
 
} 
 

 
var vertexShader = getShader (vshaderCode,gl.VERTEX_SHADER); 
 
var fragmentShader = getShader (fshaderCode,gl.FRAGMENT_SHADER); 
 

 
//Create the program to link shaders 
 

 
var prog = gl.createProgram(); 
 
gl.attachShader(prog,vertexShader); 
 
gl.attachShader(prog,fragmentShader); 
 
gl.linkProgram(prog); 
 

 
var _position = gl.getAttribLocation(prog, "pos"); 
 
var u_ColorLocation = gl.getUniformLocation(prog, "uColor"); 
 

 
//Draw 
 

 
var r = Math.random(), g= Math.random(), b = Math.random(); 
 

 
gl.enableVertexAttribArray(_position); 
 
gl.useProgram(prog); 
 
gl.vertexAttribPointer(_position, 2, gl.FLOAT, false, 0,0); 
 
gl.uniform4f(u_ColorLocation, r, g, b, 1.0); 
 
gl.drawArrays(gl.TRIANGLES, 0, 3);
<canvas id="cont"></canvas>

+0

注意,根據OpenGL ES 2.0的規範'COMPILE_STATUS'允許總是報告成功沿如檢查'LINK_STATUS'當錯誤最終報告。我不知道有哪些驅動程序會這樣做,但它是規範的一部分,所以一定要檢查LINK_STATUS。 我知道,因爲我不得不重構所有的WebGL一致性測試來考慮這一點:P – gman 2014-11-27 00:49:09