예제 #1
0
        public async Task <List <GRingSurfaceDetail> > ProvideSurfaceDetail()
        {
            var stainResourceWithCoords = await _stainTerrainServiceProxy.RetriveResource(_inGamePosition);

            var uniformsPack = new UniformsPack();

            uniformsPack.SetTexture("_PaletteTex", stainResourceWithCoords.Resource.TerrainPaletteTexture);
            uniformsPack.SetTexture("_PaletteIndexTex", stainResourceWithCoords.Resource.PaletteIndexTexture);
            uniformsPack.SetTexture("_ControlTex", stainResourceWithCoords.Resource.ControlTexture);
            uniformsPack.SetUniform("_TerrainStainUv", stainResourceWithCoords.Coords.ToVector4());

            uniformsPack.SetUniform("_TerrainTextureSize", stainResourceWithCoords.Resource.TerrainTextureSize);
            uniformsPack.SetUniform("_PaletteMaxIndex", stainResourceWithCoords.Resource.PaletteMaxIndex);

            return(new List <GRingSurfaceDetail>()
            {
                new GRingSurfaceDetail()
                {
                    UniformsWithKeywords = new UniformsWithKeywords()
                    {
                        Keywords = new ShaderKeywordSet(),
                        Uniforms = uniformsPack
                    },
                    ShaderName = "Custom/Terrain/Ring1"
                }
            });
        }
예제 #2
0
        public async Task <TextureWithCoords> ApplyFeatureAsync(TextureWithCoords texture,
                                                                TerrainCardinalResolution resolution, bool canMultistep)
        {
            var configuration = _configurations[resolution];

            var detailedHeightmapArray = await TaskUtils
                                         .RunInThreadPool(
                () =>
            {
                var creator      = new DiamondSquareCreator(_randomProviderGenerator.GetRandom());
                var initialArray = creator.CreateDiamondSquareNoiseArray(
                    texture.TextureSize,
                    configuration.DiamondSquareWorkingArrayLength);
                return(initialArray);
            });

            var detailedTexture = await _commonExecutor
                                  .AddAction(() => HeightmapUtils.CreateTextureFromHeightmap(detailedHeightmapArray));


            UniformsPack pack = new UniformsPack();

            pack.SetTexture("_Texture1", texture.Texture);
            pack.SetTexture("_Texture2", detailedTexture);
            pack.SetUniform("_Texture2Weight", configuration.DiamondSquareWeight);

            var renderCoords = new MyRectangle(0, 0, 1, 1);

            var outTextureSize = texture.TextureSize;

            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true);
            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep        = canMultistep,
                Coords              = renderCoords,
                OutTextureInfo      = outTextureInfo,
                RenderTextureFormat = RenderTextureFormat.RFloat,
                ShaderName          = "Custom/TerrainCreation/DiamondSquareTextureAddingPlain",
                UniformPack         = pack,
                CreateTexture2D     = false
            };

            var renderedTexture = await _rendererProxy.AddOrder(template);

            await _commonExecutor.AddAction(() => GameObject.Destroy(detailedTexture));

            return(new TextureWithCoords(sizedTexture: new TextureWithSize()
            {
                Texture = renderedTexture,
                Size = texture.TextureSize
            }, coords: texture.Coords));
        }
예제 #3
0
        private async Task <Texture> GenerateTextureWithMipMapsAsync(TextureWithSize tex)
        {
            IntVector2   outTextureSize = tex.Size;
            UniformsPack pack           = new UniformsPack();

            pack.SetTexture("_SourceTexture", tex.Texture);
            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true);
            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep         = false,
                Coords               = new MyRectangle(0, 0, 1, 1),
                OutTextureInfo       = outTextureInfo,
                RenderTextureFormat  = RenderTextureFormat.RFloat,
                ShaderName           = "Custom/TerGen/Cutting",
                UniformPack          = pack,
                CreateTexture2D      = false,
                RenderTextureMipMaps = true
            };
            var outTex = await _rendererProxy.AddOrder(template);

            await _commonExecutor.AddAction(() => outTex.wrapMode = TextureWrapMode.Clamp);

            return(outTex);
        }
