具有反射问题Three.js的片段着色器

时间:2018-09-26 12:16:23

标签: javascript three.js glsl gltf

without reflection

我有带有纹理和PBR效果的gltf CUP模型。我想应用环境反射(Cubereflection)。应用反射时遇到问题。颜色和纹理已更改,仅环境反射即将到来。我无法解决此问题。我的着色器在哪里出错或其他问题。我对着色器程序了解不多。我应该如何通过反射获得适当的颜色(如第一张图像)。我附上了两张没有反射和有反射的图像。反射效果很好,但是不知道为什么这种正确的颜色没有出现。请帮忙?

   my shader programme.
        var meshlambert_vert =
        varying vec3 vReflect;
        varying vec3 vRefract[3];
        varying float vReflectionFactor;
        attribute vec3 a_normal;
        varying vec3 v_normal;
        varying vec3 v_position;
        uniform mat3 u_normalMatrix;
        void main() {
                vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
                v_position = mvPosition.xyz;
                vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
                vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
                vec3 I = worldPosition.xyz - cameraPosition;
                vReflect = reflect( I, worldNormal );
                v_normal = u_normalMatrix * a_normal;
                vRefract[0] = refract( normalize( I ), worldNormal, 0.02 );
                vRefract[1] = refract( normalize( I ), worldNormal, 0.02 * 0.2);
                vRefract[2] = refract( normalize( I ), worldNormal, 0.02 * 0.2 );
                vReflectionFactor = 0.1 + 1.0 * pow( 1.0 + dot( normalize( I ), worldNormal ), 0.2 );
                gl_Position = projectionMatrix * mvPosition;
        };


var meshlambert_frag =
    uniform samplerCube tCube;
    varying vec3 vReflect;
    varying vec3 vRefract[3];
    varying float vReflectionFactor;
    uniform vec4 u_ambient;
    uniform vec4 u_emission;
    uniform vec4 u_specular;
    uniform vec4 u_diffuse;
    varying vec3 v_normal;
    varying vec3 v_position;
    void main() {
        vec4 color = vec4(0., 0.29411,0.47843, 1.0);
        vec3 diffuseLight = vec3(0., 0., 0.);
        vec3 u_light2Color = vec3(1.0,1.0,1.0);
        vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
        vec3 specularLight = vec3(0.5, 0.5,0.5);
        float specularIntensity = 0.5;
        float attenuation = 0.5;
        vec3 l = vec3(0.0,0.5,0.5);
        vec3 u_light0Color = vec3(1.0,1.0,1.0);
        vec4 emission;
        vec4 ambient;
        vec4 specular;
        ambient = u_ambient;
        diffuse = u_diffuse;
        emission = u_emission;
        specular = u_specular;
        vec3 ambientLight = vec3(0., 0., 0.);
        ambientLight += u_light2Color;
        ambient.xyz *= ambientLight;
        color.xyz += ambient.xyz;
        specularLight += u_light0Color * specularIntensity;
        specular.xyz *= specularLight;
        color.xyz += specular.xyz;
        vec3 normal = normalize(v_normal);
        if ( dot( normal, v_position ) > 0.0 ) {
            normal *= -1.0;
        }
        diffuseLight += u_light0Color * max(dot(normal,l), 0.) * attenuation;
        diffuse.xyz *= diffuseLight;
        color.xyz += diffuse.xyz;
        color.xyz += emission.xyz;
        vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );
        vec4 refractedColor = vec4( 0.0 );
        refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;
        refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;
        refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;
        gl_FragColor = mix( color, reflectedColor, clamp( 0.98, 0.0, 1.0 ) );
    }";

具有反射功能的立方映射代码:Aftre reflection

var loader = new THREE.CubeTextureLoader();
        loader.setPath( 'textures/env1/' );

        var textureCube = loader.load( [
            'posx.jpg', 'negx.jpg',
            'posy.jpg', 'negy.jpg',
            'posz.jpg', 'negz.jpg'
        ] );
    textureCube.mapping = THREE.CubeReflectionMapping;

    var cubeShader = THREE.ShaderLib[ "cube" ];
    var cubeMaterial = new THREE.ShaderMaterial( {
            fragmentShader: cubeShader.fragmentShader,
            vertexShader: cubeShader.vertexShader,
            uniforms: cubeShader.uniforms,
            depthWrite: false,
            side: THREE.BackSide
        } );

        cubeMaterial.uniforms[ "tCube" ].value = textureCube;

    cubeMesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 100, 100, 100 ), cubeMaterial );
    scene.add( cubeMesh );
var sphereMaterial=new THREE.MeshLambertMaterial( {envMap: textureCube } );
                    object.traverse( function ( child ) {
                        if ( child instanceof THREE.Mesh ) {
                             child.material = sphereMaterial;

                         }
                     } );

1 个答案:

答案 0 :(得分:2)

您以98:2的恒定比率混合反射颜色和材料的颜色

gl_FragColor = mix( color, reflectedColor, clamp( 0.98, 0.0, 1.0 ) );

材料的颜色成分很弱,无法“看到”它。

出于调试原因,尝试按50:50的比例进餐:

gl_FragColor = mix( color, reflectedColor, 0.5 );

但是您可能希望我们vReflectionFactor来获得比率:

gl_FragColor = mix( color, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );

请注意,如果您使用vReflectionFactor,则只会看到反射,因为结果是

vReflectionFactor = 0.1 + 1.0 * pow( 1.0 + dot( normalize( I ), worldNormal ), 0.2 );

始终大于1.0。这是因为1.0 + dot( normalize( I ), worldNormal比1.0高。

我不知道您想要实现什么,但是您可以使用

vReflectionFactor = 0.1 + pow( dot(normalize(I), worldNormal), 0.2 );

vReflectionFactor = 0.1 + pow( 1.0 - dot(normalize(I), worldNormal), 0.2 );