2013-03-27 15 views
22

Tôi đã bắt đầu với trình kết xuất WebGL của ThreeJS sau khi thực hiện một số WebGL "thông thường" không có thư viện bổ sung + trình tạo bóng GLSL. Tôi đang cố gắng viết các trình đổ bóng tùy chỉnh ngay trong chương trình ThreeJS của mình và tôi nhận thấy rằng ThreeJS chăm sóc rất nhiều các công cụ chuẩn như phép chiếu và các ma trận mô hình/khung nhìn. vertex shader đơn giản của tôi bây giờ trông như thế này:BaJS thuộc tính đổ bóng được xác định trước/đồng phục

// All of these seem to be predefined: 
// vec3 position; 
// mat4 projectionMatrix; 
// mat4 modelViewMatrix; 
// mat3 normalMatrix; 
// vec3 normal; 

// I added this 
varying vec3 vNormal; 

void main() { 
    vNormal = normalMatrix * vec3(normal); 
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 
} 

Câu hỏi của tôi là: Những biến khác (tôi giả sử họ đang đồng phục) được định nghĩa trước cho đỉnh và mảnh shaders rằng tôi có thể sử dụng không? Liệu ThreeJS có hỗ trợ các vectơ ánh sáng/màu sáng không (dĩ nhiên giả sử tôi đã thêm một hoặc nhiều ánh sáng vào cảnh ThreeJS của tôi)?

Cập nhật (ngày 9 tháng 10 năm 2014): Câu hỏi này đã nhận được một vài lượt xem và người dùng Killah đã đề cập rằng câu trả lời hiện tại không dẫn đến giải pháp nữa với phiên bản hiện tại của ba.js. Tôi đã thêm và chấp nhận câu trả lời của riêng tôi, xem câu trả lời dưới đây.

+0

đẹp câu hỏi, '+ 1' –

Trả lời

4

câu hỏi này nhận được khá nhiều quan điểm, và người dùng Killah nói rằng câu trả lời hiện không dẫn đến một giải pháp nữa với phiên bản hiện tại của ba .js. Đây là lý do tại sao tôi đã cố gắng giải quyết vấn đề một lần nữa, và tôi muốn để phác thảo một vài lựa chọn mà tôi tìm thấy:

  • Cách nhanh nhất và dễ dàng nhất (trong khi không phải là rất thanh lịch) là chỉ cần đặt một ngẫu nhiên lỗi trong trình đổ bóng của bạn. Bạn sẽ nhận được một lỗi giao diện điều khiển với toàn bộ mã đổ bóng, bao gồm mọi thứ mà ba.js thêm vào.

  • Giải pháp tốt hơn là xuất nguồn nguồn đổ bóng từ nơi được biên dịch, cụ thể là BA.WebGLShader (như phiên bản ba.js hiện tại, r68). Tôi đã thực hiện một bản sao nhanh và dán mà nên đầu ra tất cả các nguồn shader trước khi chúng được biên soạn.

    Thêm này sau đó có three.js và trước khi mã của riêng bạn:

    THREE.WebGLShader = (function() { 
        var addLineNumbers = function (string) { 
         var lines = string.split('\n'); 
         for (var i = 0; i < lines.length; i ++) { 
          lines[ i ] = (i + 1) + ': ' + lines[ i ]; 
         } 
         return lines.join('\n'); 
        }; 
        return function (gl, type, string) { 
         var shader = gl.createShader(type); 
         console.log(string); 
         gl.shaderSource(shader, string); 
         gl.compileShader(shader); 
         if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === false) { 
          console.error('THREE.WebGLShader: Shader couldn\'t compile.'); 
         } 
         if (gl.getShaderInfoLog(shader) !== '') { 
          console.warn('THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog(shader)); 
          console.warn(addLineNumbers(string)); 
         } 
         return shader; 
        }; 
    })(); 
    

    Lưu ý rằng đoạn mã này chỉ được sao chép (và rất nhẹ thay đổi) từ các nguồn three.js và cần được loại bỏ trước khi thực sự sử dụng mật mã. Chỉ để gỡ lỗi!

  • Có thêm một lựa chọn đó là ít xâm lấn: bạn có thể kiểm tra ShaderMaterial của bạn sau khi tạo và làm cho nó ít nhất một lần, như vậy:

    var material = new THREE.ShaderMaterial({ 
        uniforms: { 
         uColorMap: { type: 't', value: THREE.ImageUtils.loadTexture('./img/_colors.png') }, 
         uSpecularMap: { type: 't', value: THREE.ImageUtils.loadTexture('./img/_spec.png') }, 
         uNormalMap: { type: 't', value: THREE.ImageUtils.loadTexture('./img/_normal.png') } 
        }, 
        vertexShader: document.getElementById('vShader').innerText, 
        fragmentShader: document.getElementById('fShader').innerText 
    }); 
    

    Sau đó, sau render các đối tượng ít nhất một lần :

    console.log(material.program.attributes); 
    console.log(material.program.uniforms); 
    

