Пример #1
0
        public MainWindow()
        {
            InitializeComponent();

            DateTime start = DateTime.Now;

            Scene.Scene  scene = Scene.ReferenceScene;
            BitmapSource rt    = RayTrace.Render(scene, 1000, 1000);

            image1.Source = rt;

            DateTime end      = DateTime.Now;
            TimeSpan duration = end - start;

            textBox1.Text = rt.Width.ToString() + "x" + rt.Height.ToString() + " image took " + (duration.TotalMilliseconds / 1000.0).ToString("F2") + "s";
        }
Пример #2
0
        public override void CursorUpdate(World world, Player player, Vector2 cursorPosition)
        {
            WorldCamera camera = world.worldCamera;

            if (!camera.turning)
            {
                RayTrace rayTrace = camera.GetRayAtScreenPosition(cursorPosition - camera.worldContainer.GetPosition());

                if (rayTrace.hit)
                {
                    bool inRange = (rayTrace.hitPosition - player.worldPosition).sqrMagnitude < 25f;

                    if (Input.GetKey(KeyCode.Mouse0) && inRange)
                    {
                        player.UseItem(Vector3Int.FloorToInt(rayTrace.hitTilePosition + rayTrace.hitDirection), Input.GetKeyDown(KeyCode.Mouse0));
                    }

                    SetConstructionGuide(camera, player, rayTrace.hitTilePosition + Vector3.one * 0.5f, rayTrace.hitDirection, inRange);
                    _previewSprite.isVisible = true;
                }
            }
        }
Пример #3
0
        public override void CursorUpdate(World world, Player player, Vector2 cursorPosition)
        {
            WorldCamera camera = world.worldCamera;

            if (!camera.turning)
            {
                RayTrace rayTrace = camera.GetRayAtScreenPosition(cursorPosition - camera.worldContainer.GetPosition());

                Tile tile = rayTrace.GetTileIn(world);

                if (tile != _lastTile)
                {
                    _progress = 0f;
                    _lastTile = tile;
                }

                if (rayTrace.hit)
                {
                    bool inRange = (rayTrace.hitPosition - player.worldPosition).sqrMagnitude < 25f;

                    if (Input.GetKey(KeyCode.Mouse0) && inRange)
                    {
                        bool clicked = _progress >= 1f;

                        if (clicked)
                        {
                            _progress = 0f;
                        }

                        player.UseItem(rayTrace.hitTilePosition, clicked); // Input.GetKeyDown(KeyCode.Mouse0));
                    }

                    SetConstructionGuide(camera, player, rayTrace.hitTilePosition, inRange, _progress);
                    _previewSprite.isVisible = true;
                }
            }
        }
Пример #4
0
        public VoxelBlock Raycast(Ray ray, out VoxelBlock emptyTargetedBlock)
        {
            VoxelBlock last      = null;
            VoxelBlock ret       = null;
            var        traverser = new GridTraverser();


            float?closest = null;


            foreach (VoxelTerrainChunk terr in TW.Data.Objects.Where(o => o is VoxelTerrainChunk))
            {
                var trace = new RayTrace();
                trace.Ray = ray;

                float?dist = trace.Ray.xna().Intersects(terr.GetBoundingBox().xna());
                if (!dist.HasValue)
                {
                    continue;
                }
                if (closest.HasValue && closest.Value < dist.Value)
                {
                    continue;
                }

                trace.Start = dist.Value + 0.001f;



                traverser.NodeSize   = terr.NodeSize;
                traverser.GridOffset = terr.WorldPosition;

                //TODO: fix multiple terrains


                var hit = false;


                VoxelTerrainChunk terr1 = terr;
                traverser.Traverse(trace, delegate(Point3 arg)
                {
                    if (!terr1.InGrid(arg))
                    {
                        return(true);
                    }

                    var voxelBlock = terr1.GetVoxelInternal(ref arg);
                    if (voxelBlock == null)
                    {
                        return(false);
                    }
                    if (voxelBlock.Filled)
                    {
                        hit = true;
                        ret = getChunkVoxelWrapper(terr1, arg);
                        return(true);
                    }
                    last = getChunkVoxelWrapper(terr1, arg);
                    return(false);
                });


                if (hit)
                {
                    closest = dist;
                }
            }
            emptyTargetedBlock = last;
            return(ret);
        }
