使用threeJS着色器性能

时间:2015-04-20 08:17:10

标签: javascript three.js textures webgl

我想通过渲染简单的纹理形状来获得尽可能好的性能。问题是phong模型它需要额外的照明(涉及计算)+颜色不像所需的颜色,需要一些tweeking。

为简化案例,我决定使用简单的平面着色器,但会出现一些问题:

    <script id="vertShader" type="shader">
        varying vec2 vUv;
        void main() {
              vUv = uv;
              gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
        }
    </script>
    <script id="fragShader" type="shader">
        varying vec2 vUv;
        uniform sampler2D material;
        void main() {
            gl_FragColor = texture2D(material, vUv);
        }
    </script>

在某些相机角度下,一些货架会消失(您可以注意到较暗的地方,并透过它们看到),这种情况不会使用phong材料:

Screenshot using the flat shader - some shelves become transparent

在每个架子内放置阴影纹理时会发生这种情况。它是一个带有阴影纹理的纹理立方体,放在每个空间内(不要问我为什么,这只是我得到的任务:))

我不知道可能导致这种情况的原因。也许加载? 我使用标准的obj加载器并添加纹理。 Obj加载器将材质设置为phong并将其切换为自定义着色器,如下所示:

    var objLoader = new THREE.OBJLoader( manager );
    objLoader.load( obj, function ( model ) {

        elements[name] = model;
        console.log('loaded ', name);
        var img = THREE.ImageUtils.loadTexture(mat);
        elements[name].traverse( function ( child ) {
            if ( child instanceof THREE.Mesh ) {
                child.material = new THREE.ShaderMaterial( {
                    uniforms: {
                        color: {type: 'f', value: 0.0},
                        material: {type: 't', value: img}
                    },
                    fragmentShader: document.getElementById('fragShader').text,
                    vertexShader: document.getElementById('vertShader').text,
                } );
            }
        });

任何建议都会有所帮助

1 个答案:

答案 0 :(得分:1)

每个表面都沿一个方向(顺时针或逆时针)绘制。如果你从另一边展示一个表面,它将会消失。#34; dissapear&#34;。我认为这是你自己着色器的问题。 - &GT;你应该从两边渲染它们( - >表现更差)或者计算它应该从哪一边渲染。

为了略微优化性能,您应该使用THREE中的标准材料。您可以在不编写自己的着色器的情况下使用它们。

类似的东西:

child.material = new THREE.MeshBasicMaterial({
    side: THREE.DoubleSide,
    color: 0x000000
    // ...
});

我在自己的项目中创建了一个带有纹理的天空盒材料:

function getSkyboxMaterial() {
    var faceMaterials = getSkyboxFaces();
    var skyboxMaterial = new THREE.MeshFaceMaterial(faceMaterials);
    return skyboxMaterial;
}

function getSkyboxFaces() {
    var NUMBER_OF_FACES = 6, faces = [], texture, faceMaterial, texturePath, i;

    for (i = 0; i < NUMBER_OF_FACES; i++) {
        texturePath = IMAGE_PREFIX + DIRECTIONS[i] + IMAGE_SUFFIX;
        texture = loadFlippedTexture( texturePath );
        faceMaterial = getFaceMaterial( texture );
        faces.push( faceMaterial );
    }
    return faces;
}

function loadFlippedTexture(texturePath) {
    var texture = loadTexture(texturePath);
    flipTexture(texture); // This is necessary, because the skybox-textures are mirrored.
    return texture;
}

function loadTexture(path) {
    return THREE.ImageUtils.loadTexture(path);
}

function flipTexture(texture) {
    texture.repeat.set(-1, 1);
    texture.offset.set(1, 0);
    return texture;
}

function getFaceMaterial(texture) {
    var faceMaterial = new THREE.MeshBasicMaterial({
        map: texture,
        side: THREE.DoubleSide
    });
    return faceMaterial;
}