Three.js - 为什么这些项目的阴影看起来像这样?

2023-12-28

我正在学习 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">
</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>

如果您知道一个好的初学者 Three.js 教程或课程(我不在乎它是否免费),请告诉我,因为我对此有点迷失,并且像 Web 开发人员一样我很感兴趣在这个 webGL 世界中:)


您可以通过增加阴影贴图的大小(从而提高分辨率)来提高阴影的质量(请参见SpotLight https://threejs.org/docs/#api/lights/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 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.BoxGeometry( 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-->
<script src="https://cdn.jsdelivr.net/npm/[email protected] /cdn-cgi/l/email-protection/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected] /cdn-cgi/l/email-protection/examples/js/controls/OrbitControls.js"></script>
<div id="WebGL-salida">
</div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Three.js - 为什么这些项目的阴影看起来像这样? 的相关文章

  • 如何将 UIWebView 中的输入的键盘按钮“返回”更改为“搜索”?

    我有一个简单的 HTML 文件 它将显示在 UIWebView 中 p p
  • 为什么 AngularJS 在使用 ng-bind-html 时会去掉 data- 属性?

    我正在使用 contentEditable div 来使用户能够格式化他们的文章 我对html内容做了一些处理并保留它 我在用ng bind html当观众想要阅读文章时呈现结果 我不想使用 sce trustAsHtml因为我仍然希望 A
  • 如何在后台加载图像?

    问题 我正在创建一个专辑 所以每次按 时间 下一个 按钮我正在加载新图像 我想要实现的是 只有在新图像从服务器完全下载后 我才想从旧图像切换到新图像 实际上我不想在加载时显示部分图像 有什么解决办法吗 PS 类似的问题 https stac
  • 禁用 Ctrl + 滚动以缩放谷歌地图

    Does anybody know how to disable the CTRL Scroll First when the mouse wheel was moved the Map would Zoom in out But now
  • 如何在 guildMemberAdd 中使用awaitReactions

    当用户连接到我的服务器时 我向他们发送消息 并且我想通过单击反应来继续授权 我怎样才能创建这个 我正在使用以下代码 robot on guildMemberAdd gMembAdd gt gMembAdd send Hi gMembAdd
  • .getDay() 奇怪的行为[重复]

    这个问题在这里已经有答案了 有一个例子 console log new Date 2013 02 24 getDay 24 gt 0 24 console log new Date 2013 02 25 getDay 25 gt 1 25
  • Mocha / Chai Expect.to.throw 未捕获抛出的错误

    我在获取 Chai 时遇到问题expect to throw测试我的 node js 应用程序 测试在抛出的错误上不断失败 但是如果我将测试用例包装在 try 和 catch 中 并对捕获的错误进行断言 它就会起作用 Does expect
  • 重置输入控件的边框颜色 (HTML/Javascript)

    有谁知道使用 javascript 修改输入控件后如何重置它的边框颜色 通过突出显示其中包含不正确或无效数据的字段等来进行验证非常有用 例如 改变边框 document getElementById myinput style border
  • 错误:导航器只能包含“屏幕”组件作为其直接子组件

    我是 React Native 新手 收到此错误 但无法解决它 我正在遵循主要的教程反应导航页面 https reactnavigation org docs screen options resolution 但我无法完成它 我将不胜感激
  • Imperavi Redactor 内容未复制到隐藏文本区域

    我正在尝试使用因佩拉维编辑器 http imperavi com redactor 在这里控制我的富文本编辑 div class control group div class controls div div document ready
  • 如果只有一个元素发生变化,为什么 AngularJs 会更新数组/哈希映射的所有元素?

    我有一个简单的哈希图和一个以文本形式显示状态的简单方法 但是当我仅更新 1 个用户状态时 所有这些状态都会更新 为所有用户调用函数 有没有一种方法可以只更新一个元素而不是全部 示例代码在这里 只需看看当您单击 更改状态 按钮时控制台中会发生
  • JavaScript/Angular 1 - Promise.all 到 async-await

    我在两个变量中分配了对 Web 服务的两次调用referencesPromise and contactTypesPromise onInit 如果需要 我可以为此创建一个新方法 onInit const referencesPromise
  • 与玻璃钢战斗

    我读过有关 FRP 的内容 非常兴奋 它看起来很棒 因此您可以编写更多高级代码 并且一切都更加可组合 等等 然后我尝试用数百个 sloc 从纯 js 到 Bacon 重写我自己的小游戏 我发现 我实际上不是编写高级纯逻辑代码 而是击败了 B
  • 不明白为什么 Chrome/Safari 无法在此处获取 ScrollHeight

    我只是问了一个问题 为什么某些 js 代码不能 100 在 Chrome 和 Safari 中工作 但经过更多故障排除后 我想我发现这是我应该发布的问题 我有一个页面 其中有一个表单 该表单的目标是同一页面上的 iframe iframe
  • 更改导航栏悬停时 div 的背景图像

    我正在开发一个项目 我对 Javascript 很陌生 所以我想知道是否有 Jquery 代码或只是一个关于如何使背景图像在导航菜单悬停时更改的过程 例如将鼠标悬停在链接一上会将 div 的背景图像更改为图像 1 将鼠标悬停在链接二上会将
  • JavaScript 中的自定义“确认”对话框?

    我一直在开发一个使用自定义 模式对话框 的 ASP net 项目 我在这里使用吓人引号 因为我知道 模式对话框 只是我的 html 文档中的一个 div 它被设置为出现在文档其余部分的 顶部 而不是真正意义上的模式对话框 在网站的许多部分
  • 如何为 chrome 和 ie favicon(加载指示器)设置动画

    我的 PM 有一个要求 将图标更改为动画加载图像 仅当我将 link href 指向 gif 文件时 它才适用于 Firefox 我做了一些研究 发现 chrome 不支持动画图标 但wiki https en wikipedia org
  • 在没有全局变量的情况下对多个事件使用 Promise 回调

    我有一个包含在函数中的承诺 我将使用不同的输入参数多次调用该函数 每次承诺解决时 我都会将解决的值推送到存储数组中 当我所有的调用承诺都得到解决后 我将在其他函数中使用这个存储数组 是否有任何干净的方法可以在不使用 全局 变量的情况下进行设
  • Google Apps 脚本:如何水平对齐 inlineImage

    我有以下代码 它是一个更大程序的一部分 我正在尝试将图像从我的 Google 驱动器插入到 Google 文档中 并调整其大小并居中 到目前为止 我能够让程序插入图像并调整其大小 但我不知道如何使 inlineImage 居中 我是使用谷歌
  • 获取不正确的日期,将时间戳转换为新日期

    我正在尝试将时间戳转换为日期 但得到的日期不正确 我正在开发一个使用 Angular 和 Typescript 的项目 我有这样的时间戳 1451642400 2016年1月1日 和1454320800 2016年2月1日 如果我编码 da

随机推荐