Esempio n. 1
0
        public static RayCastResult rayCast(Vector3 startPos, Vector3 dir, RayCastManager rtm, float length, RayCastBlockType mask)
        {
            DirInfo dirInfo       = new DirInfo(dir);
            Vector3 startPosInner = startPos;
            float   hitTime       = 0;
            float   startOffset   = 0;
            bool    bHitBounds    = true;//能击中总区域,或者在内部

            if (startPos.x >= 0 && startPos.x < rtm.getSizeX() && startPos.y >= 0 && startPos.y < rtm.getSizeY() && startPos.z >= 0 && startPos.z < rtm.getSizeZ())
            {
                bHitBounds = true;
            }
            else
            {
                bHitBounds = Misc.rayHitAABB(startPos, dir, new Vector3(0, 0, 0), rtm.getSize(), ref hitTime);
                if (hitTime > 0)
                {
                    startOffset = hitTime;
                }
                startPosInner = startPos + dir * startOffset - dir * 0.01f;
            }
            if (bHitBounds)
            {
                RayCastResult rlt = rayTraceSmall(startPosInner, dirInfo, rtm, Face.FNI_Unknown, length - startOffset, mask);
                rlt.hitLength += startOffset;
                return(rlt);
            }
            else
            {
                return(new RayCastResult(false, 0, 0, 0, Face.FNI_Unknown, 0));
            }
        }
Esempio n. 2
0
        public static void SetExtendAo(List <MeshTool.BlockSurface> surface, RayCastManager scene, int normalIndex, VecInt3 gpos)
        {
            for (int i = 0; i < surface.Count; i++)
            {
                VecInt3 pos    = surface[i].pos;
                VecInt3 adjPos = new VecInt3();
                adjPos.x = pos.x + Const.AdjacencyOffsetV[normalIndex].x + gpos.x;
                adjPos.y = pos.y + Const.AdjacencyOffsetV[normalIndex].y + gpos.y;
                adjPos.z = pos.z + Const.AdjacencyOffsetV[normalIndex].z + gpos.z;
                for (int v = 0; v < 4; v++)
                {
                    int curLight = scene.getLight(adjPos.x, adjPos.y, adjPos.z);
                    int num      = 1;
                    for (int b = 0; b < 3; b++)
                    {
                        int sx = Const.VertexSharedOffset[normalIndex, v, b, 0];
                        int sy = Const.VertexSharedOffset[normalIndex, v, b, 1];
                        int sz = Const.VertexSharedOffset[normalIndex, v, b, 2];
                        if (!scene.testBlock(adjPos.x + sx, adjPos.y + sy, adjPos.z + sz, RayCastBlockType.Opacity))
                        {
                            curLight += scene.getLight(adjPos.x + sx, adjPos.y + sy, adjPos.z + sz);
                            num++;
                        }
                    }

                    surface[i].extendAo[v] = curLight / (Const.MaxLightIteration * num * 1.0f);
                }
            }
        }
Esempio n. 3
0
        static float calcDirectSunLight(RayCastManager rayTraceManager, Vector3 sunDir, int globalX, int globalY, int globalZ, int faceIndex)
        {
            //计算ao
            Vector3 faceNormal      = Const.getFaceNormal(faceIndex);
            float   faceLightFactor = Vector3.Dot(faceNormal, -sunDir);

            if (faceLightFactor < 0)
            {
                return(0);
            }
            else
            {
                Vector3 startPos  = (new Vector3(globalX, globalY, globalZ) + Vector3.one * 0.5f + faceNormal * 0.501f) * Const.BlockSize;
                float   rayLength = 100.0f;
                //float brightness = 0.0f;
                RayCastRestult rlt = rayTraceManager.rayCast(startPos, -sunDir, rayLength, RayCastBlockType.All);
                if (rlt.bHit)
                {
                    return(0);
                }
                else
                {
                    return(faceLightFactor);
                }
            }
        }
