//===================================================================================================
        //
        //      APPLY BRUSH
        //
        //===================================================================================================

        private void ApplyBrushInternal(PaintContext ctx, BrushTransform brushXform, Vector3 brushPosWS,
                                        float brushRotation, float brushStrength, float brushSize, Texture brushTexture)
        {
            brushPosWS.y = 0;

            /*
             *  blit steps
             *  1. blit noise to intermediate RT, this includes all the noise transformations and filters,
             *     using the appropriate noise material. do this with NoiseUtils.Blit2D?
             *  2. use that noise texture and mult it with brushmask to paint height on terrain
             */

            // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow
            float previewSize = 1 / 512f;

            // get proper noise material from current noise settings
            NoiseSettings noiseSettings = this.noiseSettings;
            Material      matNoise      = NoiseUtils.GetDefaultBlitMaterial(noiseSettings);

            // setup the noise material with values in noise settings
            noiseSettings.SetupMaterial(matNoise);

            // convert brushRotation to radians
            brushRotation *= Mathf.PI / 180;

            // change pos and scale so they match the noiseSettings preview
            bool isWorldSpace = (m_toolSettings.coordSpace == CoordinateSpace.World);

            brushSize  = isWorldSpace ? brushSize * previewSize : 1;
            brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero;

            // // override noise transform
            Quaternion rotQ         = Quaternion.AngleAxis(-brushRotation, Vector3.up);
            Matrix4x4  translation  = Matrix4x4.Translate(brushPosWS);
            Matrix4x4  rotation     = Matrix4x4.Rotate(rotQ);
            Matrix4x4  scale        = Matrix4x4.Scale(Vector3.one * brushSize);
            Matrix4x4  noiseToWorld = translation * scale;

            matNoise.SetMatrix(NoiseSettings.ShaderStrings.transform,
                               noiseSettings.trs * noiseToWorld);

            // render the noise field to a texture
            // TODO(wyatt): Handle the 3D case. Would need to blit to Volume Texture
            int rtW = ctx.destinationRenderTexture.width;
            int rtH = ctx.destinationRenderTexture.height;
            RenderTextureFormat     rtF     = RenderTextureFormat.RFloat;
            RenderTextureDescriptor rtDesc  = new RenderTextureDescriptor(rtW, rtH, rtF);
            RenderTexture           noiseRT = RenderTexture.GetTemporary(rtDesc);

            RenderTexture tempRT = RenderTexture.GetTemporary(noiseRT.descriptor);
            RenderTexture prev   = RenderTexture.active;

            RenderTexture.active = tempRT;

            int noisePass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName);

            Graphics.Blit(tempRT, matNoise, noisePass);

            RenderTexture.active = noiseRT;

            // if(noiseSettings.filterSettings.filterStack != null)
            // {
            //     noiseSettings.filterSettings.filterStack.Eval(tempRT, noiseRT);
            // }
            // else
            {
                Graphics.Blit(tempRT, noiseRT);
            }

            RenderTexture.active = prev;

            RenderTexture.ReleaseTemporary(tempRT);

            // then add the result to the heightmap using the noise height tool shader
            Material matFinal = paintMaterial;

            TerrainPaintUtility.SetupTerrainToolMaterialProperties(ctx, brushXform, matFinal);
            // set brush params
            Vector4 brushParams = new Vector4(0.01f * brushStrength, 0.0f, brushSize, 1 / brushSize);

            matFinal.SetVector("_BrushParams", brushParams);
            matFinal.SetTexture("_BrushTex", brushTexture);
            matFinal.SetTexture("_NoiseTex", noiseRT);
            matFinal.SetVector("_WorldHeightRemap", m_toolSettings.worldHeightRemap);
            Graphics.Blit(ctx.sourceRenderTexture, ctx.destinationRenderTexture, matFinal, 0);

            RenderTexture.ReleaseTemporary(noiseRT);
        }
        public override void Eval(FilterContext fc)
        {
            if (m_noiseSettings == null)
            {
                m_noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>();
            }

            m_noiseSettings.useTextureForPositions = m_useHeightmap;

            if (m_useHeightmap)
            {
                m_noiseSettings.positionTexture = fc.renderTextureCollection[FilterContext.Keywords.Heightmap];
            }

            Vector3 brushPosWS    = fc.brushPos;
            float   brushSize     = fc.brushSize;
            float   brushRotation = fc.brushRotation;

            // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow
            float previewSize = 1 / 512f;

            // get proper noise material from current noise settings
            NoiseSettings noiseSettings = m_noiseSettings;
            Material      mat           = NoiseUtils.GetDefaultBlitMaterial(noiseSettings);

            // setup the noise material with values in noise settings
            noiseSettings.SetupMaterial(mat);

            // convert brushRotation to radians
            brushRotation *= Mathf.PI / 180;

            // change pos and scale so they match the noiseSettings preview
            bool isWorldSpace = false == m_isLocalSpace;

            brushSize  = isWorldSpace ? brushSize * previewSize : 1;
            brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero;

            // // override noise transform
            Quaternion rotQ         = Quaternion.AngleAxis(-brushRotation, Vector3.up);
            Matrix4x4  translation  = Matrix4x4.Translate(brushPosWS);
            Matrix4x4  rotation     = Matrix4x4.Rotate(rotQ);
            Matrix4x4  scale        = Matrix4x4.Scale(Vector3.one * brushSize);
            Matrix4x4  noiseToWorld = translation * scale;

            mat.SetMatrix(NoiseSettings.ShaderStrings.transform, noiseSettings.trs * noiseToWorld);

            int pass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName);

            RenderTextureDescriptor desc = new RenderTextureDescriptor(fc.destinationRenderTexture.width, fc.destinationRenderTexture.height, RenderTextureFormat.RFloat);
            RenderTexture           rt   = RenderTexture.GetTemporary(desc);

            Graphics.Blit(fc.sourceRenderTexture, rt, mat, pass);

            Material blendMat = FilterUtility.blendModesMaterial;

            blendMat.SetTexture("_MainTex", fc.sourceRenderTexture);
            blendMat.SetTexture("_BlendTex", rt);

            Graphics.Blit(fc.sourceRenderTexture, fc.destinationRenderTexture, blendMat, 1);

            RenderTexture.ReleaseTemporary(rt);
        }
