Как сохранить эффект свечения модели json, вращающейся в сцене three.js?

Я добавляю в сцену модель JSON с эффектом свечения.

Следующее:

Я пытаюсь повернуть модель JSON автоматически. Тем не менее, это выглядит странно, когда он вращается. Эффект свечения модели не работает.

Я предполагаю, что положение модели json не изменяется при вращении этой модели. Как результат, viewVector.value ShaderMaterial является постоянным, когда эта модель вращается (я не меняю положение камеры).

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

}

Это Three.ShaderMaterial.

VertexShader и FragmentShader

<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
}
);

Как мне изменить код в этом случае? Вот демо и исходный код.

1 ответ

Решение

Для этого вы можете использовать встроенные функции three.js. Вместо того, чтобы использовать положение камеры, я решил показать вам, как установить положение источника света в мире. Таким образом, вы можете сопоставить источник света в вашем пользовательском шейдере с любыми источниками света, которые вы планируете добавить позже в свой трехмерный мир. Не стесняйтесь изменить значение 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));
    }
}
Другие вопросы по тегам