예제 #4
0
        public async Task <TextureWithSize> ExtractMipmapAsync(TextureWithSize inputTexture, RenderTextureFormat format, int mipmapLevelToExtract)
        {
            var pack = new UniformsPack();

            pack.SetTexture("_InputTexture", inputTexture.Texture);
            pack.SetUniform("_MipmapLevelToExtract", mipmapLevelToExtract);

            var outSize = ComputeMipmappedOutSize(inputTexture.Size, mipmapLevelToExtract);

            var newTexture = await _textureRenderer.AddOrder(new TextureRenderingTemplate()
            {
                CanMultistep         = true,
                Coords               = new MyRectangle(0, 0, 1, 1),
                CreateTexture2D      = false,
                OutTextureInfo       = new ConventionalTextureInfo(outSize.X, outSize.Y, TextureFormat.ARGB32, true),
                RenderTextureFormat  = format,
                RenderTextureMipMaps = true,
                ShaderName           = "Custom/Tool/ExtractMipmap",
                UniformPack          = pack,
            });

            return(new TextureWithSize()
            {
                Texture = newTexture,
                Size = outSize
            });
        }
        private async Task <UniformsPack> CreateUniformsPack(Ring1Node ring1Node)
        {
            UniformsPack pack = new UniformsPack();


            var terrainOutput = await _terrainShapeDb.Query(new TerrainDescriptionQuery()
            {
                QueryArea = Ring1Node.Ring1Position,
                RequestedElementDetails = new List <TerrainDescriptionQueryElementDetail>()
                {
                    new TerrainDescriptionQueryElementDetail()
                    {
                        //PixelsPerMeter = 10, //todo
                        Resolution = TerrainCardinalResolution.FromRing1NodeLodLevel(Ring1Node.QuadLodLevel),
                        Type       = TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY
                    },
                    new TerrainDescriptionQueryElementDetail()
                    {
                        //PixelsPerMeter = 10, //todo
                        Resolution = TerrainCardinalResolution.FromRing1NodeLodLevel(Ring1Node.QuadLodLevel),
                        Type       = TerrainDescriptionElementTypeEnum.TESSALATION_REQ_ARRAY
                    },
                }
            });

            var uvPosition =
                _coordsCalculator.CalculateUvPosition(Ring1Node.Ring1Position); //_submapTextures.UvPosition;
            var heightmapTexture   = terrainOutput.GetElementOfType(TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY);
            var tessalationTexture =
                terrainOutput.GetElementOfType(TerrainDescriptionElementTypeEnum.TESSALATION_REQ_ARRAY);

            pack.SetUniform("_TerrainTextureUvPositions",
                            new Vector4(uvPosition.X, uvPosition.Y, uvPosition.Width, uvPosition.Height));
            pack.SetTexture("_HeightmapTex", heightmapTexture.TokenizedElement.DetailElement.Texture.Texture);
            pack.SetTexture("_TessalationTex", tessalationTexture.TokenizedElement.DetailElement.Texture.Texture);

            pack.SetTexture("_LodTexture", _visibilityTexture);
            pack.SetUniform("_MaxHeight", 100);
            pack.SetUniform("_LodTextureUvOffset",
                            _coordsCalculator.CalculateTextureUvLodOffset(ring1Node.Ring1Position));
            pack.SetUniform("_BaseTrianglesCount",
                            _coordsCalculator.CalculateGameObjectSize(ring1Node.Ring1Position).X - 1);
            return(pack);
        }
예제 #6
0
        public GRingWeldingDetail ProvideWeldingDetails(TerrainDetailElementOutput heightmapDetail, int heightmapOffset)
        {
            if (!_weldingPack.WeldingEnabled)
            {
                return(new GRingWeldingDetail()
                {
                    Modifier = new Ring1GroundPieceModifier(),
                    UniformsPack = new UniformsPack()
                });
            }


            if (_weldingPack == null)
            {
                Debug.LogError("WARNING. Welding pack not set!!. Only for testing!!");
                return(new GRingWeldingDetail()
                {
                    Modifier = new Ring1GroundPieceModifier(),
                    UniformsPack = new UniformsPack()
                });
            }
            var groundPieceModifier = new Ring1GroundPieceModifier();

            _weldingTerrainIndex = _weldingPack.RegisterTerrain(new WeldingRegistrationTerrain()
            {
                Texture             = heightmapDetail.TokenizedElement.DetailElement.Texture,
                DetailGlobalArea    = heightmapDetail.TokenizedElement.DetailElement.DetailArea,
                Resolution          = heightmapDetail.TokenizedElement.DetailElement.Resolution,
                TerrainLod          = heightmapOffset,
                UvCoordsPositions2D = heightmapDetail.UvBase
            }, (t) => groundPieceModifier.ModifyMaterial((material) =>
            {
                t.SetToMaterial(material);
            }));

            var pack = new UniformsPack();

            pack.SetTexture("_WeldTexture", _weldingPack.WeldTexture.Texture);

            var emptyUvs = new TerrainWeldUvs();

            pack.SetUniform("_LeftWeldTextureUvRange", emptyUvs.LeftUv);
            pack.SetUniform("_RightWeldTextureUvRange", emptyUvs.RightUv);
            pack.SetUniform("_TopWeldTextureUvRange", emptyUvs.TopUv);
            pack.SetUniform("_BottomWeldTextureUvRange", emptyUvs.BottomUv);

            return(new GRingWeldingDetail()
            {
                UniformsPack = pack,
                Modifier = groundPieceModifier,
                WeldingIndex = _weldingTerrainIndex
            });
        }
        public async Task <List <GRingSurfaceDetail> > ProvideSurfaceDetail()
        {
            var devisedPatches =
                await _patchesCreator.CreatePatchAsync(_inGamePosition.ToRectangle(), _flatLod.ScalarValue);

            Preconditions.Assert(devisedPatches.Count <= 1,
                                 $"More than one patches created: {devisedPatches.Count}, rect is {_inGamePosition}");
            if (!devisedPatches.Any())
            {
                return(new List <GRingSurfaceDetail>());
            }

            var onlyPatch    = devisedPatches.First();
            var stampedSlice = await _patchStamper.FinalizeGPatchCreation(onlyPatch, _flatLod.ScalarValue);

            if (stampedSlice != null)
            {
                UniformsPack pack = new UniformsPack();
                pack.SetTexture("_MainTex", stampedSlice.ColorStamp);
                pack.SetTexture("_NormalTex", stampedSlice.NormalStamp);

                var uniforms = new UniformsWithKeywords()
                {
                    Uniforms = pack,
                    Keywords = new ShaderKeywordSet()
                };

                return(new List <GRingSurfaceDetail>()
                {
                    new GRingSurfaceDetail()
                    {
                        ShaderName = "Custom/Terrain/Ring2Stamped",
                        UniformsWithKeywords = uniforms
                    }
                });
            }

            return(new List <GRingSurfaceDetail>());
        }