Esempio n. 4
0
        static float calcAo(RayCastManager rayTraceManager, Vector3[] rays, int globalX, int globalY, int globalZ, int faceIndex)
        {
            //计算ao
            Vector3 startPos   = (new Vector3(globalX, globalY, globalZ) + Vector3.one * 0.5f + Const.getFaceNormal(faceIndex) * 0.51f) * Const.BlockSize;
            float   rayLength  = 16;
            float   brightness = 0.0f;

            Vector3[] startPosArray  = new Vector3[rays.Length];
            float[]   rayLenghtArray = new float[rays.Length];
            for (int i = 0; i < startPosArray.Length; i++)
            {
                startPosArray[i]  = startPos;
                rayLenghtArray[i] = rayLength;
            }
            RayCastRestult[] rlts = rayTraceManager.batchRayCast(startPosArray, rays, rayLenghtArray, RayCastBlockType.Opacity);
            for (uint i = 0; i < rays.Length; i++)
            {
                RayCastRestult rlt = rlts[i];//rayTraceManager.rayCast(startPos, rays[i], rayLength);
                if (rlt.bHit && rlt.hitLength < rayLength)
                {
                    float a = ((rlt.hitLength) / rayLength);
                    brightness += (a / rays.Length);
                }
                else
                {
                    brightness += 1.0f / rays.Length;
                }
            }
            brightness = Mathf.Clamp(brightness, 0.0f, 1.0f);
            return(Mathf.Pow(brightness, 0.8f) * 0.9f + 0.1f);
        }
Esempio n. 5
0
 public static void calcLight(BlockManager blockManager, RayCastManager rayTraceManager, Vector3[][] rays, Vector3 sunDir)
 {
     ////射线求交方式计算AO
     //blockManager.forEachChunk((BlockChunk chunk, int i, int j, int k) => {
     //    if (!chunk.isEmpty()) {
     //        calcChunkLight(chunk, i, j, k, rayTraceManager, rays, sunDir);
     //    }
     //});
 }
Esempio n. 6
0
        private static Texture3D Create3DTexture(RayCastManager rtc)
        {
            Texture3D voxelTexture = new Texture3D(rtc.getSizeX(), rtc.getSizeY() / 8, rtc.getSizeZ(), TextureFormat.Alpha8, false);

            voxelTexture.filterMode = FilterMode.Point;
            voxelTexture.wrapMode   = TextureWrapMode.Clamp;
            voxelTexture.SetPixels(ToColorsA(rtc, 8));
            voxelTexture.Apply();
            return(voxelTexture);
        }
Esempio n. 7
0
        public static Color[] ToColorsA(RayCastManager rtc, int bits)
        {
            int dgx = rtc.getSizeX();
            int dgy = rtc.getSizeY();
            int dgz = rtc.getSizeZ();

            Color[,,] colors = new Color[dgx, (dgy / bits), dgz];
            for (int gx = 0; gx < dgx; gx++)
            {
                for (int gy = 0; gy < dgy / bits; gy++)
                {
                    for (int gz = 0; gz < dgz; gz++)
                    {
                        int iv = 0;
                        for (int n = 0; n < bits; n++)
                        {
                            iv |= rtc.testBlock(gx, gy * bits + n, gz, RayCastBlockType.Opacity) ? (1 << n) : 0;
                        }
                        float a = iv / (float)((1 << bits) - 1);
                        colors[gx, gy, gz] = new Color(0, 0, 0, a);
                    }
                }
            }


            int sizeX = colors.GetLength(0);
            int sizeY = colors.GetLength(1);
            int sizeZ = colors.GetLength(2);

            Color[] rlt = new Color[sizeX * sizeY * sizeZ];
            for (int x = 0; x < sizeX; x++)
            {
                for (int y = 0; y < sizeY; y++)
                {
                    for (int z = 0; z < sizeZ; z++)
                    {
                        rlt[z * sizeY * sizeX + y * sizeX + x] = colors[x, y, z];
                    }
                }
            }
            return(rlt);
        }
