乐虎国际官网
乐虎国际官网 当前位置:首页>乐虎国际官网>正文

乐虎国际官网

发布时间:2018-08-17

原标题:new Sphere

海子他们立即奋力划开来,在水中他们差点要被下面突然伸出来的手给拉下湖底里去,还好他们都是熟悉水性的老手,否则一般般的人,估计都跑不掉那只突然从水下伸出来的手的,估计不被拽到湖底里去,也得被吓个半死的了,以为是碰到了水鬼来索命来了。

博彩注册送64元现金可提现

驼子从后面接近,双手快速捏住前面,弯着身子,屁股在后面不停蠕动,再看女人趴在桌子上,脸上厌恶之色消失,不是享受,就算是一个没有节制的淫、娃、荡、妇,绝地不会和一个自己厌恶的人去做那种事。
因此几天的相处,两个境界不是相差太远都对武道有着独特见解的人分享了自己的经验之后都是有着很丰富的收获,尤其是作为泰山北斗的张三丰,几十年来已经没几个人敢和刘皓这样和他分享。

可是刘皓来到女儿岛修养之后,身体恢复一点,蜕变一点,他的实力就提升一点,因为是在蜕变突破之中,所以他对自己的气势难以控制,导致给人的感觉一言一语之间都带着一股凌驾众生唯我不灭的威压,让人觉得十分的压抑,所以咋婆婆才会有这样的反应。

0x00 前言

最近看到了我司大网红aras-p(Aras Pranckevičius)的博客开了一个很有趣的新系列《Daily Pathtracer~》,来实现一个简单的ToyPathTracer。
屏幕快照 2018-05-29 下午11.12.31.png
除了使用C++,aras还使用了两种不同的C#运行时来实现,即.NET Standard和Xamarin/Mono。效率上自然C++要强于.NET Standard,而.NET Standard的表现要强于Xamarin/Mono。

除此之外,aras当然还会用到Unity来实现,比较有意思的是Unity的实现中使用了2018中的Burst来提升性能,而结果甚至有点小惊人呢,之后可以再说。

而aras的这个小巧的ToyPathTracer事实上和最近在知乎上小火的小书《Ray Tracing in One Weekend》还有些关系。其实这是一套3本中的第一本书,另外还有两本,分别叫《Ray Tracing: the Next Week》和《Ray Tracing: The Rest Of Your Life》。

屏幕快照 2018-05-29 下午9.54.28.png
嗯,真是一入码门深似海。而图形学作为程序员的三大浪漫之一,真是诚不我欺也。

