有没有办法使用three.js获得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>
我的输出就像:
我想要的是:物体背面应该有一盏灯,物体的雕刻部分应该发光(相对于物体的深度)。
答案 0 :(得分:5)
这绝不是一个答案,但我认为最好的方法是编写(或查找)自定义着色器。我将在前言中说,编写着色器是不孩子的游戏:由于着色器编程语言相对较低并且严重依赖于深奥几何学的知识,它可能变得非常复杂数学
经过一些窥探之后,看起来你需要一个可以实现称为子表面散射(通常称为SSS)的着色器的着色器 - 这实际上是基于其厚度通过半透明物体的光的行为(和其他一些我不会钻研的属性:
为了实现Lithophane效果,您需要生成厚度图&#34;映射到对象网格的各种类型,然后自定义着色器将通过此贴图正确散射光线,以产生类似于您所需的效果。
我在DICE游戏中通过主要渲染程序员执行的主要simple presentation了解了所有这些。以下是演示文稿中的示例幻灯片:
此着色器实时产生类似于的效果
的效果:如果你真的想要达到这个效果,我真的建议你做一些关于Cg或GLSL着色器编程的阅读。我个人喜欢Cg,因为我因为它与Unity3D的兼容性而受到激励。出于这个原因,我找到了学习Cg的很好的资源,即the wikibook on the subject。它(有点)特定于Unity,但原则是合理的。
无论哪种方式,我都祝你好运。希望这有帮助!