예제 #8
0
        private async Task <UniformsPack> CreateUniformsPack(
            List <TerrainDescriptionQueryElementDetail> queryElementDetails,
            UniformsPack uniformsPack,
            StainTerrainResourceWithCoords stainResourceWithCoords)
        {
            var terrainDetailAreaPosition = _coordsCalculator.CalculateGlobalObjectPosition(Ring1Node.Ring1Position);

            var terrainOutput = await _terrainShapeDb.Query(new TerrainDescriptionQuery()
            {
                QueryArea = terrainDetailAreaPosition,
                RequestedElementDetails = queryElementDetails
            });

            var heightmapTexture = terrainOutput.GetElementOfType(TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY);

            uniformsPack.SetTexture("_HeightmapTex",
                                    heightmapTexture.TokenizedElement.DetailElement.Texture.Texture);
            uniformsPack.SetUniform("_HeightmapUv", heightmapTexture.UvBase.ToVector4());

            if (terrainOutput.HasElementOfType(TerrainDescriptionElementTypeEnum.NORMAL_ARRAY))
            {
                var normalAsTexture = terrainOutput.GetElementOfType(TerrainDescriptionElementTypeEnum.NORMAL_ARRAY);
                uniformsPack.SetTexture("_NormalmapTex",
                                        normalAsTexture.TokenizedElement.DetailElement.Texture.Texture);
                uniformsPack.SetUniform("_NormalmapUv", normalAsTexture.UvBase.ToVector4());
            }

            uniformsPack.SetTexture("_PaletteTex", stainResourceWithCoords.Resource.TerrainPaletteTexture);
            uniformsPack.SetTexture("_PaletteIndexTex", stainResourceWithCoords.Resource.PaletteIndexTexture);
            uniformsPack.SetTexture("_ControlTex", stainResourceWithCoords.Resource.ControlTexture);
            uniformsPack.SetUniform("_TerrainStainUv", stainResourceWithCoords.Coords.ToVector4());

            uniformsPack.SetUniform("_TerrainTextureSize", stainResourceWithCoords.Resource.TerrainTextureSize);
            uniformsPack.SetUniform("_PaletteMaxIndex", stainResourceWithCoords.Resource.PaletteMaxIndex);
            return(uniformsPack);
        }
예제 #9
0
        public DebugFlatTerrainShapeDb(UTTextureRendererProxy textureRenderer)
        {
            var size = new IntVector2(241, 241);
            var tex  = new Texture2D(size.X, size.Y, TextureFormat.ARGB32, true, true);

            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    tex.SetPixel(x, y, new Color(0, 0, 0, 0));
                }
            }
            tex.Apply();

            _blankTexture = new TextureWithSize()
            {
                Texture = tex,
                Size    = size
            };

            var pack = new UniformsPack();

            pack.SetTexture("_HeightmapTex", tex);
            pack.SetUniform("_HeightMultiplier", 80);
            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(size.X, size.Y, TextureFormat.ARGB32, true);

            var renderCoords = new MyRectangle(0, 0, 1, 1);
            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep        = false,
                Coords              = renderCoords,
                OutTextureInfo      = outTextureInfo,
                RenderTextureFormat = RenderTextureFormat.ARGB32,
                ShaderName          = "Custom/Terrain/NormalmapGenerator",
                UniformPack         = pack,
                CreateTexture2D     = false
            };
            var outNormalTex = textureRenderer.AddOrder(template).Result;

            _normalTexture = new TextureWithSize()
            {
                Size    = size,
                Texture = outNormalTex
            };
        }
예제 #10
0
        public async Task <TextureWithCoords> ApplyFeatureAsync(TextureWithCoords inputTexture,
                                                                TerrainCardinalResolution resolution, bool CanMultistep = false)
        {
            if (!TaskUtils.GetGlobalMultithreading())
            {
                Preconditions.Assert(inputTexture.Texture.width == inputTexture.Texture.height,
                                     "Only square inputTextures are supported");
            }
            UniformsPack pack = new UniformsPack();
            await _commonExecutor.AddAction(() => inputTexture.Texture.filterMode = FilterMode.Point);

            pack.SetTexture("_SourceTexture", inputTexture.Texture);
            pack.SetUniform("_InputGlobalCoords", inputTexture.Coords.ToVector4());
            pack.SetUniform("_QuantingResolution", inputTexture.TextureSize.X - 1);


            var configuration = _configurations[resolution];

            pack.SetUniform("_DetailResolutionMultiplier", configuration.DetailResolutionMultiplier);
            pack.SetUniform("_NoiseStrengthMultiplier", configuration.NoiseStrengthMultiplier);

            var renderCoords = new MyRectangle(0, 0, 1, 1);

            var outTextureSize = inputTexture.TextureSize;

            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true);
            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep        = false,
                Coords              = renderCoords,
                OutTextureInfo      = outTextureInfo,
                RenderTextureFormat = RenderTextureFormat.RFloat,
                ShaderName          = "Custom/TerrainCreation/NoiseAddingPlain",
                UniformPack         = pack,
                CreateTexture2D     = false
            };

            return(new TextureWithCoords(sizedTexture: new TextureWithSize()
            {
                Texture = await _rendererProxy.AddOrder(template),
                Size = inputTexture.TextureSize
            }, coords: inputTexture.Coords));
        }
