2015-10-23 15 views
5

ContextWebGL - kích thước biến mảng trên vertex gọi

Tôi đang cố gắng để vẽ đường cong Bezier trong một canvas. Tôi đã đạt được để vẽ các đường cong bậc hai và khối từ trong bóng đổ, nhưng tôi đã có một biến thống nhất cho mỗi và mọi điểm kiểm soát cho đến nay.

Vì vậy, tôi nhấp vào canvas của tôi, thêm điểm và khi tôi có đủ (tương ứng 3 và 4), tôi vẽ đường cong của mình.

Bây giờ tôi đang cố gắng khái quát đường cong Bezier. Mặc dù tôi đã đạt được điều này ở phía bên JavaScript, tôi cảm thấy sẽ tốt hơn nếu thực hiện điều này từ phía trình đổ bóng, vì tốc độ hiển thị sẽ tăng lên đáng kể.

Vì vậy, tôi muốn vẽ đường cong của mình ngay khi có ít nhất hai điểm. Nhưng tôi có thể tiếp tục thêm điểm và vẽ đường cong của tôi bằng mọi điểm, theo thứ tự như điểm kiểm soát.

Giải thích

Vì vậy, tôi biết điều đó là không thể để thiết lập một mảng động trong GLSL, nhưng nó possibliy để tự động khai báo một mảng GLSL dựa trên một biến JS?

Nếu câu hỏi của tôi không rõ ràng (Tôi biết tôi gặp khó khăn trong việc xây dựng mọi thứ ngay lập tức), hãy để tôi giải thích bằng một ví dụ.

uniform vec2 uMyPoints[<length>]; 

Vì vậy, đây là những gì tôi muốn đạt được, nhưng tất nhiên, kích thước mảng phải là một hằng số, theo thông số kỹ thuật của glsl.

Tuy nhiên, theo quan điểm của tôi, tôi cảm thấy mình có thể thiết lập length từ biến JS. Trực giác của tôi là kích thước mảng trong GLSL sẽ là hằng số trong suốt thời gian thực hiện các trình đổ bóng khác nhau trong quá trình kết xuất, nhưng có thể thay đổi từ một lần hiển thị khác sang hiển thị khác.

Câu hỏi

Vì vậy, câu hỏi của tôi cho bạn là: Dựa trên những, bạn có biết cách nào tốt hay thủ thuật để có bộ thể một hằng số trong GLSL từ một biến javascript?

Nếu có vẻ như có thể, điều này sẽ giúp tôi rất nhiều. Cảm ơn bạn đã xem xét.

Như một vấn đề của so sánh:?.. Làm sao chúng ta có thể thiết lập "numLights" in this example từ JS

trả lời

Chuỗi thay thế phù hợp với nhu cầu của tôi độc đáo Mặc dù đó là một chút khéo léo, nó sẽ làm tốt hơn nữa nghiên cứu đã dẫn tôi biết rằng kích thước mảng tiềm ẩn có sẵn Open GL ES phiên bản 3, mà nên được sử dụng bởi các phiên bản tương lai của WebGL, nhưng không phải ngay bây giờ. Tôi chính xác muốn tránh việc có N điểm trong bóng đổ, vì số lượng điểm có thể thay đổi.

Cảm ơn cho câu trả lời;)

Trả lời

2

Chuỗi thay thế các công trình

<script id="vs" type="notjs">  
uniform vec2 uMyPoints[<length>]; 
... 
</script> 

js

var numPoints = 10; 
var vSrc = document.getElementById("vs").text; 
vSrc = vSrc.replace(/<length>/g, numPoints); 

Đây là những gì các chương trình phức tạp nhất làm cho bóng đổ. Chúng tạo ra các shader với thao tác chuỗi.

Tất nhiên bạn có thể muốn sử dụng chức năng đẹp hơn để thực hiện thay thế chuỗi. Ví dụ có lẽ cái gì đó như

/** 
    * Replace %(id)s in strings with values in objects(s) 
    * 
    * Given a string like `"Hello %(name)s from $(user.country)s"` 
    * and an object like `{name:"Joe",user:{country:"USA"}}` would 
    * return `"Hello Joe from USA"`. 
    * 
    * @function 
    * @param {string} str string to do replacements in 
    * @param {Object|Object[]} params one or more objects. 
    * @returns {string} string with replaced parts 
    * @memberOf module:Strings 
    */ 
    var replaceParams = (function() { 
    var replaceParamsRE = /%\(([^\)]+)\)s/g; 

    return function(str, params) { 
     if (!params.length) { 
     params = [params]; 
     } 

     return str.replace(replaceParamsRE, function(match, key) { 
     var keys = key.split('.'); 
     for (var ii = 0; ii < params.length; ++ii) { 
      var obj = params[ii]; 
      for (var jj = 0; jj < keys.length; ++jj) { 
      var part = keys[jj]; 
      obj = obj[part]; 
      if (obj === undefined) { 
       break; 
      } 
      } 
      if (obj !== undefined) { 
      return obj; 
      } 
     } 
     console.error("unknown key: " + key); 
     return "%(" + key + ")s"; 
     }); 
    }; 
    }()); 

bây giờ nếu bạn đang đổ bóng trông như thế này

uniform Lights u_lights[%(numLights)s]; 
uniform vec2 u_points[%(numPoints)s]; 

bạn có thể thay thế nó bằng

vSrc = replaceParams(vsrc, { 
    numLights: 4, 
    numPoints: 10, 
}); 

Bạn cũng có thể sử dụng tất nhiên '#define trong shader

#define NUM_LIGHTS %(numLights)s 
#define NUM_POINTS %(numPoints)s 

uniform Lights u_lights[NUM_LIGHTS]; 
uniform vec2 u_points[NUM_POINTS]; 

void main() { 
    for (int i = 0; i < NUM_LIGHTS; ++i) { 
    ... 
    } 
} 

vv ..

Nhưng, trung thực hầu hết mọi người sẽ không vượt qua các điểm kiểm soát bezier như đồng phục vì có hạn chế nghiêm trọng về số lượng đồng phục. Hầu hết mọi người sẽ vượt qua các điểm kiểm soát bezier trong các thuộc tính. Bạn có thể có lẽ thậm chí thiết lập các sải chân và bù đắp khi gọi gl.vertexAttribPointer do đó nếu điểm của bạn đi

[pt0, pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8, ..] 

Bạn có thể làm 4 thuộc tính

attribute vec2 p0; 
attribute vec2 p1; 
attribute vec2 p2; 
attribute vec2 p3; 

Và điểm tất cả trong số họ với một sải chân bù đắp và để thiết lập của bạn 4 thuộc tính để các điểm được lấy ra

p0 = pt0, p1 = pt1, p2 = pt2, p3 = pt3, 
p0 = pt1, p1 = pt2, p2 = pt3, p3 = pt4, 
p0 = pt2, p1 = pt3, p2 = pt4, p3 = pt5, 
p0 = pt3, p1 = pt4, p2 = pt5, p3 = pt6, 

vv ..

Các vấn đề liên quan