Beispiel #1
0
        private void ProcessTriangle(
            ref GSubdivNode n, ref int leafIndex,
            ref Vector2 uv0, ref Vector2 uv1, ref Vector2 uv2, ref Vector2 uvc,
            ref Vector3 v0, ref Vector3 v1, ref Vector3 v2,
            ref int i0, ref int i1, ref int i2,
            ref Vector3 normal, ref Color32 color,
            ref Color hmData0, ref Color hmData1, ref Color hmData2,
            ref float heightSample, ref int removedLeafCount)
        {
            GGeometryJobUtilities.NormalizeToPoint(ref uv0, ref chunkUvRect, ref n.v0);
            GGeometryJobUtilities.NormalizeToPoint(ref uv1, ref chunkUvRect, ref n.v1);
            GGeometryJobUtilities.NormalizeToPoint(ref uv2, ref chunkUvRect, ref n.v2);

            if (displacementStrength > 0)
            {
                DisplaceUV(ref uv0);
                DisplaceUV(ref uv1);
                DisplaceUV(ref uv2);
            }

            GetHeightMapData(ref hmData0, ref uv0);
            GetHeightMapData(ref hmData1, ref uv1);
            GetHeightMapData(ref hmData2, ref uv2);

            GetHeightSample(ref heightSample, ref hmData0);
            v0.Set(
                uv0.x * terrainSize.x - chunkLocalPosition.x,
                heightSample * terrainSize.y,
                uv0.y * terrainSize.z - chunkLocalPosition.z);

            GetHeightSample(ref heightSample, ref hmData1);
            v1.Set(
                uv1.x * terrainSize.x - chunkLocalPosition.x,
                heightSample * terrainSize.y,
                uv1.y * terrainSize.z - chunkLocalPosition.z);

            GetHeightSample(ref heightSample, ref hmData2);
            v2.Set(
                uv2.x * terrainSize.x - chunkLocalPosition.x,
                heightSample * terrainSize.y,
                uv2.y * terrainSize.z - chunkLocalPosition.z);

            i0 = leafIndex * 3 + 0;
            i1 = leafIndex * 3 + 1;
            i2 = leafIndex * 3 + 2;

            vertices[i0] = v0;
            vertices[i1] = v1;
            vertices[i2] = v2;

            uvs[i0] = uv0;
            uvs[i1] = uv1;
            uvs[i2] = uv2;

            if (!smoothNormal)
            {
                normal      = Vector3.Cross(v1 - v0, v2 - v0).normalized;
                normals[i0] = normal;
                normals[i1] = normal;
                normals[i2] = normal;
            }
            else if (smoothNormal && !useSmoothNormalMask)
            {
                normals[i0] = GetSmoothNormal(ref uv0, ref v0).normalized;
                normals[i1] = GetSmoothNormal(ref uv1, ref v1).normalized;
                normals[i2] = GetSmoothNormal(ref uv2, ref v2).normalized;
            }
            else if (smoothNormal && useSmoothNormalMask)
            {
                normal = Vector3.Cross(v1 - v0, v2 - v0);
                Vector3 smoothNormal;
                float   mask;

                smoothNormal = GetSmoothNormal(ref uv0, ref v0);
                mask         = GetSmoothNormalMask(ref uv0);
                normals[i0]  = Vector3.Lerp(normal, smoothNormal, mask).normalized;

                smoothNormal = GetSmoothNormal(ref uv1, ref v1);
                mask         = GetSmoothNormalMask(ref uv1);
                normals[i1]  = Vector3.Lerp(normal, smoothNormal, mask).normalized;

                smoothNormal = GetSmoothNormal(ref uv2, ref v2);
                mask         = GetSmoothNormalMask(ref uv2);
                normals[i2]  = Vector3.Lerp(normal, smoothNormal, mask).normalized;
            }

            if (hmData0.a >= 0.5 || hmData1.a >= 0.5 || hmData2.a >= 0.5)
            {
                triangles[i0]     = i0;
                triangles[i1]     = i0;
                triangles[i2]     = i0;
                removedLeafCount += 1;
            }
            else
            {
                triangles[i0] = i0;
                triangles[i1] = i1;
                triangles[i2] = i2;
            }

            if (albedoToVertexColorMode == GAlbedoToVertexColorMode.Sharp)
            {
                uvc        = (uv0 + uv1 + uv2) / 3f;
                color      = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uvc);
                colors[i0] = color;
                colors[i1] = color;
                colors[i2] = color;
            }
            else if (albedoToVertexColorMode == GAlbedoToVertexColorMode.Smooth)
            {
                colors[i0] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv0);
                colors[i1] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv1);
                colors[i2] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv2);
            }
        }