예제 #11
0
        public Task PlaceSegmentAsync(Texture segmentTexture, PlacementDetails placementDetails)
        {
            var          segmentPlacement0 = CalculateSegmentPlacement(placementDetails.ModuledPositionInGrid);
            UniformsPack uniforms          = new UniformsPack();

            uniforms.SetTexture("_SegmentSurfaceTexture", segmentTexture);
            uniforms.SetUniform("_SegmentCoords", segmentPlacement0.Uvs.ToVector4());
            uniforms.SetUniform("_TextureArraySliceIndex", _ceilArraySliceIndex);

            return(_renderer.AddOrder(new TextureRenderingTemplate()
            {
                CanMultistep = false,
                CreateTexture2D = false,
                RenderTextureToModify = _floorTextureArray,
                ShaderName = "Custom/ESurface/SegmentPlacer",
                UniformPack = uniforms,
                RenderingRectangle = segmentPlacement0.Pixels,
                RenderTargetSize = _floorTextureSize,
                RenderTextureArraySlice = _ceilArraySliceIndex
            }));
        }
예제 #12
0
        public Texture2D WrapTexture(Texture2D inputTexture)
        {
            UniformsPack uniforms = new UniformsPack();

            uniforms.SetUniform("_Margin", _configuration.Margin);
            uniforms.SetTexture("_InputTex", inputTexture);

            var outSize = (new Vector2(inputTexture.width, inputTexture.height) / (1 + 2 * _configuration.Margin)).ToIntVector2();

            outSize = new IntVector2(Mathf.ClosestPowerOfTwo(outSize.X), Mathf.ClosestPowerOfTwo(outSize.Y));

            return((Texture2D)_textureRenderer.AddOrder(new TextureRenderingTemplate()
            {
                CanMultistep = false,
                Coords = new MyRectangle(0, 0, 1, 1),
                CreateTexture2D = true,
                OutTextureInfo = new ConventionalTextureInfo(outSize.X, outSize.Y, inputTexture.format, false),
                UniformPack = uniforms,
                ShaderName = "Custom/NPR/ArtMapWrapping"
            }).Result); //todo async
        }
예제 #13
0
        private GrassGroupsPlanter CreateBushGroupsPlanter(OtherThreadExecutingLocation otherThreadExecutingLocation)
        {
            var meshGenerator = new GrassMeshGenerator();
            var mesh          = meshGenerator.GetGrassBillboardMesh(0, 1);

            var instancingMaterial = new Material(Shader.Find("Custom/Vegetation/GrassBushBillboard.Instanced"));

            instancingMaterial.enableInstancing = true;

            /// CLAN

            var billboardsFileManger = new Grass2BillboardClanFilesManager();
            var clan        = billboardsFileManger.Load(_veConfiguration.Grass2BillboardsPath, new IntVector2(256, 256));
            var singleToDuo = new Grass2BakingBillboardClanGenerator(
                _initializationFields.Retrive <ComputeShaderContainerGameObject>(),
                _initializationFields.Retrive <UnityThreadComputeShaderExecutorObject>());
            var bakedClan = singleToDuo.GenerateBakedAsync(clan).Result;
            ///

            var commonUniforms = new UniformsPack();

            commonUniforms.SetUniform("_BendingStrength", 0.6f);
            commonUniforms.SetUniform("_WindDirection", Vector4.one);

            commonUniforms.SetTexture("_DetailTex", bakedClan.DetailTextureArray);
            commonUniforms.SetTexture("_BladeSeedTex", bakedClan.BladeSeedTextureArray);

            var instancingContainer = new GpuInstancingVegetationSubjectContainer(
                new GpuInstancerCommonData(mesh, instancingMaterial, commonUniforms),
                new GpuInstancingUniformsArrayTemplate(new List <GpuInstancingUniformTemplate>()
            {
                new GpuInstancingUniformTemplate("_Color", GpuInstancingUniformType.Vector4),
                new GpuInstancingUniformTemplate("_InitialBendingValue", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_PlantBendingStiffness", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_PlantDirection", GpuInstancingUniformType.Vector4),
                new GpuInstancingUniformTemplate("_RandSeed", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_ArrayTextureIndex", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_Pointer", GpuInstancingUniformType.Float),
            })
                );

            var globalGpuInstancingContainer = _initializationFields.Retrive <GlobalGpuInstancingContainer>();
            var bucketId = globalGpuInstancingContainer.CreateBucket(instancingContainer);
            GrassGroupsContainer grassGroupsContainer =
                new GrassGroupsContainer(globalGpuInstancingContainer, bucketId);

            IGrassPositionResolver grassPositionResolver =
                new PoissonDiskSamplerPositionResolver(_veConfiguration.BushExclusionRadiusRange);

            GrassDetailInstancer grassDetailInstancer = new GrassDetailInstancer();

            DesignBodySpotUpdaterProxy designBodySpotUpdaterProxy = _initializationFields.Retrive <DesignBodySpotUpdaterProxy>();

            var mediatorSpotUpdater = new ListenerCenteredMediatorDesignBodyChangesUpdater(designBodySpotUpdaterProxy);
            var grassGroupsPlanter  = new GrassGroupsPlanter(
                grassDetailInstancer, grassPositionResolver, grassGroupsContainer, mediatorSpotUpdater,
                new Grass2BushAspectsGenerator(bakedClan), //todo!
                _veConfiguration.BushTemplatesConfiguration, _veConfiguration.VegetationRepositioner);

            mediatorSpotUpdater.SetTargetChangesListener(new LambdaSpotPositionChangesListener(null, dict =>
            {
                otherThreadExecutingLocation.Execute(() =>
                {
                    foreach (var pair in dict)
                    {
                        grassGroupsPlanter.GrassGroupSpotChanged(pair.Key, pair.Value);
                    }
                    return(TaskUtils.EmptyCompleted());
                });
            }));

            var rootMediator = _initializationFields.Retrive <RootMediatorSpotPositionsUpdater>();

            rootMediator.AddListener(mediatorSpotUpdater);

            return(grassGroupsPlanter);
        }
