public static Buffer CreateLutBuffer(float f_x, float f_y)
        {
            var filter =
                //new MitchelFilter(f_x, f_y);
            new GaussianFilter(f_x, f_y);

            float[] Gaussian2x2_filterTable = new float[16 * 16];
            for (var y = 0; y < 16; ++y)
            {
                float fy = (y + 0.5f) * 2.0f / 16.0f;
                for (var x = 0; x < 16; ++x)
                {
                    float fx = (x + 0.5f) * 2.0f / 16.0f;
                    Gaussian2x2_filterTable[x + y * 16] = filter.Evaluate(fx, fy);
                    //Max<float>(0.f, expf(-alpha * fx * fx) - expX) *Max<float>(0.f, expf(-alpha * fy * fy) - expY);
                }
            }

            BufferDesc desc = new BufferDesc()
            {
                Width = 16 * 16,
                Type = BufferType.Input,
                Format = Format.Float
            };

            Buffer res = new Buffer(ComponentPipeline.Instance.Session.OptixContext, desc);

            res.SetData(Gaussian2x2_filterTable);

            return res;
        }
Exemple #2
0
        public override void SetupScene(SceneGraph scene)
        {
            Tracer.Print("SceneSetup", "Start building scene data");

            builder.Build(scene);

            Tracer.Print("SceneSetup", "Creating buffers");

            var optixContext = ComponentPipeline.Instance.Session.OptixContext;
            ComponentPipeline.Instance.Session.Frame.CurrentCamera = builder.Camera;

            var spdBuffDesc = new BufferDesc
            {
                Width = outputBuffer.Width + 1,
                Height = outputBuffer.Height + 1,
                Depth = outputBuffer.Depth,
                Format = Format.Float3,
                Type = BufferType.InputOutput
            };
            hdrBuffer = new Buffer(optixContext, spdBuffDesc);

            hdrBuffer.SetData(new Vector3[spdBuffDesc.Width * spdBuffDesc.Height]);

            var rndBuffDesc = new BufferDesc
            {
                Width = outputBuffer.Width + 1,
                Height = outputBuffer.Height + 1,
                Depth = outputBuffer.Depth,
                Format = Format.UInt,
                Type = BufferType.InputOutput
            };
            rndBuffer = new Buffer(optixContext, rndBuffDesc);
            GenerateSeeds();
            optixContext["rnd_seeds"].Set(rndBuffer);
            optixContext["hdr_buffer"].Set(hdrBuffer);

            optixContext["top_object"].Set(ComponentPipeline.Instance.Session.Frame.TopObject);
            optixContext["output_buffer"].Set(outputBuffer);
            optixContext["scene_epsilon"].Set(0.00001f);
            optixContext["rr_begin_depth"].Set(rrBeginDepth);
            optixContext["max_depth"].Set(maxDepth);
            optixContext["sqrt_num_samples"].Set(sqrtSamples);
            optixContext["bad_color"].SetFloat3(new Vector3(1.0f, 0.0f, 0.0f));
            //optixContext["bg_color"].Set(100 / 255.0f, 149 / 255.0f, 237 / 255.0f);
            optixContext["bg_color"].Set(0f,0f,0f);

            optixContext["lights"].Set(ComponentPipeline.Instance.Session.Frame.LightBuffer);
            optixContext["lightTriangles"].Set(ComponentPipeline.Instance.Session.Frame.LightTrianglesBuffer);

            optixContext["Y_log_av"].Set(yAvg);
            optixContext["Y_max"].Set(yMax);
            optixContext["gamma_value"].Set(gamma_value);

            QMC.InitContext(optixContext);
            Tracer.Print("SceneSetup", "Optix context compilation.");

            ComponentPipeline.Instance.Session.OptixContext.Compile();
            ComponentPipeline.Instance.Session.OptixContext.BuildAccelTree();

            Tracer.Print("SceneSetup", "Finished.");
        }