Пример #5
0
        public override void CursorUpdate(World world, Player player, Vector2 cursorPosition)
        {
            WorldCamera    camera  = world.worldCamera;
            List <ITarget> targets = world.targets;

            ITarget nearestTarget = null;

            Vector2 screenPositionA, screenPositionB;

            screenPositionA = new Vector2(1920f, 1080f);

            for (int index = 0; index < targets.Count; index++)
            {
                screenPositionB = camera.GetScreenPosition(targets[index].worldPosition) + camera.worldContainer.GetPosition();

                float sqrMagnitude = (screenPositionB - cursorPosition).sqrMagnitude;

                //if ((screenPositionB.x > Menu.screenWidth * 0.5f || screenPositionB.x < Menu.screenWidth * -0.5f) ||
                //    (screenPositionB.y > Menu.screenHeight * 0.5f || screenPositionB.y < Menu.screenHeight * -0.5f))
                if (sqrMagnitude > 4096f)
                {
                    continue;
                }

                else if ((screenPositionA - cursorPosition).sqrMagnitude > sqrMagnitude)
                {
                    nearestTarget   = targets[index];
                    screenPositionA = screenPositionB;
                }
            }

            if (_currentTarget != nearestTarget)
            {
                _lastScreenPosition = position;
                _lastSize           = size;

                _currentTarget = nearestTarget;
                _lastTime      = menu.time;

                _targetInspector.InspectTarget(_currentTarget);
            }

            if (_currentTarget != null)
            {
                _targetScreenPosition = screenPositionA + nearestTarget.boundRect.position;
                _targetSize           = nearestTarget.boundRect.size;

                if (Input.GetKey(KeyCode.Mouse0))
                {
                    player.UseItem(_currentTarget.worldPosition, Input.GetKeyDown(KeyCode.Mouse0));
                }
            }

            else
            {
                _targetScreenPosition = cursorPosition;
                _targetSize           = new Vector2(12f, 12f);

                if (Input.GetKey(KeyCode.Mouse0))
                {
                    RayTrace rayTrace = camera.GetRayAtScreenPosition(cursorPosition - camera.worldContainer.GetPosition());

                    Vector3 targetPosition = new Vector3(rayTrace.hitPosition.x, player.worldPosition.y, rayTrace.hitPosition.z);

                    if (rayTrace.hit)
                    {
                        player.UseItem(targetPosition, Input.GetKeyDown(KeyCode.Mouse0));
                    }
                }
            }
        }
