2015-11-17 17 views
5

वहाँ एक रास्ता Three.jsLithophane प्रभाव

Sample image का उपयोग कर Lithophane असर पाने के लिए है।

वर्तमान में मैंने पारदर्शिता और अस्पष्टता के साथ विभिन्न सामग्रियों का प्रयास किया है लेकिन सफल नहीं हुए हैं।

<html lang="en"> 
<head> 
    <title>Lith (Three.js)</title> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> 

</head> 
<body> 

<script src="js/three.min.js"></script> 
<script src="./js/dat.gui.min.js"></script> 
<script src="./js/STLLoader.js"></script> 
<script src="js/Detector.js"></script> 
<script src="js/OrbitControls.js"></script> 
<script src="js/SkyShader.js"></script> 
<script src="js/THREEx.WindowResize.js"></script> 

<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div> 
<script> 
var container, scene, camera, renderer, controls, stats; 
var clock = new THREE.Clock(); 
var cube; 

init(); 
animate(); 

function init() 
{ 
    // SCENE 
    scene = new THREE.Scene(); 
    // CAMERA 
    var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; 
    var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH/SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000; 
    camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); 
    scene.add(camera); 
    camera.position.set(0,150,400); 
    camera.lookAt(scene.position); 
    // RENDERER 
    if (Detector.webgl) 
     renderer = new THREE.WebGLRenderer({antialias:true}); 
    else 
     renderer = new THREE.CanvasRenderer(); 
    renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); 
    renderer.setClearColor(0x999999); 
    container = document.getElementById('ThreeJS'); 
    container.appendChild(renderer.domElement); 
    // EVENTS 
    THREEx.WindowResize(renderer, camera); 

    controls = new THREE.OrbitControls(camera, renderer.domElement); 

    // SKYBOX/FOG 
    var skyBoxGeometry = new THREE.CubeGeometry(10000, 10000, 10000); 
    var skyBoxMaterial = new THREE.MeshBasicMaterial({ color: 0x9999ff, side: THREE.BackSide }); 
    var skyBox = new THREE.Mesh(skyBoxGeometry, skyBoxMaterial); 
    // scene.add(skyBox); 
    scene.fog = new THREE.FogExp2(0x9999ff, 0.00025); 

    //////////// 
    // CUSTOM // 
    //////////// 

    // must enable shadows on the renderer 
    renderer.shadowMapEnabled = true; 

    // "shadow cameras" show the light source and direction 

    // spotlight #1 -- yellow, dark shadow 
    var spotlight = new THREE.SpotLight(0xffff00); 
    spotlight.position.set(0,150,-50); 
    spotlight.shadowCameraVisible = true; 
    spotlight.shadowDarkness = 0.8; 
    spotlight.intensity = 2; 
    // must enable shadow casting ability for the light 
    spotlight.castShadow = true; 
    scene.add(spotlight); 

    var sphereSize = 10; 
    var pointLightHelper = new THREE.SpotLightHelper(spotlight, sphereSize); 
    scene.add(pointLightHelper); 


    var light = new THREE.SpotLight(0x999999); 
    light.intensity = 0.6; 
    camera.add(light); 

    var loader = new THREE.STLLoader(); 
    loader.load('./TestOriginal.stl', function(object) { 
     meshObject = object; 
     var color = new THREE.Color(0xffffff); 
     var material = new THREE.MeshPhongMaterial({ 
        color: color,//'white', 
        side: THREE.DoubleSide, 
        //shading: THREE.SmoothShading, 
        opacity: 0.6, 
        transparent: true 
       }); 
     this.mesh = new THREE.Mesh(object, material); 

     mesh.position.set(0,0,0); 
     scene.add(mesh); 

     mesh.position.set(0,0,0); 
     var newScale = 1; 
     mesh.geometry.computeBoundingBox(); 
     boundingBox = mesh.geometry.boundingBox; 
     mesh.translateX(-((boundingBox.max.x + boundingBox.min.x) * newScale)/2); 
     mesh.translateY(-((boundingBox.max.y + boundingBox.min.y) * newScale)/2); 
     mesh.translateZ(-((boundingBox.max.z + boundingBox.min.z) * newScale)/2); 
    }); 

    // floor: mesh to receive shadows 
    var floorTexture = new THREE.ImageUtils.loadTexture('./checkerboard.jpg'); 
    floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; 
    floorTexture.repeat.set(10, 10); 
    // Note the change to Lambert material. 
    var floorMaterial = new THREE.MeshLambertMaterial({ map: floorTexture, side: THREE.DoubleSide }); 
    var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 100, 100); 
    var floor = new THREE.Mesh(floorGeometry, floorMaterial); 
    floor.position.y = -80.5; 
    floor.rotation.x = Math.PI/2; 
    floor.receiveShadow = true; 
    scene.add(floor); 
} 