Exemple #3
0
        public override void SetupScene(Scene.SceneGraph scene)
        {
            Tracer.Print("SceneSetup", "Start building scene data");

            this.SafeExec(() => builder.Build(scene), ex => { Trace.WriteLine(ex.StackTrace); });

            Tracer.Print("SceneSetup", "Creating buffers");

            var optixContext = ComponentPipeline.Instance.Session.OptixContext;

            UpdateDescriptionBuffer();

            this.Cameras = builder.Cameras;
            ComponentPipeline.Instance.Session.Frame.CurrentCamera = builder.Camera;

            var spdBuffDesc = new BufferDesc
            {
                Width = outputBuffer.Width,
                Height = outputBuffer.Height,
                Depth = outputBuffer.Depth,
                Format = Format.Float3,
                Type = BufferType.InputOutput
            };

            var sampBuffDesc = new BufferDesc
            {
                Width = outputBuffer.Width,
                Height = outputBuffer.Height,
                Depth = outputBuffer.Depth,
                Format = Format.UInt,
                Type = BufferType.InputOutput
            };
            hdrBuffer = new Buffer(optixContext, spdBuffDesc);
            hdrBuffer.SetData(new Vector3[spdBuffDesc.Width * spdBuffDesc.Height]);
        }
Exemple #4
0
        protected void UpdateDescriptionBuffer()
        {
            var optixContext = ComponentPipeline.Instance.Session.OptixContext;
            var descriptions = builder.MaterialDescriptions.ToArray();

            if (mdBuffer != null)
            {
                mdBuffer.Destroy();
                mdBuffer = null;
            }
            var mdBuffDesc = new BufferDesc
            {
                Width = (ulong)descriptions.Length,
                Format = Format.User,
                Type = BufferType.Input,
                ElemSize = (uint)Marshal.SizeOf(typeof(MaterialDescription))
            };
            mdBuffer = new Buffer(optixContext, mdBuffDesc);
            mdBuffer.SetData(descriptions);
            optixContext["materialDescriptions"].Set(mdBuffer);
        }
        public override void SetScene(IRayEngineScene secn)
        {
            string shaderPath = Path.GetFullPath(@"G:\Git\RayDen\RayDen.OptixEngine\Cuda\Scripts\CudaScripts\hitkernel.ptx");

            Tracer.TraceLine("OptixIntersectionDevice  -  Initializing Optix");
            this.scene = (RayEngineScene) secn;
            var scn = scene.SceneGeometry;

            Material material = new Material(Context);
            material.Programs[0] = new SurfaceProgram(Context, RayHitType.Closest, shaderPath, "first_hit");
            //            material.Programs[1] = new SurfaceProgram(Context, RayHitType.Any, shaderPath, "shadow");


            var mVertices = scn.Vertices.ToList();
            var mNormals = scn.Normals.ToList();
            List<UV> mTexcoords = null;
            mTexcoords = scn.TexCoords == null ? new List<UV>() : scn.TexCoords.Select(it=>new UV(it.x,it.y)).ToList();

            var vDesc = new BufferDesc() { Width = (uint)mVertices.Count, Format = Format.Float3, Type = BufferType.Input };
            var nDesc = new BufferDesc() { Width = (uint)mNormals.Count, Format = Format.Float3, Type = BufferType.Input };
            var tcDesc = new BufferDesc() { Width = (uint)mTexcoords.Count, Format = Format.Float2, Type = BufferType.Input };

            // Create the buffers to hold our geometry data
            var vBuffer = new  DeviceBuffer(Context, vDesc);
            var nBuffer = new  DeviceBuffer(Context, nDesc);
            var tcBuffer = new DeviceBuffer(Context, tcDesc);


            vBuffer.SetData(mVertices.ToArray());
            nBuffer.SetData(mNormals.ToArray());
            tcBuffer.SetData(mTexcoords.ToArray());


            foreach (var triangleMesh in scene.Meshes.Cast<TriangleMeshInfo>())
            {
                var group = triangleMesh;


                var viDesc = new BufferDesc() { Width = (uint)(group.TrianglesCount), Format = Format.Int3, Type = BufferType.Input };
                var niDesc = new BufferDesc() { Width = (uint)(group.TrianglesCount), Format = Format.Int3, Type = BufferType.Input };
                var tiDesc = new BufferDesc() { Width = (uint)(group.TrianglesCount), Format = Format.Int3, Type = BufferType.Input };
                var ofsDesc = new BufferDesc()
                    {
                        Width = (uint) (group.TrianglesCount),
                        Format = Format.UInt,
                        Type = BufferType.Input
                    };

                var viBuffer = new DeviceBuffer(Context, viDesc);
                var niBuffer = new DeviceBuffer(Context, niDesc);
                var tiBuffer = new DeviceBuffer(Context, tiDesc);

                var gIndexes =
                    scene.Triangles.ToList().GetRange(group.StartTriangle, group.TrianglesCount)
                         .SelectMany(tri => new []
                             {
                                 tri.v0.VertexIndex,
                                 tri.v1.VertexIndex,
                                 tri.v2.VertexIndex
                             })
                         .ToArray();

                var gNIndexes =
                    scene.Triangles.ToList().GetRange(group.StartTriangle, group.TrianglesCount)
                         .SelectMany(tri => new[]
                             {
                                 tri.v0.NormalIndex,
                                 tri.v1.NormalIndex,
                                 tri.v2.NormalIndex
                             })
                         .ToArray();
                var gTIndexes =
                    scene.Triangles.ToList().GetRange(group.StartTriangle, group.TrianglesCount)
                         .SelectMany(tri => new []
                             {
                                 tri.v0.TexCoordIndex,
                                 tri.v1.TexCoordIndex,
                                 tri.v2.TexCoordIndex
                             })
                         .ToArray();

                viBuffer.SetData(Convert(gIndexes).ToArray());
                niBuffer.SetData(Convert(gNIndexes).ToArray());
                tiBuffer.SetData(Convert(gTIndexes).ToArray());

                var geometry = new Geometry(Context);
                geometry.IntersectionProgram = new Program(Context, IntersecitonProgPath, IntersecitonProgName);
                geometry.BoundingBoxProgram = new Program(Context, BoundingBoxProgPath, BoundingBoxProgName);
                geometry.PrimitiveCount = (uint)(group.EndTriangle - group.StartTriangle);

                geometry["vertex_buffer"].Set(vBuffer);
                geometry["normal_buffer"].Set(nBuffer);
                geometry["texcoord_buffer"].Set(tcBuffer);
                geometry["vindex_buffer"].Set(viBuffer);
                geometry["nindex_buffer"].Set(niBuffer);
                geometry["tindex_buffer"].Set(tiBuffer);
                geometry["mesh_offset"].SetInt4(group.StartTriangle);
                //geometry[ "material_buffer" ].Set(mtBuffer);

                //create a geometry instance
                var instance = new GeometryInstance(Context);
                instance.Geometry = geometry;
                instance.AddMaterial(material);
                //create an acceleration structure for the geometry
                Acceleration accel = new Acceleration(Context, Builder, Traverser);

                if (Builder == AccelBuilder.Sbvh || Builder == AccelBuilder.TriangleKdTree)
                {
                    accel.VertexBufferName = "vertex_buffer";
                    accel.IndexBufferName = "vindex_buffer";
                }

                //now attach the instance and accel to the geometry group
                GeoGroup.Acceleration = accel;
                GeoGroup.AddChildren(new[] { instance });
            }

            Program rayGen = new Program(Context, shaderPath, "intersector_camera");
            Program exception = new Program(Context, shaderPath, "exception");
            Program miss = new Program(Context, shaderPath, "miss");
            Context["intersect_ray_type"].Set(0u);
            Context["scene_epsilon"].Set(0.0001f);
            Context.SetRayGenerationProgram(0, rayGen);
            Context.SetExceptionProgram(0, exception);
            Context.SetRayMissProgram(0, miss);
            Context["top_object"].Set(GeoGroup);
            Tracer.TraceLine("OptixIntersectionDevice  -  Compiling Optix contex");
            Context.Compile();
            Context.BuildAccelTree();
            Tracer.TraceLine("OptixIntersectionDevice  -  Complete");
        }
        private void SetDefaultMaterialProperties(GeometryInstance instance, Material mtrl, SceneMaterial material)
        {
            var brdf = (BrdfTypes)(int)material["brdf_id"];
            if (brdf == BrdfTypes.BRDF_TYPE_GLOSSY_REFLECTION_MEASURED)
            {
                int th, td, pd;
                string[] names =
                {
                    "chrome-steel.binary", "gold-metallic-paint.binary", "green-acrylic.binary", "chrome-steel.binary",
                    "color-changing-paint1.binary", "colonial-maple-223.binary", "dark-blue-paint.binary",
                    "green-fabric.binary",
                    "green-plastic.binary", "hematite.binary", "nylon.binary", "pearl-paint.binary"
                };

                Random rnd = new Random();
                string fileName = string.Format(@"F:\3D\Brdfs\merl\{0}", names[rnd.Next(0, names.Length - 1)]);
                Trace.TraceInformation("Loading material data for " + fileName);
                var data =
                    OptixMaterialFactory.FileHelper.Read(fileName, out th, out td, out pd)
                        .Select(i => (float)i)
                        .ToArray();
                mtrl["nThetaH"].Set(th);
                mtrl["nThetaD"].Set(td);
                mtrl["nPhiD"].Set(pd);
                var bDesc = new BufferDesc()
                {
                    Width = (uint)data.Length,
                    Format = Format.Float,
                    Type = BufferType.Input
                };
                var viBuffer = new Buffer(Session.OptixContext, bDesc);
                viBuffer.SetData(data);
                mtrl["brdf"].Set(viBuffer);
            }
            else
            {
                var bDesc = new BufferDesc()
                {
                    Width = (uint)1,
                    Format = Format.Float,
                    Type = BufferType.Input
                };
                var viBuffer = new Buffer(Session.OptixContext, bDesc);
                viBuffer.SetData(new[] { 1u });
                mtrl["brdf"].Set(viBuffer);
            }
        }
        private void BuildMaterials(SceneMaterial[] sceneMaterials, SceneResourceReference[] sceneResources)
        {
            foreach (var sceneMaterial in sceneMaterials)
            {
                var material = new Material(Session.OptixContext);
                if (this.Materials == null)
                {
                    this.Materials = new Dictionary<string, Material>(StringComparer.InvariantCultureIgnoreCase);
                }
                this.Materials.Add(sceneMaterial.Name, material);
                sceneMaterial.ResolveReferences();
                if (OnMaterialScriptsResolve != null)
                {
                    var args = new MaterialResolveArgs { MaterialName = sceneMaterial.Name, IsVolume = MaterialManager.IsVolume(sceneMaterial.Name) };
                    var scripts = OnMaterialScriptsResolve(args).ToArray();
                    for (int n = 0; n < RayTypeCount; n++)
                    {

                        material.Programs[n] = new SurfaceProgram(Session.OptixContext, n == 0 ? RayHitType.Closest : RayHitType.Any, scripts[n].PtxPath, scripts[n].Method);

                        //material["diffuse_color"].SetFloat3((Vector3)sceneMaterial["diffuse_color"]);
                        //material["glossy_color"].SetFloat3((Vector3)sceneMaterial["gloss_color"]);
                        //material["specular_color"].SetFloat3((Vector3)sceneMaterial["specular_color"]);
                        //material["index_of_refraction"].Set(1.5f);
                        //material["phong_exp"].Set((float)sceneMaterial["exponent"]);

                        //(Vector3)sceneMaterial["emission_color"]

                        string diffuse_map = sceneMaterial.Get<string>("!diffuse_map", null);
                        string alpha_map = sceneMaterial.Get<string>("!alpha_map", null);
                        string bump_map = sceneMaterial.Get<string>("!bump_map", null);
                        var samplers = LoadTextures(diffuse_map, bump_map, alpha_map, material);

                        var materialDescription = new MaterialDescription()
                        {
                            diffuse = (Vector3)sceneMaterial["diffuse_color"],
                            gloss = (Vector3)sceneMaterial["gloss_color"],
                            specular = (Vector3)sceneMaterial["specular_color"],
                            index_of_refraction = sceneMaterial.Get("index_of_refraction", 1.5f),
                            roughness = sceneMaterial.Get("roughness", 1.0f),
                            reflectivity = sceneMaterial.Get("reflectivity", 0.75f),
                            exponent = (float)sceneMaterial["exponent"],
                            emission = (Vector3)sceneMaterial["emission_color"]
                        };
                        if (samplers[0] > 0)
                        {
                            materialDescription.diffuse_tex = samplers[0];
                            materialDescription.use_diffuse = 1;
                        }

                        if (samplers[1] > 0)
                        {
                            materialDescription.bump_tex = samplers[1];
                            materialDescription.use_bump = 1;
                        }

                        if (samplers[2] > 0)
                        {
                            materialDescription.alpha_tex = samplers[2];
                            materialDescription.use_alpha = 1;
                        }
                        if (this.MaterialDescriptions == null)
                        {
                            this.MaterialDescriptions = new List<MaterialDescription>();
                        }
                        this.MaterialDescriptions.Add(materialDescription);
                        material["material_description_id"].Set(this.MaterialDescriptions.IndexOf(materialDescription));
                        sceneMaterial["MaterialDescriptionIndex"] =
                            this.MaterialDescriptions.IndexOf(materialDescription);
                        if (args.IsVolume)
                        {
                            material["use_density_map"].Set(1);
                            if (densityMap == null)
                            {
                                uint w = 126, h = 126, d = 126;
                                byte[] voxelData = new byte[w * h * d];
                                //Random rnd = new Random();

                                //for (int i = 0; i < w; i++)
                                //    for (int j = 0; j < h; j++)
                                //        for (int k = 0; k < d; k++)
                                //        {
                                //            voxelData[i + w * (j + k * d)] = (byte)(rnd.Next(255 - i));
                                //        }

                                var voxData = VolumeDataManager.OpenSlab(@"C:\Users\aircraft\Downloads\MagicaVoxel-0.97-win-mac\export\export\maze.slab.vox");
                                //VolumeDataManager.OpenXRaw(@"C:\Users\aircraft\Downloads\MagicaVoxel-0.97-win-mac\export\export\monu1.xraw");
                                w = (uint)voxData.Width;
                                h = (uint)voxData.Height;
                                d = (uint)voxData.Depth;
                                voxelData = voxData.Data;

                                var voxDataBuffer = new Buffer(ComponentPipeline.Instance.Session.OptixContext, new BufferDesc()
                                {
                                    Width = w,
                                    Depth = d,
                                    Height = h,
                                    Format = Format.Byte,
                                    Type = BufferType.Input
                                });
                                voxDataBuffer.SetData(voxelData);
                                densityMap = new TextureSampler(ComponentPipeline.Instance.Session.OptixContext, TextureSamplerDesc.Default);
                                densityMap.SetBuffer(voxDataBuffer, 0U);
                            }
                            material["density_map"].Set(densityMap.GetId());
                        }
                    }
                }
                else
                {
                    throw new ApplicationException("Material resolve event is not initialized");
                }

                //Evaluate programs count - engine dependent
                //Set programs - dependent on prev. step

                //END TODO

                sceneMaterial.InitializeOptixEntity(material, sceneMaterial.Name + " : " + ((BrdfTypes)sceneMaterial["brdf_id"]));
            }
        }
        private void BuildGeometry(SceneMeshData SceneData, SceneMeshEntity[] sceneMesh, bool hasAreaLights = false, IEnumerable<SceneLightsource> areaLights = null)
        {
            topObject = new GeometryGroup(Session.OptixContext);
            Session.OptixContext["scene_sphere_radius"].Set(SceneData.BoundingSphereRadius);
            Session.OptixContext["scene_sphere_center"].SetFloat3(SceneData.BoundingSphereCenter);

            var vDesc = new BufferDesc { Width = (uint)SceneData.Positions.Count, Format = Format.Float3, Type = BufferType.Input };
            var nDesc = new BufferDesc { Width = (uint)SceneData.Normals.Count, Format = Format.Float3, Type = BufferType.Input };
            var tcDesc = new BufferDesc { Width = (uint)SceneData.TexCoords.Count, Format = Format.Float2, Type = BufferType.Input };

            var vBuffer = new Buffer(Session.OptixContext, vDesc);
            var nBuffer = new Buffer(Session.OptixContext, nDesc);
            var tcBuffer = new Buffer(Session.OptixContext, tcDesc);

            vBuffer.SetData(SceneData.Positions.ToArray());
            nBuffer.SetData(SceneData.Normals.ToArray());
            tcBuffer.SetData(SceneData.TexCoords.ToArray());

            var lightTriangleIndexes = new Dictionary<string, List<int>>(StringComparer.InvariantCultureIgnoreCase);

            var instances = new List<GeometryInstance>();
            var triLights = new List<TriangleLight>();
            int idx = 0;
            foreach (var group in sceneMesh)
            {
                //empty group

                if (group.VertexIndexes.Count == 0 && group.NormalIndexes.Count == 0 && group.TextureIndexes.Count == 0)
                    continue;

                var center = new Vector3();
                foreach (var vi in group.VertexIndexes)
                {
                    center += SceneData.Positions[vi.X];
                    center += SceneData.Positions[vi.Y];
                    center += SceneData.Positions[vi.Z];
                    center /= 3.0f;
                }
                //ValidateGroup( group );

                //var mat = this.ResolveMaterial(group.Material);

                bool normalsUseVIndices = GenerateNormals && group.NormalIndexes.Count == 0 && SceneData.Normals.Count > 0;

                if (normalsUseVIndices)
                    Debug.Assert(SceneData.Normals.Count == SceneData.Positions.Count);

                int numNormIndices = normalsUseVIndices ? group.VertexIndexes.Count : group.NormalIndexes.Count;

                var viDesc = new BufferDesc() { Width = (uint)group.VertexIndexes.Count, Format = Format.Int3, Type = BufferType.Input };
                var niDesc = new BufferDesc() { Width = (uint)numNormIndices, Format = Format.Int3, Type = BufferType.Input };
                var tiDesc = new BufferDesc() { Width = (uint)group.TextureIndexes.Count, Format = Format.Int3, Type = BufferType.Input };

                var viBuffer = new Buffer(Session.OptixContext, viDesc);
                var niBuffer = new Buffer(Session.OptixContext, niDesc);
                var tiBuffer = new Buffer(Session.OptixContext, tiDesc);

                viBuffer.SetData(group.VertexIndexes.ToArray());
                niBuffer.SetData(normalsUseVIndices ? group.VertexIndexes.ToArray() : group.NormalIndexes.ToArray());
                tiBuffer.SetData(group.TextureIndexes.ToArray());

                var geometry = new Geometry(Session.OptixContext);
                string intersect_program = "mesh_intersect";
                string isect_script = IntersectionScript;
                //if (!string.IsNullOrWhiteSpace(group.mtrl) && matTypes.ContainsKey(group.mtrl))
                //{
                //    if (matTypes[group.mtrl].Equals("Volume"))
                //    {
                //        intersect_program = "volume_mesh_intersect";
                //        isect_script = GetScript("triangle_mesh_iterative.ptx");
                //    }
                //}

                geometry.IntersectionProgram = new Program(Session.OptixContext, isect_script, intersect_program);
                geometry.BoundingBoxProgram = new Program(Session.OptixContext, isect_script, "mesh_bounds");
                geometry.PrimitiveCount = (uint)group.VertexIndexes.Count;

                geometry["vertex_buffer"].Set(vBuffer);
                geometry["normal_buffer"].Set(nBuffer);
                geometry["texcoord_buffer"].Set(tcBuffer);
                geometry["vindex_buffer"].Set(viBuffer);
                geometry["nindex_buffer"].Set(niBuffer);
                geometry["tindex_buffer"].Set(tiBuffer);

                var instance = new GeometryInstance(Session.OptixContext);
                instance.Geometry = geometry;
                instance["geometric_center"].SetFloat3(center);
                //instance.AddMaterial(mat);
                group.EngineEntity = geometry;
                if (group.Material != null)
                {
                    int lindex;
                    if (hasAreaLights && MeshIsLight(group.Name, out lindex))
                    {
                        instance.AddMaterial(this.GetLightMaterial(group.Material, lindex));
                    }
                    else
                    {
                        var mtrl = ResolveMaterial(group.Material);

                        if (mtrl != null)
                        {
                            group.Material.EngineEntity = mtrl;
                            instance.AddMaterial(mtrl);
                            SetDefaultMaterialProperties(instance, mtrl, group.Material);
                        }
                        else
                        {
                            Tracer.WriteLine("Mesh {0} missed material {1}", group.Name, group.Material.Name);
                        }
                    }
                }
                else
                {
                    Tracer.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ----Mesh {0} missed material {1}", group.Name, group.Material);
                    Console.ReadLine();
                }

                //if (!string.IsNullOrWhiteSpace(LightNameTemplate))
                //{
                //    Regex lightReg = new Regex(LightNameTemplate, RegexOptions.IgnoreCase);

                //    if (lightReg.IsMatch(group.Name))
                //    {
                //        var lt = new Lightsource()
                //        {
                //            Type = LightSourceTypes.Area,
                //            Emission = Scene.LightGain,
                //            Name = group.Name,
                //        };
                //        lt[Lightsource.AreaMeshName] = group.Name;
                //        Scene.Lights = Scene.Lights.Union(new[] { lt }).ToArray();
                //    }
                //}

                if (hasAreaLights)
                {
                    var light =
                        areaLights.FirstOrDefault(
                            lt => lt.Name.Equals(group.Name, StringComparison.InvariantCultureIgnoreCase));
                    //    SetDefaultLightProperties(instance, light);

                    if (light != null)
                    {
                        var ti = new List<int>();
                        lightTriangleIndexes.Add(group.Name, ti);
                        for (int index = 0; index < group.VertexIndexes.Count; index++)
                        {
                            var vIndex = group.VertexIndexes[index];
                            var v1 = SceneData.Positions[vIndex.X];
                            var v2 = SceneData.Positions[vIndex.Y];
                            var v3 = SceneData.Positions[vIndex.Z];
                            var e1 = v2 - v3;
                            var e2 = v1 - v3;
                            Vector3 n = Vector3.Cross(ref e1, ref e2);//SceneGraph.LightOrientation *
                            if (group.NormalIndexes.Any())
                            {
                                n = (SceneData.Normals[group.NormalIndexes[index].X]);//Scene.LightOrientation *
                            }

                            n.Normalize();
                            ti.Add(idx + 1);
                            triLights.Add(new TriangleLight()
                            {
                                color = light.Color, //Emission * emissionScale,
                                v1 = v1,
                                v2 = v2,
                                v3 = v3,
                                normal = n,
                                idx = idx++
                            });
                        }
                    }
                }
                instances.Add(instance);
            }

            var Builder = AccelBuilder.Sbvh;
            var Traverser = AccelTraverser.Bvh;

            //create an acceleration structure for the geometry
            var accel = new Acceleration(Session.OptixContext, Builder, Traverser);

            if (Builder == AccelBuilder.Sbvh || Builder == AccelBuilder.TriangleKdTree)
            {
                accel.VertexBufferName = "vertex_buffer";
                accel.IndexBufferName = "vindex_buffer";
            }

            //now attach the instance and accel to the geometry group
            topObject.Acceleration = accel;
            topObject.AddChildren(instances);
            topObject.Acceleration.MarkAsDirty();
            BuildCache.Add("LightTrianglesIndexes", lightTriangleIndexes);
            BuildCache.Add("LightTriangles", triLights);
        }