Javascript 三种JS中的利托芬效应

Javascript 三种JS中的利托芬效应,javascript,3d,three.js,webgl,Javascript,3d,Three.js,Webgl,有没有办法使用three.js获得立石粉效果 目前我尝试了不同的透明和不透明材质,但没有成功 <html lang="en"> <head> <title>Lith (Three.js)</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimu

有没有办法使用three.js获得立石粉效果

目前我尝试了不同的透明和不透明材质,但没有成功

    <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>

Lith(Three.js)
var容器、场景、摄影机、渲染器、控件、统计信息;
var clock=新的三个时钟();
var立方;
init();
制作动画();
函数init()
{
//场面
场景=新的三个。场景();
//摄像机
变量SCREEN\u WIDTH=window.innerWidth,SCREEN\u HEIGHT=window.innerHeight;
可变视角=45,纵横比=屏幕宽度/屏幕高度,近=0.1,远=20000;
摄像机=新的三个透视摄像机(视角、方向、近距离、远距离);
场景。添加(摄影机);
相机位置设置(0150400);
摄像机。注视(场景。位置);
//渲染器
if(Detector.webgl)
renderer=new THREE.WebGLRenderer({antialas:true});
其他的
renderer=new THREE.CanvasRenderer();
设置大小(屏幕宽度、屏幕高度);
renderer.setClearColor(0x99999);
container=document.getElementById('ThreeJS');
container.appendChild(renderer.doElement);
//事件
三倍。窗口大小调整(渲染器、相机);
控件=新的三个.轨道控件(摄影机、渲染器.doElement);
//云台/雾
var skyBoxGeometry=新的三立方测量法(10000,10000,10000);
var skyBoxMaterial=new THREE.MeshBasicMaterial({color:0x9999ff,side:THREE.BackSide});
var skyBox=new THREE.Mesh(skyBoxGeometry,skyBoxMaterial);
//场景.添加(skyBox);
scene.fog=新的三个.FogExp2(0x9999ff,0.00025);
////////////
//习俗//
////////////
//必须在渲染器上启用阴影
renderer.shadowMapEnabled=true;
//“阴影摄影机”显示光源和方向
//聚光灯#1——黄色,暗影
var spotlight=新的三个聚光灯(0xffff00);
聚光灯位置设置(0150,-50);
spotlight.shadowCameravible=true;
聚光灯.阴影暗度=0.8;
1.2.2强度=2;
//必须为灯光启用阴影投射能力
spotlight.castShadow=true;
场景。添加(聚光灯);
var sphereSize=10;
var pointLightHelper=新的三个.SpotLightHelper(spotlight,sphereSize);
添加(pointLightHelper);
var灯光=新的三点聚光灯(0x99999);
光照强度=0.6;
相机。添加(灯光);
var loader=new THREE.STLLoader();
loader.load('./TestOriginal.stl',函数(对象){
网格对象=对象;
var color=新的三种颜色(0xffffff);
var材质=新的3.0网格材质({
颜色:颜色,白色,
三面,双面,
//着色:3.SmoothShading,
不透明度:0.6,
透明:正确
});
this.mesh=新的三个.mesh(对象、材质);
网格位置设置(0,0,0);
场景。添加(网格);
网格位置设置(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)*新闻缩放)/2);
mesh.translateZ(-(boundingBox.max.z+boundingBox.min.z)*新缩放)/2);
});
//地板:网格以接收阴影
var floorTexture=new THREE.ImageUtils.loadTexture('./checkboard.jpg');
floorTexture.wrapps=floorTexture.wrapT=THREE.RepeatWrapping;
地板结构。重复。设置(10,10);
//请注意对Lambert材质的更改。
var floorMaterial=new THREE.MeshLambertMaterial({map:floorTexture,side:THREE.DoubleSide});
var地板测量法=新的三平面几何(1000、1000、100、100);
var地板=新的三层网格(地板测量、地板材料);
楼层位置y=-80.5;
floor.rotation.x=Math.PI/2;
floor.receiveShadow=true;
场景。添加(楼层);
}
函数animate()
{
请求动画帧(动画);
render();
更新();
}
函数更新()
{   
控件更新();
}
函数render()
{
渲染器。渲染(场景、摄影机);
}
我的输出如下:

我还尝试了shader material,它为我提供了如下功能:


我想要的是:应该有一个从物体背面发出的光,物体的雕刻部分应该发光(相对于物体的深度)。

这绝不是一个答案,但我真的认为最好的方法是编写(或找到)一个自定义着色器。首先,我要说编写着色器不是儿戏:它可能变得极其复杂,因为着色器编程语言的级别相对较低,并且严重依赖于深奥的几何/数学知识


在一些窥探之后,看起来您需要一个着色器来实现所谓的亚表面散射(俗称SSS)——这本质上是光通过半透明对象的行为,基于其厚度(以及我将不深入讨论的一些其他属性):

要实现石粉效果,您需要生成一个映射到对象网格的“厚度贴图”,然后自定义着色器将光线正确地散射到此贴图,以产生类似于您所需的效果

所有这些我都是通过骰子游戏中主要由首席渲染程序员执行的一次演示学习到的。以下是演示文稿中的示例幻灯片:

此着色器根据厚度实时生成类似于此的效果:

如果你真的想达到这个效果,我会认真地建议你阅读Cg或GLSL着色器编程。就我个人而言,我喜欢Cg,因为它与Unity3D的兼容性激励我学习它。出于这个原因,我发现了一个学习Cg的好资源,即。是(某物)