2014-10-23 2 views
0

제 질문은 여러 부분으로 나누어 져 있습니다. 각자 고유 한 도전 과제를 제시하고 있습니다.지구를위한 쉐이더 만들기 밤낮으로 클릭 할 수있는 스프라이트 만들기

우선 : 하루에 지구와 밤에 지구를 혼합하는 쉐이더 (다양한 도시의 야간 조명)를 만들어야합니다. 나는이 주제에 관해서 이전에 대답 한 질문에서 본 기술을 시도했지만 그것은 나에게 도움이되지 못했다.

<script id="fragmentShader" type="x-shader/x-fragment"> 
    uniform sampler2D dayTexture; 
    uniform sampler2D nightTexture; 

    uniform vec3 sunDirection; 

    varying vec2 vUv; 
    varying vec3 vNormal; 

    void main(void) { 
     vec3 dayColor = texture2D(dayTexture, vUv).rgb; 
     vec3 nightColor = texture2D(nightTexture, vUv).rgb; 

     // compute cosine sun to normal so -1 is away from sun and +1 is toward sun. 
     float cosineAngleSunToNormal = dot(normalize(vNormal), sunDirection); 

     // sharpen the edge beween the transition 
     cosineAngleSunToNormal = clamp(cosineAngleSunToNormal * 10.0, -1.0, 1.0); 

     // convert to 0 to 1 for mixing 
     float mixAmount = cosineAngleSunToNormal * 0.5 + 0.5; 

     // Select day or night texture based on mix. 
     vec3 color = mix(nightColor, dayColor, mixAmount); 

     gl_FragColor = vec4(color, 1.0); 
     //gl_FragColor = vec4(mixAmount, mixAmount, mixAmount, 1.0); 
    } 
</script> 
<script id="vertexShader" type="x-shader/x-vertex"> 


     varying vec2 vUv; 
     varying vec3 vNormal; 

     void main() 
     { 
      vUv = uv; 
      vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 
      vNormal = normalMatrix * normal; 
      gl_Position = projectionMatrix * mvPosition; 
     } 


</script> 

<script> 


uniforms = { 
    sunDirection: { type: "v3", value: new THREE.Vector3(0,1,0) }, 
    dayTexture: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture("images/Color_Map.jpg") }, 
    nightTexture: { type: "t", value: 1, texture: THREE.ImageUtils.loadTexture("images/Night_Lights.jpg") } 
}; 

uniforms.dayTexture.texture.wrapS = uniforms.dayTexture.texture.wrapT = THREE.Repeat; 
uniforms.nightTexture.texture.wrapS = uniforms.nightTexture.texture.wrapT = THREE.Repeat; 





material = new THREE.ShaderMaterial({ 

    uniforms: uniforms, 
    vertexShader: document.getElementById('vertexShader').textContent, 
    fragmentShader: document.getElementById('fragmentShader').textContent 
    }); 

var controls = new THREE.TrackballControls(camera); 

webglEl.appendChild(renderer.domElement); 

render(); 

function render() { 
    controls.update(); 
    lexington_line.rotation.y += 0.0005; //0.0005 
    florida_line.rotation.y += 0.0005; // 0.0005 
    sphere.rotation.y += 0.0005; //0.0005 
    clouds.rotation.y += 0.0007; //0.0007  
    var t = Date.now() * 0.001; 
    uniforms.sunDirection.value.x = Math.sin(t); 
    uniforms.sunDirection.value.y = Math.cos(t); 
    requestAnimationFrame(render); 
    renderer.render(scene, camera); 
} 

function createSphere(radius, segments, material) { 
    return new THREE.Mesh(
     new THREE.SphereGeometry(radius, segments, segments), 
     new THREE.MeshPhongMaterial({ 
      map:   THREE.ImageUtils.loadTexture('images/Color_Map.jpg'), 
      bumpMap:  THREE.ImageUtils.loadTexture('images/elev_bump_4k.jpg'), 
      bumpScale: 0.005, 
      specularMap: THREE.ImageUtils.loadTexture('images/water_4k.png'), 
      specular: new THREE.Color('grey')       
     }) 
    ); 
} 

</script> 

내 두 번째 질문은 당신이 클릭 할 수있는 정신을 작성해야하고 사진을 (구현되지 않음) 내가 볼 때 나는 소리가 날 수 있도록 코드를 가지고 있지만 볼 수 있도록 그것은 카메라를 회전 : 관련 코드는 다음과 콘솔에서 제대로 작동하지 않는 것 같습니다. 가장 가까운 클릭은 곡면이 정확하게 향할 때만 정확합니다. 그러나 곡면이나 바로 위의 특정 위치에서 클릭하면 올바른 클릭 (교차 [0])을주지 않습니다. 관련 코드는 다음과 같습니다.

//Normal Lines. 


//Not sure if this is needed, Further testing required. 
//document.body.appendChild(renderer.domElement); 


//Lexington KY Location: Normal Line. 
var lex_normal = new THREE.Geometry(); 