Пример #6
0
    Color TraceColor(Vector3 startPos, Vector3 rayDir, int sample, int depth)
    {
        if (depth <= 0)
        {
            return(Color.black);
        }
        RayTrace.Ray ray = new RayTrace.Ray(startPos, rayDir, 1000);
        RayTrace.Intersect(ref ray);
        if (ray.geomID == RayTrace.Invalid)
        {
            return(skyColor);
        }
        else
        {
            SimpleModel model    = scene.models[(int)ray.geomID];
            SimpleMesh  mesh     = model.mesh;
            int         t0       = mesh.triangles[ray.primID * 3 + 0];
            int         t1       = mesh.triangles[ray.primID * 3 + 1];
            int         t2       = mesh.triangles[ray.primID * 3 + 2];
            Vector2     uv       = RayTraceTool.Lerp(mesh.uv[t0], mesh.uv[t1], mesh.uv[t2], ray.u, ray.v);
            Color       texColor = model.material.LinearSample(uv);

            if (!ignoreMaterialColor)
            {
                texColor *= model.material.GetColor();
            }

            if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Opaque)
            {
                texColor.a = 1;
            }

            Vector3 hitPos    = ray.pos + ray.dir * ray.length;
            Vector3 hitNormal = RayTraceTool.Lerp(mesh.normals[t0], mesh.normals[t1], mesh.normals[t2], ray.u, ray.v);
            hitNormal = (model.rst.rot * hitNormal);


            float transFactor   = 1 - texColor.a;
            float glossiness    = model.material.glossiness;
            float reflectFactor = Mathf.Lerp(0.2f * glossiness, 1f, model.material.metallic);
            if (reflectFactor > 0.01f)
            {
                reflectFactor = Fresnel_Schlick(Vector3.Dot(-rayDir, hitNormal), reflectFactor);
            }
            float grayscale     = texColor.grayscale;
            float diffuseFactor = Mathf.Clamp01(1 - transFactor - reflectFactor);

            int transSample   = (int)(sample * grayscale * transFactor);
            int reflectSample = (int)(sample * reflectFactor);
            int diffuseSample = (int)(sample * grayscale * diffuseFactor);


            Color finaleColor = Color.black;

            Color reflectColor = Color.black;
            {
                Color finalLightColor = Color.black;// GetAllLightsColor(model, hitPos, hitNormal) * (reflectFactor + scene.lights.Length);//光源直接贡献
                if (reflectSample > 0)
                {
                    Vector3   reflectDir = Vector3.Reflect(rayDir, hitNormal);
                    Vector3[] dirs       = RayTraceTool.GetRandomDirs_BlinnPhong_Importance2(hitNormal, reflectDir, glossiness, reflectSample);
                    for (int i = 0; i < reflectSample; i++)
                    {
                        finalLightColor += TraceColor(hitPos + hitNormal * 0.01f, dirs[i], 1, depth - 1);//间接光贡献
                    }
                    finalLightColor /= (reflectSample);
                }
                reflectColor = Color.Lerp(Color.white, texColor, model.material.metallic) * finalLightColor;
            }

            Color diffuseColor = Color.black;
            {
                Color finalLightColor = GetAllLightsColor(model, hitPos, hitNormal) * (diffuseSample + scene.lights.Length);//光源直接贡献
                if (diffuseSample > 0)
                {
                    Vector3   reflectDir = Vector3.Reflect(rayDir, hitNormal);
                    Vector3[] dirs       = RayTraceTool.GetRandomDirs_RoundProj(hitNormal, diffuseSample);
                    for (int i = 0; i < diffuseSample; i++)
                    {
                        finalLightColor += TraceColor(hitPos + hitNormal * 0.01f, dirs[i], 1, depth - 1);//间接光贡献
                    }
                }
                finalLightColor /= (diffuseSample + scene.lights.Length);
                diffuseColor     = texColor * finalLightColor;
            }

            //Color reflectColor = Color.black;
            //if(reflectFactor > 0.01f){
            //    Vector3 refDir = Vector3.Reflect(rayDir,hitNormal);
            //    Color finalLightColor = TraceColor(hitPos + refDir * 0.01f, refDir,reflectSample ,depth - 1);
            //    reflectColor = finalLightColor;
            //}

            finaleColor = reflectColor * reflectFactor + diffuseColor * diffuseFactor;

            if (texColor.a < 0.99f)
            {
                Color transColor = TraceColor(hitPos + rayDir * 0.01f, rayDir, transSample, depth);
                if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Alphablend)
                {
                    finaleColor = finaleColor * texColor.a + transColor * (1 - texColor.a);
                }
                else if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Multiply)
                {
                    finaleColor = finaleColor * transColor;
                }
                else if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Additive)
                {
                    finaleColor = finaleColor + transColor;
                }
            }

            return(finaleColor);
        }
    }
Пример #7
0
 public void Release()
 {
     RayTrace.Release();
     SimpleMaterial.textures.Clear();
     scene = null;
 }
