繁体   English   中英

在 three.js 中如何使球体上的光变锐利?

[英]In three.js how to make light on sphere sharp?

我有简单的 three.js 场景,带有球体和定向光。 在球体上,您可以看到它逐渐变暗。 如何更快地从明暗过渡。 如何让光线“更锐利”?

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 3; camera.position.z = 6; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshPhongMaterial({ color: 0x777777 }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 10, 10); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script>

实现预期效果的一种方法是通过卡通着色。 因此,试试MeshToonMaterial 您还可以定义一个渐变映射来定义材质的不同照明区域。

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 3; camera.position.z = 6; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshToonMaterial({ color: 0x777777 }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 10, 10); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>

您可以设置material.shininess 看到这个

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 1; camera.position.z = 2; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshPhongMaterial({ color: 0x777777, shininess: 400, }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 10, 10); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script>

即使使用MeshToonMaterial ,如果您不想要镜面高光,您也需要将shininess设置为 0

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 1; camera.position.z = 2; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshToonMaterial({ color: 0x777777, shininess: 0, }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 10, 10); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>

此外,除非您使用gradientMap映射,否则相对光量是硬编码的

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 0; camera.position.z = 2; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshToonMaterial({ color: 'red', shininess: 0, gradientMap: new THREE.DataTexture( new Uint8Array([ 0, // black (color away from light multiplied by color of material) 255, // white (color toward light multiplied by material ]), 2, // width of texture 1, // height of texture, THREE.LuminanceFormat, // format of texture ), }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(50, 50, 30); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>

请注意,上面的 gradientMap 是一个 2x1 像素纹理,因此在面向灯光和不面向灯光之间的截止值为 50%。 要移动截止点,请使 gradientMap 更大。 例如,具有black, black, white, white, white的 5x1 像素纹理将是 40% 黑色、60% 白色

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 0; camera.position.z = 2; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshToonMaterial({ color: 'red', shininess: 0, gradientMap: new THREE.DataTexture( new Uint8Array([ 0, // black (color away from light multiplied by color of material) 0, 255, // white (color toward light multiplied by material 255, 255, ]), 5, // width of texture 1, // height of texture, THREE.LuminanceFormat, // format of texture ), }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(50, 50, 30); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>

如果要显式设置 2 colors 则使gradientMap具有 colors 并将材质颜色设置为白色

 var scene, camera, renderer, controls, sphere, geometry, material, light; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 0; camera.position.z = 2; renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xffffff, 1); document.body.appendChild(renderer.domElement); geometry = new THREE.SphereGeometry(1, 32, 32); material = new THREE.MeshToonMaterial({ color: 'white', shininess: 0, gradientMap: new THREE.DataTexture( new Uint8Array([ 255, 0, 255, // purple (color away from light multiplied by color of material) 0, 255, 255, // cyan (color toward light multiplied by material ]), 2, // width of texture 1, // height of texture, THREE.RGBFormat, // format of texture ), }); sphere = new THREE.Mesh(geometry, material); scene.add(sphere); light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(50, 50, 30); scene.add(light); renderer.render(scene, camera);
 <script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>

如果您想要超过 2 个颜色/分区,则在 gradientMap 中放置超过 2 个 colors

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM