如何保持 json 模型在 three.js 场景中旋转的发光效果?

How to maintain the glow effect of a json model rotating in three.js scene?

我在场景中添加了一个 json 具有发光效果的模型。

如下:

我尝试自动旋转 json 模型。 但是,旋转时看起来很奇怪。 模型的发光效果不起作用。

我假设json模型在旋转时不会改变模型的位置。结果,当这个模型旋转时,ShaderMaterial 的 viewVector.value 是恒定的(我不改变相机的位置)。

if(jsonMesh){
    jsonMesh.rotation.y += 0.1;
    jsonMesh.material.uniforms.viewVector.value =
        new THREE.Vector3().subVectors( camera.position, jsonMesh.position );

}

这是Three.ShaderMaterial。

顶点着色器和片段着色器

<script id="vertexShader" type="x-shader/x-vertex">
    uniform vec3 viewVector;
    uniform float c;
    uniform float p;
    varying float intensity;
    void main()
    {
        vec3 vNormal = normalize( normalMatrix * normal );
        vec3 vNormel = normalize( normalMatrix * viewVector );
        intensity = pow( c - dot(vNormal, vNormel), p );

        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
</script>

<script id="fragmentShader" type="x-shader/x-fragment"> 
    uniform vec3 glowColor;
    varying float intensity;
    void main() 
    {
        vec3 glow = glowColor * intensity;
        gl_FragColor = vec4( glow, 1.0 );
    }
</script>

Three.ShaderMaterial.

var customMaterial = new THREE.ShaderMaterial( 
{
    uniforms: 
    { 
        "c":   { type: "f", value: 1.0 },
        "p":   { type: "f", value: 1.4 },
        glowColor: { type: "c", value: new THREE.Color(0xffff00) },
        viewVector: { type: "v3", value: camera.position }
    },
    vertexShader:   document.getElementById( 'vertexShader'   ).textContent,
    fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
    side: THREE.FrontSide,
    blending: THREE.AdditiveBlending,
    transparent: true
}
);

这种情况下应该如何修改代码? 这里是 Demo and source code.

您可以为此使用内置的 three.js 函数。我没有使用相机位置,而是选择向您展示如何在世界中设置光源位置。这样您就可以将自定义着色器上的光源与您计划稍后添加到 3d 世界的任何光源相匹配。随意将 worldLightPoint 值更改为 camera.position 而不是新的 THREE.Vector3(100,100,100)。在这种情况下,效果将随着相机位置的变化而保持不变。

var v = new THREE.Vector3();
//var worldLightPoint =  camera.position;
var worldLightPoint = new THREE.Vector3(100,100,100);
function update()
{
    controls.update();
    stats.update();
    if(jsonMesh){
        jsonMesh.rotation.y += 0.1;
        jsonMesh.material.uniforms.viewVector.value = jsonMesh.worldToLocal(v.copy(worldLightPoint));
    }
}