首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >三维阴影实现思想

三维阴影实现思想
EN

Stack Overflow用户
提问于 2012-08-27 11:04:14
回答 4查看 2K关注 0票数 11

假设你的眼睛在物体A上的表面点P1上,并且有一个目标物体B,在物体B后面有一个点光源。

问题:如果我看着光源,说“我在阴影中”,如果我因为物体B而看不到光,那我是对的吗?然后我将物体A的那个点标记为“B在A上的阴影点之一”。

如果这是真的,那么我们可以在A的表面上建立一个“阴影几何学”(黑色)物体,然后因为光、B、A等的运动而不断地改变它.实时?假设一个球面(A)有1000个顶点,其他球面(B)也有1000个顶点,那么这是否意味着1毫秒的比较?(阴影,O(N^2) (时间)复杂性吗?)我不确定其复杂性,因为改变P1 (眼睛)也改变了B的观察点(在P1和光源点之间)。二级阴影和更高的阴影(例如光线在两个物体之间多次反射)怎么办?

我现在使用的是java-3D,但是它没有阴影功能,所以我想转移到其他兼容java的库中。

谢谢。

编辑:,我需要禁用“相机”时,移动相机,以建立阴影。我该怎么做?这是否严重地降低了性能?

新理念: java3D已经内置了碰撞检测。我将创建从光到目标多边形顶点的线(不可见),然后检查来自另一个物体的碰撞。如果发生碰撞,添加顶点corrd。到阴影列表,但这只适用于点灯:

任何为java3d提供一个真正的阴影库的人都会很有帮助。

非常小的示例Geomlib阴影/光线跟踪在java3D中可能是最好的射线跟踪示例?

我知道这有点难,但至少有一百人可以尝试。

谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-10-10 14:11:00

你的方法可以概括如下:

代码语言:javascript
复制
foreach (point p to be shaded) {
    foreach (light) {
        if (light is visible from p)
            // p is lit by that light
        else
            // p is in shadow
    }
}

有趣的是,就是这样在GPU上实现实时阴影的。

然而,要想有效地工作,这并不是件容易的事。渲染场景是一个流线型的过程,一个三角形一个三角形.如果对于每个三角形中的每个点(像素、片段),您需要考虑其他三角形中的所有其他三角形来检查光线交集,这将是非常麻烦的。

那么如何有效地做到这一点呢?答:逆转这一过程。

通常情况下,现场的灯光比像素少得多。让我们利用这一事实,做一些预处理:

代码语言:javascript
复制
// preprocess
foreach (light) {
    // find all pixels p on the scene reachable from the light
}
// then render the whole scene...
foreach (point p to be shaded) {
    foreach (light) {
        // simply look up into what was calculated before...
        if (p is visible by the light)
            // p is lit
        else
            // p is in shadow
    }
 }

看起来快多了..。但仍有两个问题:

  1. 如何在光线下找到所有可见的像素?
  2. 如何使它们在呈现过程中快速可访问以进行查找?

有一个棘手的部分:

  • 为了找出所有的点可见的一盏灯,在那里放置一个相机,并渲染整个场景!深度测试将拒绝不可见的点。
  • 为了以后可以访问这个结果,请将其保存为纹理,并在实际呈现阶段使用该纹理进行查找。

这种技术称为阴影映射,从光线中可见像素的纹理称为阴影映射。有关更详细的说明,请参见例如维基百科文章

票数 2
EN

Stack Overflow用户

发布于 2012-10-05 20:04:57

阴影可能是三维图形编程中最复杂的话题,有很多种方法,但是最好的选择应该根据任务的要求来确定。您正在讨论的算法是实现从光斑光源到平面的阴影的最简单的方法。它不应该在CPU上完成,因为您已经使用GPU进行3D渲染。

基本上,方法是两次渲染同一个物体:一次是从摄像机的角度,一次是从光源的角度。您需要准备模型视图矩阵,以便在这两个视图之间进行转换。一旦你从光点渲染物体,你就得到了深度图,其中每个点都位于离光源最近的地方。然后,对于普通渲染的每个像素,您应该将其3D坐标转换为先前的视图,并对照相应的深度值进行检查。这实际上给了你一种方法来判断哪些像素被阴影覆盖。

两次呈现同一个对象会对性能产生影响。如果您的任务不具备阴影投射解决方案的高可伸缩性,那么它可能是一条路。

若干相关问题:

如何在OpenGL中创建廉价阴影?

有什么简单的方法可以在OpenGL中获取阴影吗?

在OpenGL中,在场景中渲染阴影最简单的方法是什么?

票数 3
EN

Stack Overflow用户

发布于 2012-10-09 15:26:24

基本上是的,你的方法会产生阴影。但是,逐点执行是不可行的(就实时性而言),除非它是在GPU上完成的。我不太熟悉API今天提供的内容,但我相信最近的任何引擎都会提供一些阴影。

您的“新想法”是如何实现阴影的日子里,当渲染仍然是用CPU完成。如果多边形的数量不太大(或者您可以通过分组卷等来有效地拒绝整个包)。它可以用相当少的CPU功率来完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12140784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档