Пример #8
0
    public void Init()
    {
        Instance = this;
        updateProgress(0);
        HaltonTool.InitHaltonSequence();

        Debug.Log("Start Time : " + Time.realtimeSinceStartup);

        scene = new SimpleScene();

        RayTrace.Init();
        SimpleMaterial.textures.Clear();

        scene.lights = GameObject.FindObjectsOfType <Light>();

        Camera cam = GetComponent <Camera>();

        if (cam)
        {
            MeshRenderer[] renderers = GameObject.FindObjectsOfType <MeshRenderer>();
            foreach (MeshRenderer r in renderers)
            {
                bool isLayerVisible = ((1 << r.gameObject.layer) & cam.cullingMask) != 0;
                if (r.isVisible && isLayerVisible)
                {
                    MeshFilter filter = r.gameObject.GetComponent <MeshFilter>();
                    if (filter && filter.sharedMesh)
                    {
                        for (int i = 0; i < filter.sharedMesh.subMeshCount; i++)
                        {
                            Mesh  mesh      = filter.sharedMesh;
                            int[] triangles = filter.sharedMesh.GetTriangles(i);
                            RayTrace.AddMesh(filter.gameObject.transform, mesh.vertexCount, triangles.Length, mesh.vertices, triangles, 1);
                            SimpleModel model = new SimpleModel(r.gameObject.transform, filter.sharedMesh, i, r.sharedMaterials[i]);
                            model.lights = RayTraceTool.GetActivityLights(r, scene);
                            scene.models.Add(model);
                        }
                    }
                }
            }
            Terrain[] terrains = GameObject.FindObjectsOfType <Terrain>();
            foreach (Terrain terrain in terrains)
            {
                bool isLayerVisible = ((1 << terrain.gameObject.layer) & cam.cullingMask) != 0;
                if (terrain.gameObject.activeInHierarchy && isLayerVisible)
                {
                    int   w          = terrain.terrainData.heightmapWidth;
                    int   h          = terrain.terrainData.heightmapHeight;
                    float realWidth  = terrain.terrainData.size.x * (1 + 1f / w);
                    float realHeight = terrain.terrainData.size.z * (1 + 1f / h);
                    float[,] heights = terrain.terrainData.GetHeights(0, 0, w, h);
                    Vector3[] vertices  = new Vector3[w * h];
                    Vector2[] uvs       = new Vector2[vertices.Length];
                    Vector3[] normals   = new Vector3[vertices.Length];
                    int[]     triangles = new int[(w - 1) * (h - 1) * 2 * 3];
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            Vector3 pos = new Vector3(i * realWidth / w, heights[j, i] * terrain.terrainData.size.y, j * realHeight / h);
                            vertices[j * w + i] = pos;
                            uvs[j * w + i]      = new Vector2(i / (float)w, j / (float)h);
                            normals[j * w + i]  = terrain.terrainData.GetInterpolatedNormal(i / (float)w, j / (float)h);
                        }
                    }

                    for (int i = 0; i < w - 1; i++)
                    {
                        for (int j = 0; j < h - 1; j++)
                        {
                            int index = (j * (w - 1) + i) * 6;
                            triangles[index + 0] = (i + 0) + (j + 0) * w;
                            triangles[index + 1] = (i + 1) + (j + 1) * w;
                            triangles[index + 2] = (i + 1) + (j + 0) * w;
                            triangles[index + 3] = (i + 0) + (j + 0) * w;
                            triangles[index + 4] = (i + 0) + (j + 1) * w;
                            triangles[index + 5] = (i + 1) + (j + 1) * w;
                        }
                    }

                    RayTrace.AddMesh(terrain.transform, vertices.Length, triangles.Length, vertices, triangles, 1);
                    SimpleModel model = new SimpleModel();
                    model.mesh     = new SimpleMesh(triangles, uvs, vertices, normals);
                    model.material = new SimpleTerrainMaterial(terrain.terrainData);
                    model.rst      = new RayTrace.RST(terrain.transform.rotation, terrain.transform.lossyScale, terrain.transform.position);
                    model.lights.AddRange(scene.lights);
                    scene.models.Add(model);
                }
            }
        }

        RayTrace.Commit();

        texture = new Texture2D(width, height, TextureFormat.ARGB32, true);
        //viewResult.sharedMaterial.mainTexture = texture;
    }