Search Unity

Question Is there a way sample a pixel from a texture in a shadergraph material?

Discussion in 'Shader Graph' started by falldeaf_unity, Sep 19, 2021.

  1. falldeaf_unity

    falldeaf_unity

    Joined:
    Jul 27, 2016
    Posts:
    35
    I made a world-position-based ocean/wave shader in shadergraph and I'm trying to detect when a wave passes a point in 3D world space so that I can trigger a VFX graph that makes a small spray of water.

    Since the waves are based on a stretched gradient noise node, I was hoping to sample a point using a raycast and use the hit object to GetTexture and GetPixel every few seconds. I've been able to get texture pixel data from a texture2D property, but I can't figure out a way to write to that texture2D property from inside the shader.

    Is there any way that I could access the world position mapped, gradient noise node's data from C# script?
     
  2. falldeaf_unity

    falldeaf_unity

    Joined:
    Jul 27, 2016
    Posts:
    35
    Been searching and testing all day today and read that in most cases a better solution is to recreate the algorithm. So I created a compiled code copy of a simplified version of my wave shadergraph, then tried to recreate the stretched gradient noise node in C#. I used SetPixel to draw out the function to a pixel map to see what it looked like and the result was strange but seemed close-ish? trying_to_replicate_gradient_noise.png
    bad_gradient_node_replication.png

    Does this even seem like I'm on the right path, though? Or a reasonable solution? I'd need the algorithm to match up to the shader output 1 to 1 so that I could detect where waves currently are.
     
  3. falldeaf_unity

    falldeaf_unity

    Joined:
    Jul 27, 2016
    Posts:
    35
    I solved this by duplicating my shader, paring it down to just the gradient noise and rendering and saving it to an image. (The gradient noise node had static settings anyway)

    After using the static image instead of the gradient noise node, I was able to use a raycast pointing at my object, then using the hit.texturecoord object, referencing the static image I created for both and get the correct value.