var vertex = new THREE.Vector3(0.1, 1.0, 1.3); 
vertex.normalize(); 
vertex.multiplyScalar(0.5); 
lex_normal.vertices.push(vertex); 
var vertex2 = vertex.clone(); 
vertex2.multiplyScalar(2); 
lex_normal.vertices.push(vertex2); 
var lexington_line = new THREE.Line(lex_normal, new THREE.LineBasicMaterial({ color: 0xffffff, opacity:12 })); 
lexington_line.rotation.y = rotation; 
scene.add(lexington_line); 
lexington_line.onClick = function(){ 
    console.log('Target Normal: Lexington, KY USA'); 

    } 

//Miami FL:: TEST! 
var mia_normal = new THREE.Geometry(); 

var vertex = new THREE.Vector3(0.26, 1.0, 1.72); 
vertex.normalize(); 
vertex.multiplyScalar(0.3); 
mia_normal.vertices.push(vertex); 
var vertex2 = vertex.clone(); 
vertex2.multiplyScalar(2); 
mia_normal.vertices.push(vertex2); 
var florida_line = new THREE.Line(mia_normal, new THREE.LineBasicMaterial({ color: 0xffffff, opacity:12 })); 
florida_line.rotation.y = rotation; 
scene.add(florida_line); 
florida_line.rotation.y = rotation; 
florida_line.onClick = function(){ 
    console.log('Target Normal: Miami, FL USA'); 
} 

// Projector to generate the 3D coordinates from the click 
var projector = new THREE.Projector(); 

// push all the clickable objects into this array 
var clickableObjects = [];  
clickableObjects.push(lexington_line,florida_line); 

// Bind the mousedown handler 
document.addEventListener('mousedown', onDocumentMouseDown, false); 

function onDocumentMouseDown(event) { 
    event.preventDefault(); 

    // transforms the 2D click coordinates into a THREE.Vector3 for 3D coordinates 
    var vector = new THREE.Vector3((event.clientX/window.innerWidth) * 2 - 1, - ( event.clientY/window.innerHeight) * 2+1, 0.2); 
     projector.unprojectVector(vector, camera); 

    // casts a ray from the camera position directly to the calculated vector 
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position ).normalize()); 


    // iterates through the clickable objects and checks if they intersect with the ray 
    var intersects = raycaster.intersectObjects(clickableObjects); 

    if (intersects.length > 0) { 
    // The intersects array contains all the elements, 
    // that intersect with the casted ray. intersects[0] is the nearest object. 
    intersects[0].object.onClick(); 
    } 


} 

}()); 

질문이 명확하지 않은 경우 알려 주시면 답변 해 드리겠습니다.

감사합니다.

편집 : 첫 번째 질문에 대한 결과는 아무 것도 아닙니다. 나는 물질을 기능에 전달했지만, 물질을 어디에 두든 상관없이 원하는 효과가없는 것처럼 보입니다. 예를 들어 나는이처럼에 전달하는 경우 :

function createSphere(radius, segments, material) { 
    return new THREE.Mesh(
     new THREE.SphereGeometry(radius, segments, segments), 
     new THREE.MeshPhongMaterial({ 
      map:   THREE.ImageUtils.loadTexture('images/Color_Map.jpg'), 
      bumpMap:  THREE.ImageUtils.loadTexture('images/elev_bump_4k.jpg'), 
      bumpScale: 0.005, 
      specularMap: THREE.ImageUtils.loadTexture('images/water_4k.png'), 
      specular: new THREE.Color('grey')       
     }), material 
    ); 
} 

는 완전히 또는 같은 행성의 색상을 변경 :

function createSphere(radius, segments, material) { 
    return new THREE.Mesh(
     new THREE.SphereGeometry(radius, segments, segments), material, 
     new THREE.MeshPhongMaterial({ 
      map:   THREE.ImageUtils.loadTexture('images/Color_Map.jpg'), 
      bumpMap:  THREE.ImageUtils.loadTexture('images/elev_bump_4k.jpg'), 
      bumpScale: 0.005, 
      specularMap: THREE.ImageUtils.loadTexture('images/water_4k.png'), 
      specular: new THREE.Color('grey')       
     }) 
    ); 
} 

이 다시 색상을 변경하지만 다르게 상기 이외. 밤 시간에 야간 조명을 표시 할 수는 없습니다 (빛이없는 지역).

재 작성시 0.2에서 0.5로 고정되었지만 많은 부분이 해결되지 않은 것 같습니다. 이 문제는 선의 꼭대기에 있지 않으면 제대로 클릭하지 않는 한 계속 유지됩니다.

답변

0

1) 다른 질문이있는 경우 다른 스레드를여십시오.

2) Querstion 1에서 얻은 결과는 무엇입니까? 그냥 작동하지 않는다고 말하는 것만으로는 충분하지 않습니다.

3) 레이캐스팅에서 0.5가되어야하는 곳에 0.2가 있습니다.

var 벡터 = 새 THREE.Vector3 ((event.clientX/window.innerWidth) * 2 - 1, (event.clientY/window.innerHeight) * 2 + 1, 0.2);

나는이 있어야한다고 생각 :

VAR 벡터 = 새로운 THREE.Vector3 ((event.clientX/window.innerWidth) * 2 - 1, - (event.clientY/window.innerHeight) * 2 + 1 , 0.5);

관련 문제