我目前正在研究光线投射和体素,这是一个很好的组合.Sebastian Scholz的Voxelrenderer很好地实现了这一点,但也使用了OpenGL.我想知道他的配方是如何工作的; 你如何使用OpenGL与光线投射和体素?光线投射的想法是不是为每个像素(或线,即在Doom中)投射光线然后绘制结果?
我试图检测用户何时在我的3D场景中点击了一个特定的立方体我看到了一些类似的问题,但似乎没有一个像我一样的问题.
我有一个3D数组的立方体,填充和显示正常,但当我的鼠标按下功能被调用时,相交数组总是空的 - 我看不出有什么问题,并希望得到任何帮助.
我的渲染器设置如下:
function setupRenderer()
{
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColorHex( 0xEEEEEE, 1 );
renderer.domElement.addEventListener( 'mousedown', onDocumentMouseMove, false );
$('body').append(renderer.domElement);
}
Run Code Online (Sandbox Code Playgroud)
并且事件处理程序是:
function onDocumentMouseDown(event)
{
console.log("mouse clicked!");
event.preventDefault();
if(event.target == renderer.domElement)
{
var mouseX = (event.clientX / window.innerWidth)*2-1;
var mouseY = -(event.clientY /window.innerHeight)*2+1;
var vector = new THREE.Vector3(mouseX, mouseY, 0.5);
projector.unprojectVector(vector, camera);
var raycaster = new THREE.Raycaster(camera.position, vector.subSelf(camera.position).normalize());
var intersects = raycaster.intersectObjects(cubes);
console.log("intersects.length: " + intersects.length);
if ( intersects.length > 0 ) {
console.log("intersected objects"); …Run Code Online (Sandbox Code Playgroud) 我有一个threejs场景,对象的交叉检查.我将每个场景对象添加到数组中,然后由raycaster检查.
var intersects = raycaster.intersectObjects( scene.children );
Run Code Online (Sandbox Code Playgroud)
然后,我检查对象的颜色,并在与鼠标指针接触时更改它.
INTERSECTED.material.emissive.setHex( 0xff0000 );
Run Code Online (Sandbox Code Playgroud)
如果我向场景添加一个辅助对象,比如CameraHelper或GridHelper,我会得到常量错误,因为.getHex .setHex辅助对象是不可能的.
是否可以从此检查中排除辅助对象,我该怎么做?
它必须是scene.children- scene.helpers,但我无法想出办法.谢谢您的帮助.
我正在开发用于HTML5画布的基本光线投射引擎,作为学习练习/爱好项目,该引擎用于诸如Wolfenstein 3D和Doom之类的游戏。我已经到了要在画布上使用纹理贴图渲染墙壁的位置,经过大量的工作才能正确完成交点测试功能,该效果很好。
我正在校正“鱼缸” /“鱼眼”变形效果(由于与屏幕中心的夹角增加而导致到相交点的距离增加),但是边缘仍然有非常轻微但明显的弯曲变形屏幕的 可以在下图中看到(我画了红色的直线,使效果更明显):

谁能弄清楚这种失真的根源是什么?这不是一个大问题,但我无法找出原因,因此我显然缺少了一些东西,并且我敢肯定有人必须知道答案。我已经广泛搜索了该问题,并且在线上没有太多信息,但是我确实在论坛帖子中找到了以下代码段:
“使用恒定角度增量而不是地平线投影而引起的翘曲完全是另一回事-那是横向拉伸/聚束效果,尽管通常情况下,这只是勉强可以察觉的效果(对于合理的FOV,尽管您可以定义999999度FOV的事实应该敲响钟声),根本没有任何合理的方法可以补偿,除了正确的开始。使用固定的增量,角度是错误的,仅此而已。”
听起来好像是我遇到的相同失真,但是除了提示固定角度增量是问题的根源(它是弯曲失真,向屏幕边缘逐渐增加)以外,它并没有提供太多帮助或见解。 ,这似乎符合此建议)。我用来纠正失真的函数是:
function m_CorrectRayLengthDistortion( dist, angleFromCentre ){
return dist * Math.cos( MOD_Maths.degToRad( angleFromCentre ) );
}
Run Code Online (Sandbox Code Playgroud)
MOD_Maths是一个实用程序模块(在这种情况下,用于将角度从度转换为弧度,以便余弦函数可以使用它)。
非常感谢您提供任何帮助,并且如果有人回答此问题,则由于在线上缺少有关该主题的信息,因此希望将来对遇到此问题的任何人提供指导。
谢谢 :)
我试图确定空间中的某个点是否对相机可见或隐藏在场景中其他对象后面。我通过从相机位置向空间中的该点投射光线并测试该光线是否与一组可相交的对象相交来实现此目的。
我的问题是,在相机位置本身与可相交对象集中的一个对象相交之前,不会发生相交。
我创建了一个 jsfiddle,其中如果检测到交叉点,则会从相机位置到我正在测试可见性的空间位置绘制一条线。目前我认为,该线仅在相机位置与可相交对象集相交的特定点处绘制。
如何让相交按应有的方式进行注册,而不必使相机位置与可相交对象集中的对象相交?
代码:
var container;
var camera, controls, scene, renderer;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
controls = new THREE.OrbitControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [65, 83, 68];
controls.addEventListener('change', render);
// world
scene = new THREE.Scene();
var testObject_G = new THREE.CubeGeometry(100, 100, 5);
var testObject_M = new THREE.MeshBasicMaterial({ …Run Code Online (Sandbox Code Playgroud) 我正在尝试制作台球游戏,我想计算主球(白球)击中另一个球后的移动方向。
正如你所看到的,我想计算射线击中球的角度/方向以及射线投射将改变其方向的角度/方向。我需要将角度显示为 Vector3 变量,以便我可以在linerenderer(3) 上使用它。
我已经计算出被击中的球将移动的方向。
如果你能在这方面帮助我那就太好了!
当前代码:
RaycastHit hitz;
if (Physics.SphereCast(transform.position, 0.8f, location - transform.position, out hitz, Mathf.Infinity, lmm2))
{
lineRenderer2 = hitz.collider.GetComponentInChildren<LineRenderer>();
lineRenderer2.SetVertexCount(2);
if (!Input.GetKey(KeyCode.Mouse0))
lineRenderer2.SetPosition(0, hitz.point);
if (!Input.GetKey(KeyCode.Mouse0))
{
Vector3 start = hitz.point;
Vector3 end = start + (-hitz.normal * 4);
if (lineRenderer2)
{
if (!Input.GetKey(KeyCode.Mouse0))
lineRenderer2.SetPosition(1, end);
}
if(lineRenderer3)
{
anglelel = Vector3.Angle(hitz.normal, hitz.point);
Vector3 cross = Vector3.Cross(hitz.normal, hitz.point);
if(cross.y > 0)
{
tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward;
}
if (cross.y < 0)
{
anglelel = …Run Code Online (Sandbox Code Playgroud) 我有两个任意点V1和V2.我定义了从V1到V2的光线,我想找到光线撞击平面的确切位置.当我运行我的代码时,命中位置落在错误的位置!如您所见,绿色球体显示的光线碰撞位置与V1和V2不对齐.

using UnityEngine;
using System.Collections;
public class RaycastLearning : MonoBehaviour {
// Use this for initialization
Vector3 v1;
Vector3 v2;
float MoveToLeft = 5f;
void Start () {
GameObject plane = GameObject.CreatePrimitive (PrimitiveType.Plane);
plane.transform.rotation = Quaternion.AngleAxis (90f, Vector3.right);
plane.transform.position = new Vector3 (MoveToLeft, 0, 5);
v2 = new Vector3 (MoveToLeft, 0f, -10f);
v1 = new Vector3 (MoveToLeft, 0f, 10f);
GameObject SV1 = GameObject.CreatePrimitive (PrimitiveType.Sphere);
SV1.transform.position = v1;
SV1.name = "SV1";
GameObject SV2 = GameObject.CreatePrimitive (PrimitiveType.Sphere);
SV2.transform.position = v2;
SV2.name = …Run Code Online (Sandbox Code Playgroud) 我已经设置了一个简单的场景,我将相机放在球体几何体内
var mat = new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('0.jpg') , overdraw:true, color: 0xffffff, wireframe: false });
var sphereGeo = new THREE.SphereGeometry(1000,50,50);
var sphere = new THREE.Mesh(sphereGeo,mat);
sphere.scale.x = -1;
sphere.doubleSided = false;
scene.add(sphere);
Run Code Online (Sandbox Code Playgroud)
我设置了一个功能,我可以在那个球体内部环顾四周,我的观点是能够在鼠标上投射光线,击中球体并获得发生击中的坐标.我正在投射一条光线但是相交仍然是空的.
var vector = new THREE.Vector3();
vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
vector.unproject( camera );
raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize());
var intersects = raycaster.intersectObjects(scene.children, true);
Run Code Online (Sandbox Code Playgroud)
一切都适用于测试立方体也放在我的球体内.我的问题是,你是从内部击中物体还是不击中物体是否重要?因为这是我脑海中唯一的解释.
提前致谢.
我有一个函数,检查游戏对象是否可以看到另一个游戏对象,而不会阻止其视图:
public bool CheckVision(GameObject target)
{
RaycastHit2D ray = (Physics2D.Raycast(transform.position, target.transform.position - transform.position, m_VisionRange));
if(ray.collider.name == target.name)
{
Debug.DrawRay(transform.position, target.transform.position - transform.position);
return true;
}
else
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是我不希望它与设置了"isTrigger"标志的碰撞器碰撞; 我希望raycast能够忽略它们.有任何想法吗?
我不确定如何做到这一点。我阅读了很多关于光线投射的内容,这似乎有助于找到与某物相交的点,但在这种情况下,我只想将 2d 鼠标坐标插入到 3d 点鼠标点击的确切位置,无论缩放、旋转、那里是否有对象等。
我已经想到但没有接近的一种方法是制作一个平行于相机的隐形平面,始终垂直定向并始终与 y 轴相交。然后使用光线投射器击中飞机,根据需要绘制,然后删除飞机。不过,这似乎是一种愚蠢的方法。
目前我有一种方法效果很好,但是当线条远离原点或相机放大时会出现一些问题
在这张照片中,我从两个不同的角度画了两条线。垂直线是相机与 x 轴和 z 轴水平时的样子,我在 y 轴上画一条直线,而水平线是我在相机朝下涂鸦时发生的情况。 https://i.imgur.com/f8qw5xV.png
可以看到,这个计算好像是用到相机的距离来做的,所以距离相机越远,计算中的失真就越大。怎样才能摆脱这种扭曲?
来源:https : //github.com/AskAlice/mandala-3d-threejs 现场演示:https : //askalice.me/mandala/
这是相关的代码:
js/content.js@112
function get3dPointZAxis(event)
{
camPos = camera.position;
var mv = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY/window.innerHeight) * 2 + 1, 1).unproject(camera);
var m2 = new THREE.Vector3(0,0,0);
var pos = camPos.clone();
pos.add(mv.sub(camPos).normalize().multiplyScalar(m2.distanceTo(camPos)));
return pos;
}
Run Code Online (Sandbox Code Playgroud)
我使用了来自两个 stackoverflow 帖子的信息来解决这个问题,它有我所描述的问题。
首先,这篇文章展示了如何绘制并将其转换为 z 轴。它是平的。但是我在尝试在三个维度上进行工作时遇到了很多麻烦。
然后我使用以下帖子中的信息至少使其与 xz 轴上的相机平行,如下所示:https : //i.imgur.com/E9AQNpH.png