2016-12-27 6 views
0

광선 효과가있는 json 모델을 장면에 추가합니다.three.js 장면에서 회전하는 json 모델의 광선 효과를 유지하는 방법은 무엇입니까?

으로 다음은 : enter image description here

나는 자동으로 JSON 모델을 회전하려고합니다. 그러나 회전 할 때 이상하게 보입니다. 모델의 광선 효과가 작동하지 않습니다. enter image description here enter image description here

나는이 모델이 회전 할 때 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입니다.

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

이 경우 코드를 어떻게 수정해야합니까? 여기에 Demosource code이 있습니다.

답변

1

내장 된 three.js 함수를 사용할 수 있습니다. 카메라 위치를 사용하는 대신 세계의 광원 위치를 설정하는 방법을 보여 주기로했습니다. 그렇게하면 맞춤 셰이더의 광원을 나중에 3D 세계에 추가 할 광원에 맞출 수 있습니다. 새 THREE.Vector3 (100,100,100) 대신 worldLightPoint 값을 camera.position으로 자유롭게 변경하십시오. 이 경우 효과는 카메라 위치에 따라 일정하게 유지됩니다.

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

팁 : 애니메이션 루프에서'new' 또는'clone()'을 호출하지 마십시오. 인스턴스를 만들고 다시 사용하십시오. 'copy()'를 사용하십시오. – WestLangley

+0

@WestLangley 권장 사항에 따라 변경되었습니다. 이해해 둡니다. – Radio

+0

부여 된 "올바른 방법"은 없지만이 패턴을 사용합니다 :'viewVector.value.copy (v)'. 너하기에 달렸다. :-) – WestLangley