在 OpenGL 中渲染一个*填充的*半透明立方体

发布于 2024-12-03 07:30:43 字数 189 浏览 5 评论 0原文

不知道如何表达我的困惑,但我的想法是这样的: 具有透明(或半透明)侧面的立方体不是实心(填充的、填充的)立方体。它更像是一个空的玻璃立方体。现在我想要的是一个坚固的填充玻璃立方体。就像水晶球一样,但呈立方体形状。它们后面的东西看起来不同。我如何告诉 OpenGL 我的几何体已填充?我如何实现从一层非常厚的玻璃(例如玻璃)后面观看某个场景的效果?

Dunno how to express my confusion but here is how it goes in my mind:
A cube with transparent(or translucent) sides is not a solid (filled, stuffed) cube. It's more like an empty glass cube. Now what I want is a solid, stuffed glass cube. Just like a crystal ball but in cube shape. Things behind them appear differently.How do I tell OpenGL that my geometry is stuffed ? How do i achieve the effect of looking at some scene from behind a very thick layer of , say, glass ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无风消散 2024-12-10 07:30:43

正确的术语是“固体”。你的问题是一个不平凡的问题,没有简单的、就地的方法来解决它。对于简单的假折射来说,最好的办法是渲染一个立方体贴图,其原点位于对象边界体积的中心,并将该立方体贴图与缩放为纹理坐标的对象法线一起使用。如果你想让它看起来更准确,你需要了解光与物质的相互作用。重现光与物质相互作用效果的唯一完全准确的方法是通过光线追踪(如果使用差分光线元素,人们可以称之为光子映射)。

如果要实时渲染结果,则使用 OpenGL 可以获得粗略的近似值。

渲染半透明固体需要以某种方式类似于

  • 折射
  • 反射
  • 吸收的光学效果 - 当光穿过固体时,它将被过滤掉
  • 荧光 - 例如,如果阳光或仅紫光穿过一块 铀玻璃,紫外线部分会引起绿色荧光。光的蓝色部分被吸收,但玻璃发出绿色部分。
  • 散射——玻璃中的小颗粒、杂质、小气泡等将光散射出去。这就是雾的作用。

在大多数情况下,伪造折射和吸收就足够了。玻璃可以通过这种方式非常有效地渲染。渲染折射、吸收固体有 3 个重要变量:

  • 入射光线的进入角度(这隐含地决定了固体内的光线)
  • 材料的厚度
  • 光线的出射角度

有多种方法可以获得这些变量:

  • 您可以预先计算它们,将它们存储为一组球谐系数,用作着色器中的附加采样器输入。
  • 您可以使用深度剥离将相关对象切成表面层。奇数层为入口,偶数层为出口。你从近到远。近表面撞击会折射光线,您跟随该光线直到它撞击出射表面并再次在那里折射。射线的长度用作例如比尔-朗伯定律吸收方程的参数。

那么如何在 OpenGL 中实现这一点呢?恐怕 Stackoverflow 上的答案无法涵盖它,除非它发展成为一篇成熟的论文。因此,我建议您参阅GPU Gems 2的第19章,其中涵盖了基础知识http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter19.html

The proper term is "solid". And your problem is a nontrivial one and there's no easy, in-situ way to solve it. The best thing for a simple fake refraction is rendering a cubemap with the origin at the objects bounding volume's center, and use that cubemap in with the objects normals scaled as texture coordinates. If you want it to look more accurate you need to know about light-matter interactions. The only perfectly accurate way to recreate the effects of light-matter interaction is by raytracing (if differential ray elements are used, one may call this photon mapping).

Using OpenGL one can get coarse approximations if the results are to be rendered in realtime.

Rendering translucent solids needs to somehow resemble the optical effects of

  • refraction
  • reflection
  • absorbtion - as the light passes through the solid it will be filtered out
  • flourescence – for example if sunlight, or just violet light passes through a piece of uranium glass, the ultraviolet part will cause green flourescence. The blue part of the light gets absorbed, but you get a green part emitting from the glass.
  • scattering - small particles in the glass, impurities, small air bubbles, etc. scatter the light out. This is what fog does.

In most cases it's sufficient to fake refraction and absorbtion. Glass can be rendered that way quite effectively. There are 3 important variables to rendering a refractive, absorbtive solid:

  • the angle of entry of the incoming ray (this implicitly determines the ray within the solid)
  • the thinkness of the material
  • the angle of exit of the ray

There are several ways to obtain those:

  • You can precompute them, store them as a set of spherical harmonics coefficients used as an additional sampler input in a shader.
  • You can use depth peeling to slice the object in question into layers of surfaces. Odd numbered layers are entry, even numbered are exit. You go from near to far. Near surface hit refracts the ray, you follow that ray until it hits the exit surface and refract it there again. The length of the ray is used as parameter into, e.g. a Beer-Lambert law absorbtion equation.

So how do you implement this in OpenGL. I'm afraid an answer on Stackoverflow will not be able to cover it, unless it grew into a fully fledged paper. Thus I refer you to Chapter 19 of GPU Gems 2, which covers the basics http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter19.html

情未る 2024-12-10 07:30:43

您正在尝试实现折射效果。在一般情况下,这不是一个小问题,书籍和在线提供了大量技术。

具体来说,对于立方体,您可以分析计算折射,并在渲染每个面时应用合适的变换(您必须根据投影通过它的一个或多个背面面细分每个正面面;然后您必须计算出立方体后面的场景将如何折射通过每个细分)。这是一个糟糕的解释,但恐怕要做出正确的解释会很复杂。抱歉,我无法提供更多帮助,但我希望这足以让您走上正轨。

You are trying to achieve a refraction effect. This isn't a trivial problem in the general case, and there is a substantial body of techniques available in books and online.

For a cube, specifically, you can compute the refraction analytically and apply a suitable transform while rendering each facet (you must subdivide each front-facing facet according to the one or more rear-facing facets that project through it; you then have to figure out how the scene behind the cube will refract through each subdivision). This is a poor explanation, but a proper explanation would be quite involved, I'm afraid. Sorry I can't help more, but I hope this is enough to set you on the right track.

生生不灭 2024-12-10 07:30:43

实现您想要的效果的一个简单方法是将立方体的正面渲染为透明面,立方体越厚,alpha 值就越大。这仅适用于从观察者到其穿过立方体的前侧和前侧的相对侧的像素。如果通过相邻的立方体边看到像素,则需要进行一些着色器数学运算来计算适当的不透明度。

A simple way to achieve what you want would be to render the cube's front side as transparent faces with an alpha value getting the bigger the thicker the cube is. This will only work acceptably for pixels the vector from the viewer to which passes through the front side and the front side's opposite side of the cube. If the pixel is seen through adjacent cube sides, you would need to do some shader math to compute the proper opacity.

尐偏执 2024-12-10 07:30:43

您可以尝试在顶/底、左/右和前/后表面之间绘制许多透明方块。这样,被更多立方体遮挡的物体将位于更透明的层后面,因此不太可见。

You could try drawing many transparent squares between the top/bottom, left/right, and front/back faces. This way, thing obscured by more of the cube would be behind more transparent layers and thus be less visible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文