function animate() 
{ 
    requestAnimationFrame(animate); 
    render();  
    update(); 
} 

function update() 
{ 
    controls.update(); 
} 

function render() 
{ 
    renderer.render(scene, camera); 
} 

</script> 

</body> 
</html> 

और मेरे उत्पादन की तरह है:

output image

मैं भी शेडर सामग्री की कोशिश की है और यह मेरे जैसे कुछ देता है: Shadder output

क्या मैं चाहता है: वहाँ एक प्रकाश होना चाहिए वस्तु के पीछे से और वस्तु के उत्कीर्ण भाग को चमक (वस्तु की गहराई के संबंध में) होना चाहिए।

+0

यह वास्तव में एक दिलचस्प सवाल है। क्या आपने जीएलएसएल या सीजी में लिखे गए शेडर की तलाश करने की कोशिश की है, जो प्रभाव पैदा करता है? मैं निश्चित रूप से पूछने वाला व्यक्ति नहीं हूं, लेकिन एक लिखना संभव हो सकता है! शायद इसे किसी स्टैब दें/किसी और को ढूंढें (अधूरा या नहीं), और उसके बाद उस समस्या के लिए एक नया प्रश्न पूछें :) –

उत्तर

5

इसका कोई जवाब नहीं है, लेकिन मुझे सच में लगता है कि इसका सबसे अच्छा तरीका एक कस्टम शेडर लिखना (या ढूंढना) होगा। मैं यह कहकर इसका प्रस्ताव दूंगा कि लेखन शेडर बच्चे का खेल नहीं है: शेडर प्रोग्रामिंग भाषाओं अपेक्षाकृत कम स्तर के कारण और गूढ़ ज्यामिति/गणित के ज्ञान पर भारी निर्भर होने के कारण यह अविश्वसनीय रूप से जटिल हो सकता है।


कुछ स्नूपिंग के बाद, यह है कि आपके पास शेडर कि प्राप्त होता है कुछ कहा उप भूतल बिखराव (बोलचाल की भाषा एसएसएस के रूप में जाना जाता है) आवश्यकता होगी लगता है - इस पर आधारित है, एक पारदर्शी वस्तु के माध्यम से प्रकाश के व्यवहार अनिवार्य रूप से है इसके मोटाई (और कुछ अन्य गुण जो मैं में तल्लीन नहीं होगा):

Sub Surface Scattering (SSS)

एक Lithophane प्रभाव को प्राप्त करने के लिए, आप, एक तरह के "मोटाई नक्शा" है कि आपके वस्तु के जाल के लिए नक्शे उत्पन्न करने के लिए आवश्यकता होगी और उसके बाद कस्टम शेडर इस मानचित्र के माध्यम से प्रकाश को सही ढंग से तितर-बितर करेगा जिससे कि इसका प्रभाव उत्पन्न हो सके तुम्हारी कामना है।

मैंने यह सब मुख्य रूप से simple presentation के माध्यम से डीआईसीई गेम में लीड रेंडरिंग प्रोग्रामर द्वारा किए जाने से सीखा। यहाँ प्रस्तुति से एक उदाहरण स्लाइड है:

DICE Game's presentation of their SSS shader implementation

यह शेडर एक प्रभाव है कि इस जैसा दिखता है पैदा करता है, मोटाई पर आधारित है, वास्तविक समय में:

enter image description here

आप गंभीर हैं, तो इस प्रभाव को प्राप्त करने के बारे में, मैं गंभीरता से सीजी या जीएलएसएल शेडर प्रोग्रामिंग पर कुछ पढ़ने की सिफारिश करता हूं। व्यक्तिगत रूप से मुझे सीजी पसंद है, क्योंकि मुझे यूनिटी 3 डी के साथ इसकी संगतता के लिए इसे सीखने के लिए प्रोत्साहित किया गया था। इस कारण से, मुझे सीजी सीखने के लिए एक महान संसाधन मिला, अर्थात् the wikibook on the subject। यह (कुछ हद तक) एकता के लिए विशिष्ट है, लेकिन सिद्धांतों की आवाज होगी।

किसी भी तरह से मैं इस विषय पर आपको शुभकामनाएं देता हूं। उम्मीद है की यह मदद करेगा!

संबंधित मुद्दे