Three.js - 为什么这些项目的阴影看起来像这样? [英] Three.js - Why is the shadow of these items looking like this?

查看:47
本文介绍了Three.js - 为什么这些项目的阴影看起来像这样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习three.js.

我举了一个例子来练习,但物品的阴影看起来不对或奇怪.

应该是这样的(这个图片是旧教程的):

代码是这样的:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js"></script><div id="WebGL-salida">

<script type="text/javascript">$(函数(){var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);var renderer = new THREE.WebGLRenderer();var color = new THREE.Color("rgb(200, 250, 250)");renderer.setClearColor(new THREE.Color(color));renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;//默认 THREE.PCFShadowMapvar ejesAyuda = new THREE.AxesHelper(20);//son los ejes de ayuda creo场景添加(ejesAyuda);var planeGeometry = new THREE.PlaneGeometry(60, 20);var planeMaterial = new THREE.MeshLambertMaterial({颜色:0xcccccc});var plane = new THREE.Mesh(planeGeometry, planeMaterial);平面.receiveShadow = true;plane.rotation.x = -0.5 * Math.PI;//-90º平面.位置.x = 15;平面.位置.y = 0;平面.位置.z = 0;场景.添加(平面);var cubeGeometry = new THREE.CubeGeometry(4, 4, 4);var cubeMaterial = new THREE.MeshLambertMaterial({颜色:0xff0000});var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);立方体.castShadow = true;//con esto le indicamos que queremos que emita sombra立方体.位置.x = -4;立方体.位置.y = 3;立方体.位置.z = 0;场景.添加(立方体);var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);var sphereMaterial = new THREE.MeshLambertMaterial({颜色:0x7777ff});var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);sphere.castShadow = true;//con esto le indicamos que queremos que emita sombrasphere.position.x = 20;sphere.position.y = 4;sphere.position.z = 2;场景添加(球体);camera.position.x = -30;相机位置 y = 40;相机.位置.z = 30;相机.看(场景.位置);var spotLight = new THREE.SpotLight(0xffffff, 0.8);spotLight.position.set(-40, 60, -10);spotLight.castShadow = true;场景添加(聚光灯);$("#WebGL-salida").append(renderer.domElement);renderer.render(场景,相机);});</script>

如果你知道一个好的初学者three.js教程或课程(我不在乎它不是免费的),请告诉我,因为我有点迷失在这方面,就像网络开发人员一样对这个 webGL 世界很感兴趣 :)

解决方案

您可以通过增加阴影贴图的大小来提高阴影的质量(参见 SpotLight):

var spotLight = new THREE.SpotLight(0xffffff, 0.8);spotLight.position.set(-40, 60, -10);spotLight.castShadow = true;spotLight.shadow.mapSize.width = 2048;spotLight.shadow.mapSize.height = 2048;

通过限制光斑的光锥角可以进一步提高质量:

spotLight.angle = Math.PI/8.0;

注意,这会导致阴影贴图的分辨率增加,阴影贴图映射到的区域减少.

查看代码片段:

var 渲染器、相机、场景、控件;var init = 函数 (){场景 = 新的 THREE.Scene();camera = new THREE.PerspectiveCamera (45, window.innerWidth/window.innerHeight, 0.1, 1000);renderer = new THREE.WebGLRenderer();控件 = 新的 THREE.OrbitControls(camera, renderer.domElement);var color = new THREE.Color("rgb(200, 250, 250)");renderer.setClearColor(new THREE.Color(color));renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;//默认 THREE.PCFShadowMapvar ejesAyuda = new THREE.AxesHelper(20);//son los ejes de ayuda creo场景添加(ejesAyuda);var planeGeometry = new THREE.PlaneGeometry(60, 20);var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});var plane = new THREE.Mesh(planeGeometry, planeMaterial);平面.receiveShadow = true;plane.rotation.x = -0.5*Math.PI;//-90º平面.位置.x = 15;平面.位置.y = 0;平面.位置.z = 0;场景.添加(平面);var cubeGeometry = new THREE.CubeGeometry(4, 4, 4);var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);立方体.castShadow = true;//con esto le indicamos que queremos que emita sombra立方体.位置.x= -4;立方体.位置.y = 3;立方体.位置.z = 0;场景.添加(立方体);var sphereGeometry = new THREE.SphereGeometry (4, 20, 20);var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});var sphere = new THREE.Mesh (sphereGeometry, sphereMaterial);sphere.castShadow = true;//con esto le indicamos que queremos que emita sombrasphere.position.x = 20;sphere.position.y = 4;sphere.position.z = 2;场景添加(球体);camera.position.x = -30;相机位置 y = 40;相机.位置.z = 30;相机.看(场景.位置);var spotLight = new THREE.SpotLight(0xffffff, 0.8);spotLight.position.set(-40, 60, -10);spotLight.castShadow = true;spotLight.angle = Math.PI/8.0;spotLight.shadow.mapSize.width = 2048;spotLight.shadow.mapSize.height = 2048;场景添加(聚光灯);document.getElementById("WebGL-salida").append(renderer.domElement);调整大小();window.onresize = 调整大小;};函数动画(){requestAnimationFrame( 动画 );renderer.render(场景,相机);}函数调整大小(){renderer.setSize(window.innerWidth, window.innerHeight);camera.aspect = window.innerWidth/window.innerHeight;相机.updateProjectionMatrix();//controls.handleResize();}在里面();animate();

<script src="https://threejs.org/build/three.min.js"></script><script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script><div id="WebGL-salida">

I'm learning about three.js.

I make a example to practise but the shadow of the items is looking wrong or stranger.

Should be like this (this image is of a old tutorial):

And the code is this:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js"></script>

<div id="WebGL-salida">
</div>

<script type="text/javascript">
  $(function() {
    var scene = new THREE.Scene();

    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

    var renderer = new THREE.WebGLRenderer();

    var color = new THREE.Color("rgb(200, 250, 250)");
    renderer.setClearColor(new THREE.Color(color));
    renderer.setSize(window.innerWidth, window.innerHeight);

    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap


    var ejesAyuda = new THREE.AxesHelper(20); //son los ejes de ayuda creo
    scene.add(ejesAyuda);

    var planeGeometry = new THREE.PlaneGeometry(60, 20);

    var planeMaterial = new THREE.MeshLambertMaterial({
      color: 0xcccccc
    });

    var plane = new THREE.Mesh(planeGeometry, planeMaterial);

    plane.receiveShadow = true;


    plane.rotation.x = -0.5 * Math.PI; // -90º
    plane.position.x = 15;
    plane.position.y = 0;
    plane.position.z = 0;

    scene.add(plane);


    var cubeGeometry = new THREE.CubeGeometry(4, 4, 4);


    var cubeMaterial = new THREE.MeshLambertMaterial({
      color: 0xff0000
    });
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

    cube.castShadow = true; //con esto le indicamos que queremos que emita sombra

    cube.position.x = -4;
    cube.position.y = 3;
    cube.position.z = 0;

    scene.add(cube);

    var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
    var sphereMaterial = new THREE.MeshLambertMaterial({
      color: 0x7777ff
    });
    var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

    sphere.castShadow = true; //con esto le indicamos que queremos que emita sombra

    sphere.position.x = 20;
    sphere.position.y = 4;
    sphere.position.z = 2;
    scene.add(sphere);

    camera.position.x = -30;
    camera.position.y = 40;
    camera.position.z = 30;
    camera.lookAt(scene.position);

    var spotLight = new THREE.SpotLight(0xffffff, 0.8);
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true;
    scene.add(spotLight);

    $("#WebGL-salida").append(renderer.domElement);
    renderer.render(scene, camera);
  });
</script>

And please, if you know about a good beginner three.js tutorial or course (I don't care if it isn't free), tell me, because i'm a bit lost in this and like web developer i'm interested in this webGL world :)

解决方案

You can improve the quality of the shadow by increasing the size of the shadow map (See SpotLight):

var spotLight = new THREE.SpotLight(0xffffff, 0.8);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;

spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;

The quality can be increased further by restricting the light cone angle of the spot:

spotLight.angle = Math.PI / 8.0;

Note, this causes that the resolution of the shadow map is increased and the area, where the shadow map is mapped to is decreased.

See the code snippet:

var renderer, camera, scene, controls;

var init = function (){
  scene  = new THREE.Scene();
  camera = new THREE.PerspectiveCamera (45, window.innerWidth/window.innerHeight, 0.1, 1000); 
  renderer = new THREE.WebGLRenderer(); 
  controls = new THREE.OrbitControls( camera, renderer.domElement );

  var color = new THREE.Color("rgb(200, 250, 250)");
  renderer.setClearColor(new THREE.Color(color));
  renderer.setSize(window.innerWidth, window.innerHeight);

  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap


  var ejesAyuda = new THREE.AxesHelper(20); //son los ejes de ayuda creo
  scene.add(ejesAyuda); 

  var planeGeometry = new THREE.PlaneGeometry(60, 20);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});

  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;
  plane.rotation.x = -0.5*Math.PI; // -90º
  plane.position.x = 15;
  plane.position.y = 0;
  plane.position.z = 0;
  scene.add(plane);


  var cubeGeometry = new THREE.CubeGeometry( 4, 4, 4);
  var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
  var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.castShadow = true; //con esto le indicamos que queremos que emita sombra
  cube.position.x= -4;
  cube.position.y = 3;
  cube.position.z = 0;
  scene.add(cube);

  var sphereGeometry = new THREE.SphereGeometry (4, 20, 20);
  var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});
  var sphere = new THREE.Mesh (sphereGeometry, sphereMaterial);
  sphere.castShadow = true; //con esto le indicamos que queremos que emita sombra
  sphere.position.x = 20;
  sphere.position.y = 4;
  sphere.position.z = 2;
  scene.add(sphere);

  camera.position.x = -30;
  camera.position.y = 40;
  camera.position.z = 30;
  camera.lookAt(scene.position); 

  var spotLight = new THREE.SpotLight(0xffffff, 0.8);
  spotLight.position.set(-40, 60, -10);
  spotLight.castShadow = true;
  spotLight.angle = Math.PI / 8.0;
  spotLight.shadow.mapSize.width = 2048;
  spotLight.shadow.mapSize.height = 2048;
  scene.add(spotLight);

  document.getElementById("WebGL-salida").append(renderer.domElement);
  resize();
  window.onresize = resize;
};

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

function resize() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
//controls.handleResize();
}

init();
animate();

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="WebGL-salida">
</div>

这篇关于Three.js - 为什么这些项目的阴影看起来像这样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