예제 #14
0
        public async Task PlaceSegmentAsync(Texture segmentTexture, PlacementDetails placementDetails)
        {
            var          segmentPlacement0 = CalculateSegmentPlacement(placementDetails.ModuledPositionInGrid);
            UniformsPack uniforms0         = new UniformsPack();

            uniforms0.SetTexture("_SegmentHeightTexture", segmentTexture);
            uniforms0.SetUniform("_SegmentCoords", segmentPlacement0.Uvs.ToVector4());

            await _renderer.AddOrder(new TextureRenderingTemplate()
            {
                CanMultistep            = false,
                CreateTexture2D         = false,
                RenderTextureToModify   = _heightMap,
                ShaderName              = "Custom/ETerrain/SegmentPlacer",
                UniformPack             = uniforms0,
                RenderingRectangle      = segmentPlacement0.Pixels,
                RenderTargetSize        = _floorTextureSize,
                RenderTextureArraySlice = _heightMapSliceIndex
            });

            if (_modifyCorners)
            {
                var modifiedCornerBuffer = await _commonExecutor.AddAction(() =>
                {
                    var tex = new RenderTexture(_modifiedCornerBufferSize.X, _modifiedCornerBufferSize.Y, 0, _heightMap.format);
                    tex.Create();
                    return(tex);
                });

                foreach (var cornerModification in placementDetails.CornersToModify)
                {
                    var cornerMask        = _cornerMaskInformations[cornerModification.Corner];
                    var segmentPlacement1 = CalculateSegmentPlacement(cornerModification.ModuledPositionOfSegment);

                    var uniforms1 = new UniformsPack();
                    uniforms1.SetTexture("_HeightMap", _heightMap);
                    uniforms1.SetUniform("_WeldingAreaCoords",
                                         RectangleUtils.CalculateSubPosition(segmentPlacement1.Uvs, cornerMask.SegmentSubPositionUv)
                                         .ToVector4());
                    uniforms1.SetUniform("_MarginSize", _interSegmentMarginSize);
                    uniforms1.SetUniform("_CornerToWeld", cornerMask.CornerToWeldVector);
                    uniforms1.SetUniform("_PixelSizeInUv", 1f / _floorTextureSize.X);
                    uniforms1.SetUniform("_HeightMapSliceIndex", _heightMapSliceIndex);

                    await _renderer.AddOrder(new TextureRenderingTemplate()
                    {
                        CanMultistep          = false,
                        CreateTexture2D       = false,
                        RenderTextureToModify = modifiedCornerBuffer,
                        ShaderName            = "Custom/ETerrain/GenerateNewCorner",
                        UniformPack           = uniforms1,
                        RenderingRectangle    = new IntRectangle(0, 0, segmentPlacement1.Pixels.Width, segmentPlacement1.Pixels.Height),
                        RenderTargetSize      = new IntVector2(segmentPlacement1.Pixels.Width, segmentPlacement1.Pixels.Height)
                    });

                    var uniforms2 = new UniformsPack();
                    uniforms2.SetTexture("_ModifiedCornerBuffer", modifiedCornerBuffer);

                    await _renderer.AddOrder(new TextureRenderingTemplate()
                    {
                        CanMultistep          = false,
                        CreateTexture2D       = false,
                        RenderTextureToModify = _heightMap,
                        ShaderName            = "Custom/ETerrain/CornerPlacer",
                        UniformPack           = uniforms2,
                        RenderingRectangle    = RectangleUtils.CalculateSubPosition(segmentPlacement1.Pixels.ToFloatRectangle(),
                                                                                    cornerMask.SegmentSubPositionUv).ToIntRectange(),
                        RenderTargetSize        = _floorTextureSize,
                        RenderTextureArraySlice = _heightMapSliceIndex
                    });
                }

                await _commonExecutor.AddAction(() => GameObject.Destroy(modifiedCornerBuffer));
            }
        }
        public void Start(ComputeShaderContainerGameObject computeShaderContainer)
        {
            var commonExecutor       = new CommonExecutorUTProxy();
            var shaderExecutorObject = new UnityThreadComputeShaderExecutorObject();

            var updater =
                new DesignBodySpotUpdater(new DesignBodySpotChangeCalculator(computeShaderContainer,
                                                                             shaderExecutorObject, commonExecutor, HeightDenormalizer.Identity));

            _designBodySpotUpdaterProxy = new DesignBodySpotUpdaterProxy(updater);
            updater.SetChangesListener(new LambdaSpotPositionChangesListener(null, dict =>
            {
                foreach (var pair in dict)
                {
                    _grassGroupsPlanter.GrassGroupSpotChanged(pair.Key, pair.Value);
                }
            }));
            _designBodySpotUpdaterProxy.StartThreading(() => { });


            var meshGenerator = new GrassMeshGenerator();
            var mesh          = meshGenerator.GetGrassBillboardMesh(0, 1);

            var instancingMaterial = new Material(Shader.Find("Custom/Vegetation/GrassBushBillboard.Instanced"));

            instancingMaterial.enableInstancing = true;

            /// CLAN

            var billboardsFileManger = new Grass2BillboardClanFilesManager();
            var clan        = billboardsFileManger.Load(@"C:\inz\billboards\", new IntVector2(256, 256));
            var singleToDuo = new Grass2BakingBillboardClanGenerator(computeShaderContainer, shaderExecutorObject);
            var bakedClan   = singleToDuo.GenerateBakedAsync(clan).Result;
            ///


            var commonUniforms = new UniformsPack();

            commonUniforms.SetUniform("_BendingStrength", 0.0f);
            commonUniforms.SetUniform("_WindDirection", Vector4.one);

            commonUniforms.SetTexture("_DetailTex", bakedClan.DetailTextureArray);
            commonUniforms.SetTexture("_BladeSeedTex", bakedClan.BladeSeedTextureArray);

            var instancingContainer = new GpuInstancingVegetationSubjectContainer(
                new GpuInstancerCommonData(mesh, instancingMaterial, commonUniforms),
                new GpuInstancingUniformsArrayTemplate(new List <GpuInstancingUniformTemplate>()
            {
                new GpuInstancingUniformTemplate("_Color", GpuInstancingUniformType.Vector4),
                new GpuInstancingUniformTemplate("_InitialBendingValue", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_PlantBendingStiffness", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_PlantDirection", GpuInstancingUniformType.Vector4),
                new GpuInstancingUniformTemplate("_RandSeed", GpuInstancingUniformType.Float),
                new GpuInstancingUniformTemplate("_ArrayTextureIndex", GpuInstancingUniformType.Float),
            })
                );

            _globalGpuInstancingContainer = new GlobalGpuInstancingContainer();
            var bucketId = _globalGpuInstancingContainer.CreateBucket(instancingContainer);
            GrassGroupsContainer grassGroupsContainer =
                new GrassGroupsContainer(_globalGpuInstancingContainer, bucketId);

            IGrassPositionResolver grassPositionResolver =
                new PoissonDiskSamplerPositionResolver(new MyRange(1.5f * 0.4f * 10, 10 * 2 * 1.3f));
            //IGrassPositionResolver grassPositionResolver = new SimpleRandomSamplerPositionResolver();

            GrassDetailInstancer grassDetailInstancer = new GrassDetailInstancer();


            _grassGroupsPlanter = new GrassGroupsPlanter(
                grassDetailInstancer, grassPositionResolver, grassGroupsContainer, _designBodySpotUpdaterProxy,
                new Grass2BushAspectsGenerator(bakedClan), //todo!
                GrassDebugUtils.BushTemplates, Repositioner.Identity);
        }
예제 #16
0
        private async Task MergeDetailObject(Dictionary <TerrainDetailCorner, TerrainDetailElement> sourceTextures,
                                             TextureWithSize sourceTexture, TextureWithSize outTexture, TerrainDetailCorner activeCorner, TextureWithSize scratchTexture)
        {
            var uniforms          = new UniformsPack();
            var cornersPresent    = new Vector4();
            var cornersMerged     = new Vector4();
            int activeCornerIndex = 0;

            var i = 0;

            foreach (var corner in TerrainDetailCorner.OrderedDirections)
            {
                if (corner == activeCorner)
                {
                    activeCornerIndex = i;
                }
                if (sourceTextures.ContainsKey(corner))
                {
                    cornersPresent[i] = 10;
                    if (sourceTextures[corner].CornersMergeStatus == CornersMergeStatus.MERGED)
                    {
                        cornersMerged[i] = 10;
                    }
                    uniforms.SetTexture("_Corner" + GetCornerTexUniformName(corner) + "Tex", sourceTextures[corner].Texture.Texture);
                }
                i++;
            }

            uniforms.SetUniform("_ActiveCornerIndex", activeCornerIndex);
            uniforms.SetUniform("_CornersMerged", cornersMerged);
            uniforms.SetTexture("_ScratchTex", scratchTexture.Texture);
            uniforms.SetUniform("_MergeMargin", _configuration.MergeMarginSize); // todo

            await _renderer.AddOrder(new TextureRenderingTemplate()
            {
                CanMultistep          = false,
                CreateTexture2D       = false,
                RenderTextureToModify = scratchTexture.Texture as RenderTexture, // todo
                ShaderName            = "Custom/TerrainDetailMerger/MergeIntoScratch",
                UniformPack           = uniforms,
                RenderingRectangle    = new IntRectangle(0, 0, scratchTexture.Size.X, scratchTexture.Size.Y),
                RenderTargetSize      = new IntVector2(scratchTexture.Size.X, scratchTexture.Size.Y),
            });


            IntRectangle renderingRectangle;

            if (activeCorner == TerrainDetailCorner.BottomLeft)
            {
                renderingRectangle = new IntRectangle(0, 0, 121, 121);
            }
            else if (activeCorner == TerrainDetailCorner.BottomRight)
            {
                renderingRectangle = new IntRectangle(120, 0, 121, 121);
            }
            else if (activeCorner == TerrainDetailCorner.TopLeft)
            {
                renderingRectangle = new IntRectangle(0, 120, 121, 121);
            }
            else if (activeCorner == TerrainDetailCorner.TopRight)
            {
                renderingRectangle = new IntRectangle(120, 120, 121, 121);
            }
            else
            {
                Preconditions.Fail("Unsupported activeCorner " + activeCorner);
                renderingRectangle = new IntRectangle(0, 0, 1, 1);
            }

            await _renderer.AddOrder(new TextureRenderingTemplate()
            {
                CanMultistep          = false,
                CreateTexture2D       = false,
                RenderTextureToModify = (RenderTexture)outTexture.Texture,
                ShaderName            = "Custom/TerrainDetailMerger/ScratchToActive",
                UniformPack           = uniforms,
                RenderingRectangle    = renderingRectangle,
                RenderTargetSize      = new IntVector2(241, 241),
            });
        }
예제 #17
0
        public async Task <TextureWithSize> GenerateNormalDetailElementAsync(MyRectangle requestedArea,
                                                                             TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus)
        {
            var baseHeightTextureOutput =
                await _baseTerrainDetailProvider.RetriveTerrainDetailAsync(
                    TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY, requestedArea, resolution, cornersMergeStatus);

            var baseHeightTexture = baseHeightTextureOutput.TokenizedElement.DetailElement;

            IntVector2   outTextureSize = TerrainShapeUtils.RetriveTextureSize(requestedArea, resolution);
            UniformsPack pack           = new UniformsPack();

            float heightMultiplier = 0;

            if (resolution == TerrainCardinalResolution.MIN_RESOLUTION)
            {
                heightMultiplier = 1.25f;
            }
            else if (resolution == TerrainCardinalResolution.MID_RESOLUTION)
            {
                heightMultiplier = 10f;
            }
            else
            {
                heightMultiplier = 80f;
            }

            pack.SetTexture("_HeightmapTex", baseHeightTexture.Texture.Texture);
            //pack.SetUniform("_HeightMultiplier", heightMultiplier);
            pack.SetUniform("_HeightMultiplier", 1);
            pack.SetUniform("_GlobalCoords", requestedArea.ToVector4());
            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true);

            var renderCoords =
                TerrainShapeUtils.ComputeUvOfSubElement(requestedArea, baseHeightTexture.DetailArea);

            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep        = false,
                Coords              = renderCoords,
                OutTextureInfo      = outTextureInfo,
                RenderTextureFormat = RenderTextureFormat.ARGB32,
                ShaderName          = "Custom/Terrain/NormalmapGenerator",
                UniformPack         = pack,
                CreateTexture2D     = false
            };
            var outTex = await _rendererProxy.AddOrder(template);

            await _commonExecutor.AddAction(() => outTex.filterMode = FilterMode.Trilinear);

            await _baseTerrainDetailProvider.RemoveTerrainDetailAsync(baseHeightTextureOutput.TokenizedElement.Token);

            //SavingFileManager.SaveTextureToPngFile(@"C:\temp\norm1.png", outTex as Texture2D);

            return(new TextureWithSize()
            {
                Size = new IntVector2(outTextureSize.X, outTextureSize.Y),
                Texture = outTex
            });
        }
