Volumetric Rendering Part 1

栏目: IT技术 · 发布时间: 5年前

内容简介:I recently wrote a small ShaderToy that does some simple volumetric rendering. I decided to follow up with a post on how the ShaderToy works. It ended up a little longer than I expected so I’ve broken this into 2 parts: the first part will talk about model

Volumetric Rendering Part 1

I recently wrote a small ShaderToy that does some simple volumetric rendering. I decided to follow up with a post on how the ShaderToy works. It ended up a little longer than I expected so I’ve broken this into 2 parts: the first part will talk about modelling a volume using SDFs.Part 2 will go into using ray marching to render the volume. I highly recommend you view the interactive ShaderToy yourself here . If you’re on a phone or laptop, I suggest viewing the fast version here . I’ve included some code snippets, which should help get a high-level understanding of how the ShaderToy works but aren’t all-inclusive. If you want to understand things at a deeper level, I’d suggest cross-referencing this with the actual ShaderToy code.

I had 3 main goals for my ShaderToy:

  1. Real-time
  2. Simple
  3. Physically-based…ish

I’ll be starting from this scene with some starter code. I’m not going to go deep into the implementation as it’s not too interesting, but just to give a sense of where we’re starting from:

  1. Ray trace against some opaque objects. All objects here are primitive objects with simple ray intersections (1 plane and 3 spheres)
  2. Phong shading is used to calculate lighting, with the 3 orb lights using a tunable light falloff factor. No shadow rays are needed because the only thing being lit is a plane.

Here’s what that looks like:

Volumetric Rendering Part 1

We’ll be rendering the volume as a separate pass that gets blended with the opaque scene, similar to how any real-time rendering engine would handle opaque surfaces vs translucents.

Part 1: Modelling a volume

But first, before we can even do any volumetric rendering, we need a volume to render! I decided to use signed distance functions (SDFs) to model my volume. Why distance fields functions? Because I’m not an artist and they’re really great for making organic shapes in a few lines of code. I’m not going to go into signed distance functions because Inigo Quilez has done a really great job of that already. If you’re interested, here’s a great list of different signed distance functions and modifiers here . And another on raymarching those SDFs.

So lets start simple and throw a sphere in there: Volumetric Rendering Part 1

Now we’ll add an extra sphere and use a smooth union to merge the sphere distance functions together. This is taken straight from Inigo’s page, but I’m pasting it here for clarity:

// Taken from https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
float sdSmoothUnion( float d1, float d2, float k ) 
{
    float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );
    return mix( d2, d1, h ) - k*h*(1.0-h); 
}

Smooth union is extremely powerful as you can get something quite interesting by just combining it with a handful of simple shapes. Here’s what my set of smooth union spheres look like: Volumetric Rendering Part 1

Okay, we have something blobby looking, but we really want something that’s more of a cloud than a blob. The really cool thing about SDFs is how easy it is to distort the surface by just addding some noise to the SDF. So lets slap some fractal brownian motion (fBM) noise ontop using the position to index into the noise function. Inigo Quilez has us covered again with a really great article on fBM noise if you’re interested. But here’s how it looks with some fBM noise tossed on top:

Volumetric Rendering Part 1

Sweet! This thing suddenly looks a lot more interesting with the fBM noise! Finally we want to give the illusion that the volume is interacting with the ground plane. To do this, I added a plane signed distance just slightly under the actual ground plane and again re-use that smooth union merge with a really aggressive union value (the k parameter). And after that you get this:

Volumetric Rendering Part 1

And then a final touch is to adjust the xz index into the fBM noise with time so that the volume has a kind of rolling fog look. In motion it looks pretty good! Volumetric Rendering Part 1

Woohoo, we have something that looks like a cloudy thing! The code for calculating the SDF is pretty compact too:

float QueryVolumetricDistanceField( in vec3 pos)
{    
    vec3 fbmCoord = (pos + 2.0 * vec3(iTime, 0.0, iTime)) / 1.5f;
    float sdfValue = sdSphere(pos, vec3(-8.0, 2.0 + 20.0 * sin(iTime), -1), 5.6);
    sdfValue = sdSmoothUnion(sdfValue,sdSphere(pos, vec3(8.0, 8.0 + 12.0 * cos(iTime), 3), 5.6), 3.0f);
    sdfValue = sdSmoothUnion(sdfValue, sdSphere(pos, vec3(5.0 * sin(iTime), 3.0, 0), 8.0), 3.0) + 7.0 * fbm_4(fbmCoord / 3.2);
    sdfValue = sdSmoothUnion(sdfValue, sdPlane(pos + vec3(0, 0.4, 0)), 22.0);
    return sdfValue;
}

But this is just rendering it as an opaque. We want something nice and fluffy! Which leads topart 2!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

个体与交互

个体与交互

Ken Howard、Barry Rogers / 贾永娜、张凯峰 / 机械工业出版社华章公司 / 2012-3-20 / 45.00元

对敏捷软件开发的关注重点,通常都集中在“机制”方面,即过程和工具。“敏捷宣言”认为,个体与交互的价值要高于过程和工具,但这一点很容易被遗忘。在敏捷开发中,如果你重新将注意力放在人的方面,将会收获巨大利益。 本书展示了如何解决敏捷团队在实际项目中遭遇的问题。同时,本书也是很有实用价值的敏捷用户指南,其中包含的故事、最佳实践方法、经验以及技巧均可应用到实际项目当中。通过逐步实践,你将学会如何让团......一起来看看 《个体与交互》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具