Exemple #3
0
        //===================================================================================================
        //
        //      APPLY BRUSH
        //
        //===================================================================================================

        private void ApplyBrushInternal(Terrain terrain, PaintContext ctx, BrushTransform brushXform, Vector3 brushPosWS,
                                        float brushRotation, float brushStrength, float brushSize, Texture brushTexture)
        {
            var prevRT = RenderTexture.active;

            brushPosWS.y = 0;

            /*
             *  blit steps
             *  1. blit noise to intermediate RT, this includes all the noise transformations and filters,
             *  using the appropriate noise material. do this with NoiseUtils.Blit2D?
             *  2. use that noise texture and mult it with brushmask to paint height on terrain
             */

            // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow
            float previewSize = 1 / 512f;

            // get proper noise material from current noise settings
            NoiseSettings noiseSettings = this.noiseSettings;
            Material      matNoise      = NoiseUtils.GetDefaultBlitMaterial(noiseSettings);

            // setup the noise material with values in noise settings
            noiseSettings.SetupMaterial(matNoise);

            // convert brushRotation to radians
            brushRotation *= Mathf.PI / 180;

            // change pos and scale so they match the noiseSettings preview
            bool isWorldSpace = (m_toolSettings.coordSpace == CoordinateSpace.World);

            brushSize  = isWorldSpace ? brushSize * previewSize : 1;
            brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero;

            // // override noise transform
            var rotQ         = Quaternion.AngleAxis(-brushRotation, Vector3.up);
            var translation  = Matrix4x4.Translate(brushPosWS);
            var rotation     = Matrix4x4.Rotate(rotQ);
            var scale        = Matrix4x4.Scale(Vector3.one * brushSize);
            var noiseToWorld = translation * scale;

            matNoise.SetMatrix(NoiseSettings.ShaderStrings.transform,
                               noiseSettings.trs * noiseToWorld);

            var noisePass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName);

            // render the noise field to a texture
            // TODO(wyatt): Handle the 3D case. Would need to blit to Volume Texture
            var rtDesc = ctx.destinationRenderTexture.descriptor;

            rtDesc.graphicsFormat = NoiseUtils.singleChannelFormat;
            rtDesc.sRGB           = false;
            var noiseRT = RTUtils.GetTempHandle(rtDesc);

            RenderTexture.active = noiseRT; // keep this
            Graphics.Blit(noiseRT, matNoise, noisePass);

            // then add the result to the heightmap using the noise height tool shader
            Material matFinal  = paintMaterial;
            var      brushMask = RTUtils.GetTempHandle(ctx.sourceRenderTexture.width, ctx.sourceRenderTexture.height, 0, FilterUtility.defaultFormat);

            Utility.SetFilterRT(commonUI, ctx.sourceRenderTexture, brushMask, matFinal);
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(ctx, brushXform, matFinal);
            // set brush params
            Vector4 brushParams = new Vector4(0.01f * brushStrength, 0.0f, brushSize, 1 / brushSize);

            matFinal.SetVector("_BrushParams", brushParams);
            matFinal.SetTexture("_BrushTex", brushTexture);
            matFinal.SetTexture("_NoiseTex", noiseRT);
            matFinal.SetVector("_WorldHeightRemap", m_toolSettings.worldHeightRemap);
            Graphics.Blit(ctx.sourceRenderTexture, ctx.destinationRenderTexture, matFinal, 0);

            RTUtils.Release(noiseRT);
            RTUtils.Release(brushMask);

            RenderTexture.active = prevRT;
        }