예제 #18
0
        private async Task <TextureWithSize> RetriveFoundationTextureAsync(MyRectangle requestedArea,
                                                                           TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus)
        {
            Texture     fundationTexture = null;
            MyRectangle renderCoords     = null;

            TerrainDetailElementToken retrivedElementToken = null;

            if (resolution == TerrainCardinalResolution.MIN_RESOLUTION)
            {
                fundationTexture = _fullFundationTextureData.Texture;
                renderCoords     =
                    TerrainShapeUtils.ComputeUvOfSubElement(requestedArea, _fullFundationTextureData.Coords);
            }
            else
            {
                var lowerResolution    = resolution.LowerResolution;
                var fundationQueryArea = TerrainShapeUtils.GetAlignedTerrainArea(requestedArea, lowerResolution,
                                                                                 _configuration.TerrainDetailImageSideDisjointResolution);

                var foundationOutput = await _baseTerrainDetailProvider.RetriveTerrainDetailAsync(
                    TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY, fundationQueryArea, lowerResolution, cornersMergeStatus);

                retrivedElementToken = foundationOutput.TokenizedElement.Token;
                var fundationDetailElement = foundationOutput.TokenizedElement.DetailElement;

                renderCoords =
                    TerrainShapeUtils.ComputeUvOfSubElement(requestedArea, fundationDetailElement.DetailArea);
                fundationTexture = fundationDetailElement.Texture.Texture;
                await _commonExecutor.AddAction(() => fundationTexture.filterMode = FilterMode.Bilinear);
            }

            IntVector2   outTextureSize = TerrainShapeUtils.RetriveTextureSize(requestedArea, resolution);
            UniformsPack pack           = new UniformsPack();

            pack.SetTexture("_SourceTexture", fundationTexture);
            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true);
            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep        = false,
                Coords              = renderCoords,
                OutTextureInfo      = outTextureInfo,
                RenderTextureFormat = RenderTextureFormat.RFloat,
                ShaderName          = "Custom/TerGen/Cutting",
                UniformPack         = pack,
                CreateTexture2D     = false
            };
            var outTex = await _rendererProxy.AddOrder(template);

            await _commonExecutor.AddAction(() => outTex.wrapMode = TextureWrapMode.Clamp);

            if (retrivedElementToken != null)
            {
                await _baseTerrainDetailProvider.RemoveTerrainDetailAsync(retrivedElementToken);
            }

            return(new TextureWithSize()
            {
                Size = outTextureSize,
                Texture = outTex
            });
        }
