Search Unity

Resolved Need help painting to splat map

Discussion in 'Shader Graph' started by nikefootbag, May 15, 2019.

  1. nikefootbag

    nikefootbag

    Joined:
    Jun 13, 2017
    Posts:
    28
    Hi, I'm trying to take texture coords from a mouse click and paint red to a splat map, which is then used in another shader to displace verts per the red color. I'm following along this tutorial but trying to do it in Shader Graph( rather than ShaderLab per the vid) -


    I've tested the displacement shader with a premade splatmap and it works as expected.

    Problem 1:
    When I use the DrawShader with Graphics.Blit, it seems to only fill one quarter of the texture and the coordinates are messed up. For example, in the screenshot below, i've clicked the very top right of the plane which receives texture coordinates "0,0", but its painting towards the center of the plane and is cut off.

    Problem 2:
    The other issue I have is that the splatmap seems to be entirely overwritten with each click, rather than being painted to.

    Can anyone see where I might be going wrong with the shadergraph or "DrawWithMouse" code below? For reference i'm using Unity 2019.1 and the project's using HDRP 5.13 & ShaderGraph 5.13.

    MouseClickAtTopRightReturnsCoords00.png

    Here's the DrawShader:
    DrawShaderGraph.PNG

    Original ShaderLab Code:

    ShaderlabCode.PNG

    Here's the code that applys the textureCoords to the "DrawToSplatMap" ShaderGraph

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DrawWithMouse : MonoBehaviour
    6. {
    7.     public Camera _camera;
    8.     public RenderTexture _splatmap;
    9.  
    10.     public Shader _drawShader;
    11.     public Material _drawMaterial;
    12.     private Material _snowMaterial;
    13.  
    14.     private RaycastHit _hit;
    15.  
    16.     [Range(1, 50)]
    17.     public float _brushSize;
    18.     [Range(0, 1)]
    19.     public float _brushStrength;
    20.  
    21.     void Start()
    22.     {
    23.         _drawMaterial = new Material(_drawShader);
    24.         _drawMaterial.SetVector("_Color", Color.red);
    25.  
    26.         _snowMaterial = GetComponent<MeshRenderer>().material;
    27.  
    28.         _splatmap = new RenderTexture(1024, 1024, 0, RenderTextureFormat.ARGBFloat);
    29.  
    30.         _snowMaterial.SetTexture("_SplatMap", _splatmap);
    31.     }
    32.  
    33.     void Update()
    34.     {
    35.         if (Input.GetKey(KeyCode.Mouse0))
    36.         {
    37.             if (Physics.Raycast(_camera.ScreenPointToRay(Input.mousePosition), out _hit))
    38.             {
    39.                 _drawMaterial.SetVector("_Coordinate", new Vector4(_hit.textureCoord.x, _hit.textureCoord.y, 0, 0));
    40.                 _drawMaterial.SetFloat("_BrushStrength", _brushStrength);
    41.                 _drawMaterial.SetFloat("_BrushSize", _brushSize);
    42.  
    43.                 RenderTexture temp = RenderTexture.GetTemporary(_splatmap.width, _splatmap.height, 0, RenderTextureFormat.ARGBFloat);
    44.  
    45.                 Graphics.Blit(_splatmap, temp);
    46.                 Graphics.Blit(temp, _splatmap, _drawMaterial);
    47.  
    48.                 RenderTexture.ReleaseTemporary(temp);
    49.             }
    50.         }
    51.     }
    52.  
    53.     private void OnGUI()
    54.     {
    55.         GUI.DrawTexture(new Rect(0, 0, 256, 256), _splatmap, ScaleMode.ScaleToFit, false, 1);
    56.     }
    57. }
    Intended result/Result from using premade texture:

    IntendedResult.png
     
  2. nikefootbag

    nikefootbag

    Joined:
    Jun 13, 2017
    Posts:
    28
  3. Saiaku

    Saiaku

    Joined:
    Feb 27, 2018
    Posts:
    3
    I know it's old, but do you know if this works in HDRP?
    I've tried using your approach for HDRP and while confirming that the shader receives the input and outputs correctly, the (custom and regular)rendertexture fails to update with information. I was hoping there was something I missed rather than this being a bug in HDRP.
     
    chortaingseng likes this.
  4. nikefootbag

    nikefootbag

    Joined:
    Jun 13, 2017
    Posts:
    28
    I wasn't able to get it working using HDRP back when I first attempted this. I'll likely have another try once HDRP leaves preview. My hope is that Graphics.Blit would work again as described in the original video tutorial above which I was following at the time. I find the custom render texture a bit of a black box.
     
  5. Saiaku

    Saiaku

    Joined:
    Feb 27, 2018
    Posts:
    3
    In my project, which is 2019.3.0f5 version with corresponding HDRP, oddly enough RenderTexture with Graphics.Blit works, but CustomRenderTexture does not. I was hoping I could update the tex through the material directly using that, but I was forced to use the 'old way'. Also, it only writes the last input to the texture, not keeping what has been added before. And my project is very similar to yours and peerplay's tutorial on this subject.
     
  6. Abended

    Abended

    Joined:
    Oct 9, 2018
    Posts:
    142
    Fellas,

    I am struggling with this now. as one of you said, it really feels like a black box. I am not using the player actions to alter the texture, rather I have a procedural shader that I can turn parts on and off to fit the shape I am looking to get out of it. I am having mixed results. At first I was only getting blobs of color on my custom render texture, but my second attempt was showing the patterns from my shader( I have some pinstripes going on) From what I am seeing here, maybe just trying to marry the shader to a render texture via script may be a more fruitful choice? I cannot figure out for the life of me why unity would offer a new object and not give any clear examples of how to use it. I appreciate your discussion and I am sure there are many who will find this thread in the future and stop chasing their own tails!
     
  7. Alex_ADEdge

    Alex_ADEdge

    Joined:
    Jul 28, 2013
    Posts:
    5
    Hey all, I came across this thread in my efforts to solve this issue with RenderTextures and getting the 'snow noise' effect working in with the scripts and shader. It seems like Unity has changed a bit and is no longer happy with the way the script in this tutorial is working.

    With the help of forum members I managed to get it solved in my own thread though, for reference if anyone else has this issue in the future: https://forum.unity.com/threads/snow-shader-c-rendertexture-casting-issues.1000758/

    Solution is pretty simple, below

    In summary it does still work in newer versions of unity, just do the following:

    1) Create a render texture in your project (right click in assets/project Create > RenderTexture)
    2) In your 'SnowTracks' material (or whatever youve called it) in the inspector apply the RenderTexture to the 'Splat Map' texture

    Now your C# script will find a RenderTexture when it calls the following line:

    RenderTexture _snow = (RenderTexture)_meshRenderer.material.GetTexture("_SplatTex");
     
    nikefootbag likes this.
  8. quniform

    quniform

    Joined:
    Nov 12, 2018
    Posts:
    4
    Hi All, Thanks for your posts about this. I'm also trying, and I'm close. I've actually created the script using Bolt, but having the same issues as others. The rendertexture only renders the current coordinates using the shader. The previous locations don't render – are they being overwritten? Placing the rendertexture asset into the mesh's material splatmap and the shader did not solve it. Also, I've tried the same setup with custom render texture with same but have same issue.
    It seems like the issue is that it can't blit from the splatmap rendertexture to the temporary render texture. But I haven't found a workaround.

    Thanks for your help.
    Using Unity 2019.4.18f1
    Bolt 1.4.13
     

    Attached Files:

    Last edited: Feb 7, 2021
  9. Luuke

    Luuke

    Joined:
    Jan 18, 2017
    Posts:
    13
    Hey guys, thanks for sharing your findings here !
    I've been trying to recreate this in HDRP, following the same tutorial. I adopted the node-setup @nikefootbag shared and adjusted it by the tips from @Alex_ADEdge but somehow nothing appears on my render texture. It just stays black, nothing happens at all. Does someone have a tip on what I am doing wrong?

    The Shader Graph looks the same to the one @nikefootbag shared. I also checked that I use the correct property references.

    My C# Code:
    (I deleted the snow stuff since I dont need it. I just wanted to test it with the GUI preview for now)
    Code (CSharp):
    1. public class DrawSplat : MonoBehaviour
    2. {
    3.  
    4.     public Camera _camera;
    5.     public Shader _drawShader;
    6.     public RenderTexture _splatmap;
    7.  
    8.     private Material _DrawMat;
    9.     private RaycastHit hit;
    10.  
    11.  
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.         _DrawMat = new Material(_drawShader);
    16.         _DrawMat.SetVector("_BrushColor", Color.red);
    17.  
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.         if (Input.GetKey(KeyCode.Mouse0))
    24.         {
    25.             if(Physics.Raycast(_camera.ScreenPointToRay(Input.mousePosition), out hit))
    26.             {
    27.                 _DrawMat.SetVector("_Coordinate", new Vector4(hit.textureCoord.x, hit.textureCoord.y, 0, 0));
    28.                 RenderTexture temp = RenderTexture.GetTemporary(_splatmap.width, _splatmap.height, 0, RenderTextureFormat.R8);
    29.                 Graphics.Blit(_splatmap, temp);
    30.                 Graphics.Blit(temp, _splatmap, _DrawMat);
    31.                 RenderTexture.ReleaseTemporary(temp);
    32.             }
    33.         }
    34.     }
    35.  
    36.     private void OnGUI()
    37.     {
    38.         GUI.DrawTexture(new Rect(0, 0, 512, 512), _splatmap, ScaleMode.ScaleToFit, false, 1);
    39.     }
    40. }
    41.  
     
    Last edited: Feb 17, 2021
  10. chortaingseng

    chortaingseng

    Joined:
    Mar 18, 2021
    Posts:
    3
    Hi, Does anyone have solution to this problem?
     
  11. Mirvini

    Mirvini

    Joined:
    Jul 25, 2013
    Posts:
    11
    I've noticed in the documentation for custom render texture (https://docs.unity3d.com/Manual/class-CustomRenderTexture.html) it says
    So does this mean in current versions of unity, shader graph output no longer works?
    Or is this comment misleading and you can still do what was done for the snow tires example.