当然,这本书的作者Peter Shirley已经将此书作为PDF免费放出了(此处有地址:https://drive.google.com/drive/folders/14yayBb9XiL16lmuhbYhhvea8mKUUK77W),但是各位如果有兴趣的话建议还是买一下吧(seriously, just buy that minibook)。

所以前言部分先安利的,是这套小书。

0x01 Unity中实现PathTracer

aras的这一系列博客很长,目录摘录在下面。

  • Part 0: Intro
  • Part 1: Initial C++ and walkthrough
  • Part 2: Fix stupid performance issue
  • Part 3: C#, Unity and Burst
  • Part 4: Correctness fixes and Mitsuba
  • Part 5: simple GPU version via Metal
  • Part 6: simple GPU version via D3D11
  • Part 7: initial C++ SIMD & SoA
  • Part 8: SSE SIMD for HitSpheres
  • Part 9: ryg optimizes my code
  • Part 10: Update all implementations to match
  • Part 11: Buffer-oriented approach on CPU
  • Part 12: Buffer-oriented approach on GPU D3D11
  • Part 13: GPU thread group data optimization

我的这篇小文作为安利文,也就不详细介绍了每一篇的内容了,相信有兴趣的小伙伴都会去看的。

但是其中有一篇文章还是蛮有趣的,因为对比了不同语言、不同运行时的性能差异,而且还演示了一下Unity2018中的Burst compiler对C#代码性能的提升。所以稍微介绍下这部分吧。

当然,首先可以看到,场景是作为硬编码写死的:

static Sphere[] s_SpheresData = {
    new Sphere(new float3(0,-100.5f,-1), 100),
    new Sphere(new float3(2,0,-1), 0.5f),
    new Sphere(new float3(0,0,-1), 0.5f),
    new Sphere(new float3(-2,0,-1), 0.5f),
    new Sphere(new float3(2,0,1), 0.5f),
    new Sphere(new float3(0,0,1), 0.5f),
    new Sphere(new float3(-2,0,1), 0.5f),
    new Sphere(new float3(0.5f,1,0.5f), 0.5f),
    new Sphere(new float3(-1.5f,1.5f,0f), 0.3f),
    #if DO_BIG_SCENE
    new Sphere(new float3(4,0,-3), 0.5f), new Sphere(new float3(3,0,-3), 0.5f), new Sphere(new float3(2,0,-3), 0.5f), new Sphere(new float3(1,0,-3), 0.5f), new Sphere(new float3(0,0,-3), 0.5f), new Sphere(new float3(-1,0,-3), 0.5f), new Sphere(new float3(-2,0,-3), 0.5f), new Sphere(new float3(-3,0,-3), 0.5f), new Sphere(new float3(-4,0,-3), 0.5f),
    new Sphere(new float3(4,0,-4), 0.5f), new Sphere(new float3(3,0,-4), 0.5f), new Sphere(new float3(2,0,-4), 0.5f), new Sphere(new float3(1,0,-4), 0.5f), new Sphere(new float3(0,0,-4), 0.5f), new Sphere(new float3(-1,0,-4), 0.5f), new Sphere(new float3(-2,0,-4), 0.5f), new Sphere(new float3(-3,0,-4), 0.5f), new Sphere(new float3(-4,0,-4), 0.5f),
    new Sphere(new float3(4,0,-5), 0.5f), new Sphere(new float3(3,0,-5), 0.5f), new Sphere(new float3(2,0,-5), 0.5f), new Sphere(new float3(1,0,-5), 0.5f), new Sphere(new float3(0,0,-5), 0.5f), new Sphere(new float3(-1,0,-5), 0.5f), new Sphere(new float3(-2,0,-5), 0.5f), new Sphere(new float3(-3,0,-5), 0.5f), new Sphere(new float3(-4,0,-5), 0.5f),
    new Sphere(new float3(4,0,-6), 0.5f), new Sphere(new float3(3,0,-6), 0.5f), new Sphere(new float3(2,0,-6), 0.5f), new Sphere(new float3(1,0,-6), 0.5f), new Sphere(new float3(0,0,-6), 0.5f), new Sphere(new float3(-1,0,-6), 0.5f), new Sphere(new float3(-2,0,-6), 0.5f), new Sphere(new float3(-3,0,-6), 0.5f), new Sphere(new float3(-4,0,-6), 0.5f),
    new Sphere(new float3(1.5f,1.5f,-2), 0.3f),
    #endif // #if DO_BIG_SCENE        
};

static Material[] s_SphereMatsData = {
    new Material(Material.Type.Lambert,     new float3(0.8f, 0.8f, 0.8f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Lambert,     new float3(0.8f, 0.4f, 0.4f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Lambert,     new float3(0.4f, 0.8f, 0.4f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Metal,       new float3(0.4f, 0.4f, 0.8f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Metal,       new float3(0.4f, 0.8f, 0.4f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Metal,       new float3(0.4f, 0.8f, 0.4f), new float3(0,0,0), 0.2f, 0),
    new Material(Material.Type.Metal,       new float3(0.4f, 0.8f, 0.4f), new float3(0,0,0), 0.6f, 0),
    new Material(Material.Type.Dielectric,  new float3(0.4f, 0.4f, 0.4f), new float3(0,0,0), 0, 1.5f),
    new Material(Material.Type.Lambert,     new float3(0.8f, 0.6f, 0.2f), new float3(30,25,15), 0, 0),
    #if DO_BIG_SCENE
    new Material(Material.Type.Lambert, new float3(0.1f, 0.1f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.2f, 0.2f, 0.2f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.3f, 0.3f, 0.3f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.4f, 0.4f, 0.4f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.5f, 0.5f, 0.5f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.6f, 0.6f, 0.6f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.7f, 0.7f, 0.7f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.8f, 0.8f, 0.8f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.9f, 0.9f, 0.9f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Metal, new float3(0.1f, 0.1f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.2f, 0.2f, 0.2f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.3f, 0.3f, 0.3f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.4f, 0.4f, 0.4f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.5f, 0.5f, 0.5f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.6f, 0.6f, 0.6f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.7f, 0.7f, 0.7f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.8f, 0.8f, 0.8f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.9f, 0.9f, 0.9f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Metal, new float3(0.8f, 0.1f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.8f, 0.5f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.8f, 0.8f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.4f, 0.8f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.1f, 0.8f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.1f, 0.8f, 0.5f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.1f, 0.8f, 0.8f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.1f, 0.1f, 0.8f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.5f, 0.1f, 0.8f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Lambert, new float3(0.8f, 0.1f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.8f, 0.5f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.8f, 0.8f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.4f, 0.8f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.1f, 0.8f, 0.1f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.1f, 0.8f, 0.5f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.1f, 0.8f, 0.8f), new float3(0,0,0), 0, 0), new Material(Material.Type.Lambert, new float3(0.1f, 0.1f, 0.8f), new float3(0,0,0), 0, 0), new Material(Material.Type.Metal, new float3(0.5f, 0.1f, 0.8f), new float3(0,0,0), 0, 0),
    new Material(Material.Type.Lambert, new float3(0.1f, 0.2f, 0.5f), new float3(3,10,20), 0, 0),
    #endif
};

当然需要来判断是否相交的:

static bool HitWorld(Ray r, float tMin, float tMax, ref Hit outHit, ref int outID, ref SpheresSoA spheres)
{
    outID = spheres.HitSpheres(ref r, tMin, tMax, ref outHit);
    return outID != -1;
}

光线的追踪:

static float3 Trace(Ray r, int depth, ref int inoutRayCount, ref SpheresSoA spheres, NativeArray<Material> materials, ref uint randState, bool doMaterialE = true)
{
    Hit rec = default(Hit);
    int id = 0;
    ++inoutRayCount;
    if (HitWorld(r, kMinT, kMaxT, ref rec, ref id, ref spheres))
    {
        Ray scattered;
        float3 attenuation;
        float3 lightE;
        var mat = materials[id];
        var matE = mat.emissive;
        ...

物体表面如何处理接收到的光线呢?可以看这里:

static bool Scatter(Material mat, Ray r_in, Hit rec, out float3 attenuation, out Ray scattered, out float3 outLightE, ref int inoutRayCount, ref SpheresSoA spheres, NativeArray<Material> materials, ref uint randState)
{
    outLightE = new float3(0, 0, 0);
    if (mat.type == Material.Type.Lambert)
    {
        // random point inside unit sphere that is tangent to the hit point
        float3 target = rec.pos + rec.normal + MathUtil.RandomUnitVector(ref randState);
        scattered = new Ray(rec.pos, normalize(target - rec.pos));
        attenuation = mat.albedo;

        // sample lights
        ...

最后,在Unity中使用了burst,并分发了任务:

[ComputeJobOptimization]
struct TraceRowJob : IJobParallelFor
{
    public int screenWidth, screenHeight, frameCount;
    [NativeDisableParallelForRestriction] public NativeArray<UnityEngine.Color> backbuffer;
    public Camera cam;

    [NativeDisableParallelForRestriction] public NativeArray<int> rayCounter;
    [NativeDisableParallelForRestriction] public SpheresSoA spheres;
    [NativeDisableParallelForRestriction] public NativeArray<Material> materials;

    public void Execute(int y)
    {
        int backbufferIdx = y * screenWidth;
        float invWidth = 1.0f / screenWidth;
        float invHeight = 1.0f / screenHeight;
        float lerpFac = (float)frameCount / (float)(frameCount + 1);
        ...

通过UnityProfiler,我们可以看到经过Burst优化后的运行状态:
rt-cs-unity-timeline-burst.png

不过让我感到比较吃惊的是,在Unity2018中使用C#+Burst时的效率竟然超过了C++的实现,看来Burst的效率还是很惊人的。

下面是aras那里的结论:

  • .NET Core is about 2x slower than vanilla C++.
  • Mono (with default settings) is about 3x slower than .NET Core.
  • IL2CPP is 2x-3x faster than Mono, which is roughly .NET Core performance level.
  • Unity’s Burst compiler can get our C# code faster than vanilla C++. Note that right now Burst is very early tech, I expect it will get even better performance later on.

当然,aras的博客中有更详细的对比数据。

所以这部分安利的,是aras的博客(http://aras-p.info/blog/2018/03/28/Daily-Pathtracer-Part-0-Intro/)。

0x02 小结

当然,aras除了写了博客之外,也开源了这个ToyPathTracer(也许先有了ToyPathTracer才有了这系列的博客也未可知)。

所以各位可以去github上clone一份代码,除了可以分别在windows和mac上编译c++、c#的实现,也可以直接在unity中使用。
屏幕快照 2018-05-29 下午10.43.52.png

所以最后安利一下这个工程(https://github.com/aras-p/ToyPathTracer)。

怎么样,是不是还挺有趣的?

Ref

《Ray Tracing in One Weekend》
https://drive.google.com/drive/folders/14yayBb9XiL16lmuhbYhhvea8mKUUK77W

《Daily Pathtracer》
http://aras-p.info/blog/2018/03/28/Daily-Pathtracer-Part-0-Intro/

《ToyPathTracer》
https://github.com/aras-p/ToyPathTracer

-EOF-
最后打个广告,欢迎支持我的书《Unity 3D脚本编程》

欢迎大家关注我的公众号慕容的游戏编程:chenjd01

编辑:秉开公徒

发布:2018-08-17 09:06:59

当前文章:http://thrksw.com/etcet/cc0db89ab32c9969.html

恒河娱乐开户 来博娱开户 绝密五码中特资料 开心8娱乐场网络博彩 狼二老虎机显示00是什么原因 台湾美女老虎机吃币 海燕百家 41668金沙12年

借贷宝注册送多少 连环夺宝注册送81元彩金 电子游艺送20元彩金 电子游艺送17元彩金 沙龙博彩娱乐场 尊龙娱乐备用网址_long8娱乐场有狼头的是什么老虎机 贵族娱乐摇钱树注册 皇冠时时彩平台网址

责任编辑:安扁

随机推荐