예제 #19
0
        public async Task <GRingGroundShapeDetail> ProvideGroundTextureDetail()
        {
            int flatLodLevel = _flatLod.ScalarValue;

            if (!_configuration.SettingPerFlatLod.ContainsKey(flatLodLevel))
            {
                Preconditions.Fail("Unsupported lod level: " + flatLodLevel);
            }
            var setting = _configuration.SettingPerFlatLod[flatLodLevel];

            TerrainCardinalResolution detailResolution = setting.DetailResolution;
            bool directNormalCalculation = setting.DirectNormalComputation;

            var queryElementDetails = new List <TerrainDescriptionQueryElementDetail>()
            {
                new TerrainDescriptionQueryElementDetail()
                {
                    Resolution = detailResolution,
                    Type       = TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY
                },
            };
            //if (!directNormalCalculation) //we have to do it every time , as we need normals for spot updating!
            {
                queryElementDetails.Add(
                    new TerrainDescriptionQueryElementDetail()
                {
                    Resolution = detailResolution,
                    Type       = TerrainDescriptionElementTypeEnum.NORMAL_ARRAY
                }
                    );
            }

            var uniformsPack = new UniformsPack();

            uniformsPack.SetUniform("_LodLevel", flatLodLevel);

            var terrainOutput = await _terrainShapeDb.Query(new TerrainDescriptionQuery()
            {
                QueryArea = _terrainDetailAreaPosition,
                RequestedElementDetails = queryElementDetails
            });

            var heightmapTexture = terrainOutput.GetElementOfType(TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY);

            uniformsPack.SetTexture("_HeightmapTex",
                                    heightmapTexture.TokenizedElement.DetailElement.Texture.Texture);
            uniformsPack.SetUniform("_HeightmapUv", heightmapTexture.UvBase.ToVector4());

            var normalAsTexture = terrainOutput.GetElementOfType(TerrainDescriptionElementTypeEnum.NORMAL_ARRAY);

            if (!directNormalCalculation)
            {
                uniformsPack.SetTexture("_NormalmapTex",
                                        normalAsTexture.TokenizedElement.DetailElement.Texture.Texture);
                uniformsPack.SetUniform("_NormalmapUv", normalAsTexture.UvBase.ToVector4());
            }

            List <string> keywords = new List <string>();

            if (directNormalCalculation)
            {
                keywords.Add("DYNAMIC_NORMAL_GENERATION");
            }

            IGroundShapeToken token = null;

            if (_spotUpdater != null) //todo remove when tests over!
            {
                token = _spotUpdater.AddArea(new GroundShapeInfo()
                {
                    TextureGlobalPosition = _terrainDetailAreaPosition,
                    TextureCoords         = new MyRectangle(heightmapTexture.UvBase),
                    HeightmapResolution   = detailResolution,
                },
                                             new UpdatedTerrainTextures()
                {
                    HeightTexture         = heightmapTexture.TokenizedElement.DetailElement.Texture.Texture,
                    NormalTexture         = normalAsTexture.TokenizedElement.DetailElement.Texture.Texture,
                    TextureGlobalPosition = heightmapTexture.TokenizedElement.DetailElement.DetailArea,
                    TextureCoords         = new MyRectangle(heightmapTexture.UvBase),
                });
            }
            else
            {
                Debug.Log("T333 WARNING. SPOT UPDATER NOT SET. SHOUDL BE USED ONLY IN TESTING");
                token = new DummyGroundShapeToken();
            }

            return(new GRingGroundShapeDetail()
            {
                ShaderKeywordSet = new ShaderKeywordSet(keywords),
                Uniforms = uniformsPack,
                GroundShapeToken = token,
                HeightDetailOutput = heightmapTexture
            });
        }