Beispiel #2
0
        private void GetHeightMapData(ref Color data, ref Vector2 uv)
        {
            Color sample      = Vector4.zero;
            float sampleCount = 0f;

            sample      += GGeometryJobUtilities.GetColorBilinear(hmC, ref uv);
            sampleCount += 1;

            if (uv.x == 0 && uv.y == 0) //bottom left corner
            {
                if (hmB.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmBL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmBL, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 0 && uv.y == 1) //top left corner
            {
                if (hmT.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmTL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmTL, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 1 && uv.y == 1) //top right corner
            {
                if (hmT.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmTR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmTR, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 1 && uv.y == 0) //bottom right corner
            {
                if (hmB.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmBR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmBR, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 0) //left edge
            {
                if (hmL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
            }
            else if (uv.y == 1) //top edge
            {
                if (hmT.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 1) //right edge
            {
                if (hmR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
            }
            else if (uv.y == 0) //bottom edge
            {
                if (hmB.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
            }

            data = sample / sampleCount;
        }
        public void Execute()
        {
            int startIndex     = 0;
            int endIndex       = 0;
            int leftNodeIndex  = 0;
            int rightNodeIndex = 0;

            GSubdivNode currentNode;
            GSubdivNode leftNode  = new GSubdivNode();
            GSubdivNode rightNode = new GSubdivNode();

            Vector2 uv0 = Vector2.zero;
            Vector2 uv1 = Vector2.zero;
            Vector2 uv2 = Vector2.zero;
            Vector2 uvc = Vector2.zero;

            float r0          = 0;
            float r1          = 0;
            float r2          = 0;
            float rc          = 0;
            float rMax        = 0;
            int   subDivLevel = 0;

            baseResolution = Mathf.Max(0, baseResolution - lod);
            resolution     = Mathf.Max(0, resolution - lod);

            int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GGeometryJobUtilities.SUB_DIV_STEP), resolution - baseResolution);

            for (int res = baseResolution; res < maxLevel; ++res)
            {
                startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
                endIndex   = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
                for (int i = startIndex; i <= endIndex; ++i)
                {
                    if (creationState[i] != GGeometryJobUtilities.STATE_CREATED)
                    {
                        continue;
                    }
                    currentNode = baseTree[i];
                    GGeometryJobUtilities.NormalizeToPoint(ref uv0, ref uvRect, ref currentNode.v0);
                    GGeometryJobUtilities.NormalizeToPoint(ref uv1, ref uvRect, ref currentNode.v1);
                    GGeometryJobUtilities.NormalizeToPoint(ref uv2, ref uvRect, ref currentNode.v2);
                    uvc = (uv0 + uv1 + uv2) / 3;

                    r0 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv0).r;
                    r1 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv1).r;
                    r2 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv2).r;
                    rc = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uvc).r;

                    rMax = Mathf.Max(Mathf.Max(r0, r1), Mathf.Max(r2, rc));

                    subDivLevel = baseResolution + (int)(rMax / GGeometryJobUtilities.SUB_DIV_STEP);
                    if (subDivLevel <= res)
                    {
                        continue;
                    }

                    GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
                    currentNode.Split(ref leftNode, ref rightNode);

                    baseTree[leftNodeIndex]      = leftNode;
                    creationState[leftNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
                    GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref leftNode);

                    baseTree[rightNodeIndex]      = rightNode;
                    creationState[rightNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
                    GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref rightNode);
                }
            }
        }