Esempio n. 8
0
    public void DoGenerate()
    {
        float startTime = Time.realtimeSinceStartup;

        bm.create(numX * Const.ChunkSize, numY * Const.ChunkSize, numZ * Const.ChunkSize, new BlockTypeFun());

        for (int x = 0; x < bm.SizeX; x++)
        {
            for (int y = 0; y < bm.SizeY; y++)
            {
                for (int z = 0; z < bm.SizeZ; z++)
                {
                    //bm.setBlock(x, y, z, (short)(z < y ? Block.BlockTypeEnum.Air : Block.BlockTypeEnum.Sand));
                    bm.setBlock(x, y, z, (short)(y < 10 || (x == 20 && z > 10 && z <= 15) ? Block.BlockTypeEnum.Sand : Block.BlockTypeEnum.Air));
                }
            }
        }

        rtm = new Block.RayCastManager();
        rtm.create(numX, numY, numZ);
        for (int x = 0; x < bm.SizeX; x++)
        {
            for (int y = 0; y < bm.SizeY; y++)
            {
                for (int z = 0; z < bm.SizeZ; z++)
                {
                    rtm.setBlock(x, y, z, bm.getBlock(x, y, z) != 0 ? RayCastBlockType.All : RayCastBlockType.Nothing);
                }
            }
        }
        rma = new Block.RayMarchingAo();
        rma.Init(rtm);

        viewVoxel.SetVexelTex(rma.GetVoxelTexture());

        Debug.Log("生成完体素数据," + (Time.realtimeSinceStartup - startTime));
        StartCoroutine(GenerateMesh());
    }
Esempio n. 9
0
 public static void calcChunkLight(BlockChunk chunk, int cx, int cy, int cz, RayCastManager rayTraceManager, Vector3[][] rays, Vector3 sunDir)
 {
     //List<VecInt3>[] surfaces = chunk.calcSurfaceList();
     //for (int f = 0; f < 6; f++) {
     //    List<VecInt3> surs = surfaces[f];
     //    for (int i = 0; i < surs.Count; i++) {
     //        VecInt3 surface = surs[i];
     //        int gx = cx * Const.ChunkSize + surface.x;
     //        int gy = cy * Const.ChunkSize + surface.y;
     //        int gz = cz * Const.ChunkSize + surface.z;
     //        Vector3 faceNormal = Const.getFaceNormal(f);
     //        float faceLightFactor = Vector3.Dot(faceNormal, -sunDir);
     //        Vector3 startPos = (new Vector3(gx, gy, gz) + Vector3.one * 0.5f + faceNormal * 0.51f) * Const.BlockSize;
     //
     //        float directionLight = 0;
     //        float aoLight = 0;
     //        float aoLenght = 8.0f;
     //        if(faceLightFactor > 0){
     //            RayCastRestult rlt = rayTraceManager.rayCast(startPos, -sunDir, 30);
     //            directionLight += rlt.bHit ? 0 : faceLightFactor;
     //        }
     //        for (int r = 0; r < rays[f].Length; r++) {
     //            RayCastRestult rlt = rayTraceManager.rayCast(startPos, rays[f][r], aoLenght);
     //            if (rlt.bHit && rlt.hitLength < aoLenght) {
     //                float a = ((rlt.hitLength) / aoLenght);
     //                aoLight += (a / rays[f].Length);
     //            }
     //            else {
     //                aoLight += 1.0f / rays[f].Length;
     //            }
     //        }
     //        float brightness = directionLight * 0.35f + aoLight * 0.45f + 0.2f;
     //        brightness = Mathf.Clamp(brightness, 0, 1);
     //        chunk.setBrightness(surface.x, surface.y, surface.z, f, (Byte)(brightness * Const.MaxBrightness));
     //    }
     //}
 }
Esempio n. 10
0
 public void Init(RayCastManager rtc)
 {
     constValueTexture = CreateConstValueTexture();
     texVoxel3D        = Create3DTexture(rtc);
     calcAoMaterial    = new Material(Shader.Find("Hidden/RaytraceAo"));
 }