예제 #20
0
        public DebugSlopedTerrainShapeDb(UTTextureRendererProxy textureRenderer)
        {
            var size             = new IntVector2(241, 241);
            var tex              = new Texture2D(size.X, size.Y, TextureFormat.ARGB32, true, true);
            var encodedHeightTex = new Texture2D(size.X, size.Y, TextureFormat.ARGB32, true, true);

            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    tex.SetPixel(x, y, new Color(0, 0, 0, 0));

                    //var distanceToCenter = 1 - (Vector2.Distance(new Vector2(120, 120), new Vector2(x, y)) /
                    //                            Mathf.Sqrt(120 * 120)) / 2;
                    //encodedHeightTex.SetPixel(x, y, HeightColorTransform.EncodeHeight(distanceToCenter / 100));

                    //var distanceToCenter = Mathf.Clamp01(
                    //    Mathf.Min(
                    //        Mathf.Abs(y - 100) / 50.0f,
                    //        Mathf.Abs(x - 100) / 50.0f)
                    //        ) / 300;

                    //encodedHeightTex.SetPixel(x, y, HeightColorTransform.EncodeHeight(distanceToCenter));


                    var heightInUnits = HeightDenormalizer.Default.Normalize(5);
                    var encodedHeight = HeightColorTransform.EncodeHeight(heightInUnits);
                    encodedHeightTex.SetPixel(x, y, encodedHeight);
                }
            }
            tex.Apply();
            encodedHeightTex.Apply();

            _blankTexture = new TextureWithSize()
            {
                Texture = tex,
                Size    = size
            };

            var transformator        = new TerrainTextureFormatTransformator(new CommonExecutorUTProxy());
            var encodedHeightTexture = new TextureWithSize()
            {
                Texture = encodedHeightTex,
                Size    = new IntVector2(241, 241)
            };
            var plainTex = transformator.EncodedHeightTextureToPlain(encodedHeightTexture);

            _heightTexture = new TextureWithSize()
            {
                Size    = new IntVector2(241, 241),
                Texture = plainTex
            };

            var pack = new UniformsPack();

            pack.SetTexture("_HeightmapTex", plainTex);
            pack.SetUniform("_HeightMultiplier", 80);
            ConventionalTextureInfo outTextureInfo =
                new ConventionalTextureInfo(size.X, size.Y, TextureFormat.ARGB32, true);

            var renderCoords = new MyRectangle(0, 0, 1, 1);
            TextureRenderingTemplate template = new TextureRenderingTemplate()
            {
                CanMultistep        = false,
                Coords              = renderCoords,
                OutTextureInfo      = outTextureInfo,
                RenderTextureFormat = RenderTextureFormat.ARGB32,
                ShaderName          = "Custom/Terrain/NormalmapGenerator",
                UniformPack         = pack,
                CreateTexture2D     = false
            };
            var outNormalTex = textureRenderer.AddOrder(template).Result;

            _normalTexture = new TextureWithSize()
            {
                Size    = size,
                Texture = outNormalTex
            };
        }