Three.js ShaderMaterial片段着色器中的透明度

时间:2014-10-08 18:54:49

标签: three.js webgl fragment-shader

我已经使用过Three.js了,但我刚开始学习着色器是如何工作的。

我有一个半透明的绿色立方体,如THREE.ShaderMaterial(基于“phong”ShaderLib)中所定义。我在ShaderMaterial多维数据集中放了一个简单的红色立方体,所以我可以告诉透明度是否有效(它是)。剩下的问题是绿色立方体的背面似乎没有渲染,尽管它设置为双面几何。

这是我的小提琴:http://jsfiddle.net/TheJim01/kgkhvbtL/113/

// partial glass box

var hostDiv, scene, renderer, camera, root, controls, light, shape;

var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 0.1,
FAR = 100;

function init() {
    hostDiv = document.createElement('div');
    document.body.appendChild(hostDiv);

    renderer = new THREE.WebGLRenderer({ antialias: true, preserverDrawingBuffer: true });
    renderer.setSize(WIDTH, HEIGHT);
    hostDiv.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
    camera.position.z = 75;

    controls = new THREE.TrackballControls(camera, renderer.domElement);

    light = new THREE.PointLight(0xffffff, 2, Infinity);
    light.position.copy(camera.position);

    scene = new THREE.Scene();
    scene.add(camera);
    scene.add(light);

    var geo = new THREE.BoxGeometry(10, 10, 10);

    var shader = {

    uniforms: THREE.UniformsUtils.merge( [

        THREE.UniformsLib[ "common" ],
        THREE.UniformsLib[ "bump" ],
        THREE.UniformsLib[ "normalmap" ],
        THREE.UniformsLib[ "fog" ],
        THREE.UniformsLib[ "lights" ],
        THREE.UniformsLib[ "shadowmap" ],

        {
            "ambient"  : { type: "c", value: new THREE.Color( 0xffffff ) },
            "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
            "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
            "shininess": { type: "f", value: 30 },
            "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
        }

    ] ),

    vertexShader: [

        "#define PHONG",

        "varying vec3 vViewPosition;",
        "varying vec3 vNormal;",

        THREE.ShaderChunk[ "map_pars_vertex" ],
        THREE.ShaderChunk[ "lightmap_pars_vertex" ],
        THREE.ShaderChunk[ "envmap_pars_vertex" ],
        THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
        THREE.ShaderChunk[ "color_pars_vertex" ],
        THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
        THREE.ShaderChunk[ "skinning_pars_vertex" ],
        THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
        THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],

        "varying vec3 glassPos;", // <!-- I added this -->

        "void main() {",

            THREE.ShaderChunk[ "map_vertex" ],
            THREE.ShaderChunk[ "lightmap_vertex" ],
            THREE.ShaderChunk[ "color_vertex" ],

            THREE.ShaderChunk[ "morphnormal_vertex" ],
            THREE.ShaderChunk[ "skinbase_vertex" ],
            THREE.ShaderChunk[ "skinnormal_vertex" ],
            THREE.ShaderChunk[ "defaultnormal_vertex" ],

        "   vNormal = normalize( transformedNormal );",

            THREE.ShaderChunk[ "morphtarget_vertex" ],
            THREE.ShaderChunk[ "skinning_vertex" ],
            THREE.ShaderChunk[ "default_vertex" ],
            THREE.ShaderChunk[ "logdepthbuf_vertex" ],

        "   vViewPosition = -mvPosition.xyz;",

            THREE.ShaderChunk[ "worldpos_vertex" ],
            THREE.ShaderChunk[ "envmap_vertex" ],
            THREE.ShaderChunk[ "lights_phong_vertex" ],
            THREE.ShaderChunk[ "shadowmap_vertex" ],

        "   glassPos = worldPosition.xyz / worldPosition.w;", // <!-- I added this -->

        "}"

    ].join("\n"),

    fragmentShader: [

        "uniform vec3 diffuse;",
        "uniform float opacity;",

        "uniform vec3 ambient;",
        "uniform vec3 emissive;",
        "uniform vec3 specular;",
        "uniform float shininess;",

        THREE.ShaderChunk[ "color_pars_fragment" ],
        THREE.ShaderChunk[ "map_pars_fragment" ],
        THREE.ShaderChunk[ "alphamap_pars_fragment" ],
        THREE.ShaderChunk[ "lightmap_pars_fragment" ],
        THREE.ShaderChunk[ "envmap_pars_fragment" ],
        THREE.ShaderChunk[ "fog_pars_fragment" ],
        THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
        THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
        THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
        THREE.ShaderChunk[ "normalmap_pars_fragment" ],
        THREE.ShaderChunk[ "specularmap_pars_fragment" ],
        THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],

        "varying vec3 glassPos;", // <!-- I added this -->

        "void main() {",

        "   gl_FragColor = vec4( vec3( 1.0 ), opacity );",

        // <!-- I added this
        "   if(glassPos.x < 0.0) {",
        "      gl_FragColor = gl_FragColor * vec4( vec3( 1.0 ), 0.5 );//discard;",
        "   }",
        // end -->

            THREE.ShaderChunk[ "logdepthbuf_fragment" ],
            THREE.ShaderChunk[ "map_fragment" ],
            THREE.ShaderChunk[ "alphamap_fragment" ],
            THREE.ShaderChunk[ "alphatest_fragment" ],
            THREE.ShaderChunk[ "specularmap_fragment" ],
            THREE.ShaderChunk[ "lights_phong_fragment" ],
            THREE.ShaderChunk[ "lightmap_fragment" ],
            THREE.ShaderChunk[ "color_fragment" ],
            THREE.ShaderChunk[ "envmap_fragment" ],
            THREE.ShaderChunk[ "shadowmap_fragment" ],
            THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
            THREE.ShaderChunk[ "fog_fragment" ],

        "}"

    ].join("\n")

};

//console.log(shader.vertexShader);
//console.log(shader.fragmentShader);

var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
uniforms['diffuse'].value.setHex(0x00ff00);
uniforms['ambient'].value.setHex(0x002200);
uniforms['emissive'].value.setHex(0x000000);
uniforms['specular'].value.setHex(0x007f00);
uniforms['ambient'].value.convertGammaToLinear();

var parameters = {
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: uniforms,
    lights: true,
    fog: false,
    doubleSided: true,
    blending: THREE.NormalBlending,
    transparent: true,
    depthTest: true
};
var shaderMaterial = new THREE.ShaderMaterial( parameters );

var msh = new THREE.Mesh(geo, shaderMaterial);
scene.add(msh);

var m = new THREE.Mesh(geo, new THREE.MeshPhongMaterial({
    color: 0xff0000,
    ambient: 0x22000,
    emissive: 0x000000,
    specular: 0x7f0000
}));
m.scale.set(0.75, 0.75, 0.75);
scene.add(m);

animate();
}

function animate() {
light.position.copy(camera.position);

requestAnimationFrame(animate);
renderer.render(scene, camera);
controls.update();
}

init();

我做错了什么吗?我错过了什么?或者这是不可能的?

谢谢!

1 个答案:

答案 0 :(得分:2)

side: THREE.DoubleSide而非doubleSided: true

three.js r.68