Esempio n. 11
0
        public static RayCastResult rayTraceSmall(Vector3 startPos, DirInfo dirInfo, RayCastManager rtm, Face faceIn, float maxLength, RayCastBlockType mask)
        {
            int   X        = (int)(startPos.x + dirInfo.stepX * 0.0001f);
            int   Y        = (int)(startPos.y + dirInfo.stepY * 0.0001f);
            int   Z        = (int)(startPos.z + dirInfo.stepZ * 0.0001f);
            float tMaxX    = (dirInfo.stepX > 0 ? (1 - (startPos.x - X)) : (startPos.x - X)) * dirInfo.tDeltaX;//沿射线走多远才能跳到下一个X格
            float tMaxY    = (dirInfo.stepY > 0 ? (1 - (startPos.y - Y)) : (startPos.y - Y)) * dirInfo.tDeltaY;
            float tMaxZ    = (dirInfo.stepZ > 0 ? (1 - (startPos.z - Z)) : (startPos.z - Z)) * dirInfo.tDeltaZ;
            int   outSizeX = dirInfo.stepX > 0 ? rtm.getSizeX() : -1;
            int   outSizeY = dirInfo.stepY > 0 ? rtm.getSizeY() : -1;
            int   outSizeZ = dirInfo.stepZ > 0 ? rtm.getSizeZ() : -1;

            while (true)
            {
                if (tMaxX < tMaxY)
                {
                    if (tMaxX < tMaxZ)
                    {
                        X += dirInfo.stepX;
                        if (X == outSizeX)
                        {
                            return(new RayCastResult(false, X, Y, Z, dirInfo.stepX > 0 ? Face.FNI_x0 : Face.FNI_x1, tMaxX));
                        }
                        else
                        {
                            if (tMaxX > maxLength)
                            {
                                return(new RayCastResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxX));
                            }
                            else if (rtm.testBlock(X, Y, Z, mask))
                            {
                                return(new RayCastResult(true, X, Y, Z, dirInfo.stepX > 0 ? Face.FNI_x0 : Face.FNI_x1, tMaxX));
                            }
                        }
                        tMaxX += dirInfo.tDeltaX;
                    }
                    else
                    {
                        Z += dirInfo.stepZ;
                        if (Z == outSizeZ)
                        {
                            return(new RayCastResult(false, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                        }
                        else
                        {
                            if (tMaxZ > maxLength)
                            {
                                return(new RayCastResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxZ));
                            }
                            else if (rtm.testBlock(X, Y, Z, mask))
                            {
                                return(new RayCastResult(true, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                            }
                        }
                        tMaxZ += dirInfo.tDeltaZ;
                    }
                }
                else
                {
                    if (tMaxY < tMaxZ)
                    {
                        Y += dirInfo.stepY;
                        if (Y == outSizeY)
                        {
                            return(new RayCastResult(false, X, Y, Z, dirInfo.stepY > 0 ? Face.FNI_y0 : Face.FNI_y1, tMaxY));
                        }
                        else
                        {
                            if (tMaxY > maxLength)
                            {
                                return(new RayCastResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxY));
                            }
                            else if (rtm.testBlock(X, Y, Z, mask))
                            {
                                return(new RayCastResult(true, X, Y, Z, dirInfo.stepY > 0 ? Face.FNI_y0 : Face.FNI_y1, tMaxY));
                            }
                        }

                        tMaxY += dirInfo.tDeltaY;
                    }
                    else
                    {
                        Z += dirInfo.stepZ;
                        if (Z == outSizeZ)
                        {
                            return(new RayCastResult(false, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                        }
                        else
                        {
                            if (tMaxZ > maxLength)
                            {
                                return(new RayCastResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxZ));
                            }
                            else if (rtm.testBlock(X, Y, Z, mask))
                            {
                                return(new RayCastResult(true, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                            }
                        }

                        tMaxZ += dirInfo.tDeltaZ;
                    }
                }
            }
        }
Esempio n. 12
0
    void Start()
    {
        SimpleModelFactory.CreateAll();
        texturePacker = new TexturePacker();
        Block.BlockManager bm = new Block.BlockManager();

        for (int i = 0; i < (int)Game.BlockType.Num; i++)
        {
            for (int f = 0; f < 6; f++)
            {
                Game.BlockType block = (Game.BlockType)i;
                texturePacker.AddTexture(block, f, TextureNameConfig.GetTextureName(block, f));
            }
        }


        texturePacker.Pack();
        packedTexture = texturePacker.GetPackedTexture();

        BlockTypeFun blockTypeFun = new BlockTypeFun();

        blockTypeFun.texturePacker = texturePacker;

        //float startTime = Time.realtimeSinceStartup;
        int WorldSizeX = 1;
        int WorldSizeY = 1;
        int WorldSizeZ = 1;

        //申请内存
        bm.create(WorldSizeX * Const.ChunkSize, WorldSizeY * Const.ChunkSize, WorldSizeZ * Const.ChunkSize, blockTypeFun);
        bm.setBlock(3, 4, 4, (int)Game.BlockType.StairLeft);
        bm.setBlock(5, 4, 4, (int)Game.BlockType.StairRight);
        bm.setBlock(4, 4, 3, (int)Game.BlockType.StairBack);
        bm.setBlock(4, 4, 5, (int)Game.BlockType.StairFront);

        //光线追踪初始化
        Block.RayCastManager rtm = new Block.RayCastManager();
        rtm.create(bm.SizeX, bm.SizeY, bm.SizeZ);
        for (int x = 0; x < bm.SizeX; x++)
        {
            for (int y = 0; y < bm.SizeY; y++)
            {
                for (int z = 0; z < bm.SizeZ; z++)
                {
                    rtm.setBlock(x, y, z, bm.getBlock(x, y, z) != 0 ? RayCastBlockType.All : RayCastBlockType.Nothing);
                }
            }
        }


        //初始化AO计算
        rma = new Block.RayMarchingAo();
        rma.Init(rtm);
        ViewVoxel viewVoxel = GameObject.FindObjectOfType <ViewVoxel>();

        if (viewVoxel)
        {
            Texture3D voxelTex3D = rma.GetVoxelTexture();
            viewVoxel.SetVexelTex(voxelTex3D);
        }

        Material mat = GlobalResources.getBlockMaterial();

        mat.mainTexture = texturePacker.GetPackedTexture();
        GameObject root = this.gameObject;

        if (root == null)
        {
            root = new GameObject("Root");
        }

        //创建网格
        for (int i = 0; i < WorldSizeX; i++)
        {
            for (int k = 0; k < WorldSizeZ; k++)
            {
                for (int j = 0; j < WorldSizeY; j++)
                {
                    Block.BlockChunk chunk = new BlockChunk(bm, i * Const.ChunkSize, j * Const.ChunkSize, k * Const.ChunkSize);
                    //TerrainTool.calcChunkLight(chunk, i, j, k, rtm, rays, sunDir);
                    //Mesh mesh = MeshTool.createMesh(chunk, blockTypeFun, 0, 0, 0);
                    for (int f = 0; f < 6; f++)
                    {
                        List <Block.MeshTool.BlockSurface> surface = Block.MeshTool.getChunkSurface(chunk, blockTypeFun, f);
                        Texture2D texSurface = Block.MeshTool.SurfacePointsToTexture(surface, f);

                        RenderTexture targetAoResult = rma.RenderByCalcShader(texSurface, new Vector3(i, j, k) * Block.Const.ChunkSize, f);

                        //回读亮度数据
                        RenderTexture.active = targetAoResult;
                        Texture2D readback = new Texture2D(targetAoResult.width, targetAoResult.height);
                        readback.ReadPixels(new Rect(0, 0, targetAoResult.width, targetAoResult.width), 0, 0);
                        Block.MeshTool.SetRaytraceAo(surface, readback);
                        Mesh mesh = Block.MeshTool.createMesh2(surface, f, blockTypeFun);

                        if (mesh != null)
                        {
                            GameObject obj = new GameObject("Chunk", typeof(MeshRenderer), typeof(MeshFilter));
                            obj.isStatic = true;
                            obj.GetComponent <Renderer>().material = mat;
                            obj.GetComponent <MeshFilter>().mesh   = mesh;
                            obj.transform.SetParent(root.transform);
                            obj.transform.position = new Vector3(i * Block.Const.ChunkSize * Block.Const.BlockSize, j * Block.Const.ChunkSize * Block.Const.BlockSize, k * Block.Const.ChunkSize * Block.Const.BlockSize);
                        }
                    }
                }
            }
        }
    }