Hope this helps tất cả mọi người! Vui lòng thêm nhận xét của bạn nếu bạn biết nhiều hơn và/hoặc cách tốt hơn để có được mã đổ bóng của bạn.

11

Đồng phục bạn có thể sử dụng trong trình đổ bóng tất cả đều phụ thuộc vào cách bạn thiết lập tài liệu của mình: bạn có bật đèn không? màu sắc đỉnh? skinning? ...

Ba JS tạo chương trình phụ thuộc nhiều vào một số định nghĩa (#ifdef trong mã) được chèn ở đầu chương trình tùy thuộc vào thông số tôi đã nói ở trên.

Tôi tìm thấy cách tốt nhất để biết những gì đang xảy ra là in các trình tạo bóng mà ba JS tạo ra: như bạn đã biết GLSL, bạn sẽ hiểu dễ dàng mã và phương tiện bạn có thể sử dụng. Hãy tìm buildProgram trong ba nguồn JS, sau đó (R 57):

var glFragmentShader = getShader("fragment", prefix_fragment + fragmentShader); 
var glVertexShader = getShader("vertex", prefix_vertex + vertexShader); 

Sau những đường nét, thêm:

console.log("fragment shader:", prefix_fragment + fragmentShader); 
console.log("vertex shader:", prefix_vertex + vertexShader); 

Và bạn sẽ có thể xem nội dung của các bóng đổ.

[EDIT] Đọc lại câu hỏi của bạn, tôi nhận ra tôi đã trả lời một chút đi, khi bạn tạo bóng đổ của riêng bạn ...

Bạn có thể có một cái nhìn tại dòng 6463 và 6490 của WebGLRenderer (https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L6463): bạn sẽ thấy đồng phục/thuộc tính tiêu chuẩn mà ba JS sẽ chèn vào trình đổ bóng của bạn. Bạn có thể có một cái nhìn vào Wiki nơi bạn có một mục về điều đó (https://github.com/mrdoob/three.js/wiki - Thuộc tính mặc định/đồng phục/sự thay đổi nào có sẵn trong trình đổ bóng tùy chỉnh?) Nhưng nó hướng bạn đến các dòng tôi đã nêu ở trên.

+0

Cảm ơn câu trả lời của bạn, mọi người trên SO là thực sự hữu ích :) Các dòng nguồn bạn chỉ ra đã trả lời câu hỏi của tôi. Đồ tốt! –

+0

Liên kết tới mã đã lỗi thời, các dòng đã thay đổi kể từ khi câu trả lời được đưa ra. – Killah

+0

@Killah Tôi sẽ nghiên cứu và cập nhật câu hỏi này bằng một câu trả lời khác. Cảm ơn bạn đã đứng đầu –

19

Đối với đồng phục, câu trả lời ngắn gọn là như sau:

Trong vertex

"uniform mat4 modelMatrix;", 
"uniform mat4 modelViewMatrix;", 
"uniform mat4 projectionMatrix;", 
"uniform mat4 viewMatrix;", 
"uniform mat3 normalMatrix;", 
"uniform vec3 cameraPosition;", 

và trong đoạn đổ bóng

"uniform mat4 viewMatrix;", 
"uniform vec3 cameraPosition;", 

Đối với câu trả lời hoàn chỉnh, liên quan đến đồng phục và các thuộc tính , trình tạo bóng tùy chỉnh của bạn có các biến chuỗi prefixVertexprefixFragment được nối trước.

var vertexGlsl = prefixVertex + vertexShader; 
var fragmentGlsl = prefixFragment + fragmentShader; 

var glVertexShader = THREE.WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl); 
var glFragmentShader = THREE.WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); 

Các prefixVertexprefixFragment định nghĩa biến có thể được tìm thấy trong WebGLProgram.js hoặc trong phiên bản phi minified của three.js.

EDIT: Cập nhật để Three.js r.73

+0

Cảm ơn bạn đã trả lời! –

+0

Tôi xin lỗi, phần cuối cùng của câu trả lời (rất hữu ích) của bạn làm tôi bối rối. Chính xác những định nghĩa biến này làm gì? Bạn liệt kê 'var glVertexShader = new THREE.WebGLShader (_gl, _gl.VERTEX_SHADER, prefix_vertex + vertexShader);' nhưng tôi không chắc chắn khi nào chúng ta cần đến chúng. – Startec

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