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

问题描述 投票:0回答:1

我有一个简单的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>
javascript three.js webgl
1个回答
3
投票

实现预期效果的一种方法是通过toon shading。因此,给 网格卡通材料 试试。你也可以定义一个 梯度图 定义了材料的不同照明区域。

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/[email protected]/build/three.js"></script>

0
投票

您可以设置 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/[email protected]/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/[email protected]/build/three.js"></script>

请注意,上面的gradientMap是一个2x1像素的纹理,所以在面对光线和不面对光线之间的截止点将是50%。要移动截止点,可以把gradientMap做得更大。例如,一个5x1像素的纹理,有 black, black, white, white, white 四成黑,六成白

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/[email protected]/build/three.js"></script>

如果你想明确地设置这2种颜色,那么就把这2种颜色设置为 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: '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/[email protected]/build/three.js"></script>

如果你想要2种以上的颜色分割,那么在gradientMap中放入2种以上的颜色。

© www.soinside.com 2019 - 2024. All rights reserved.