Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Setting property of .hlsl include of ShaderGraph material

Discussion in 'High Definition Render Pipeline' started by unity_iT6SZm-KziEirA, Nov 24, 2023.

  1. unity_iT6SZm-KziEirA


    Oct 16, 2018

    I have been messing around with compute shaders lately, generating procedural terrain and foliage.

    To handle noise, I have developped a noise layer system that can be configured via the inspector, and translates it to gpu as well as an utility .cging file for all the math. My terrain then samples the configured noise and generates (marching cubes) its mesh.

    Then for foliage I sample all the triangles of my terrain mesh and estimate a survivability factor depending on a measure system (humidity, altitude, temperature, slope...) that uses the same noise layer system. That works fine.

    The problem happens when I want to use the same measure system (humidity, altitude, temperature, slope...) to change the texture of the terrain (example : dirt when dry, grass when moist).

    I use a shadergraph shader to blend the textures together depending on humidity and a CustomFunction node referencing a method in the .hlsl file that samples the measures (the same that works for foliage).

    Here is my MeasureSampler.hlsl :
    Code (CSharp):
    1. #include "Utils.cginc"
    3. RWStructuredBuffer<NoiseSettings> MS_I_NoiseSettings;
    4. RWStructuredBuffer<NoiseLayer> MS_I_MeasureNoiseLayers;
    5. int MS_I_MeasureNoiseLayersLength;
    6. float3 MS_I_WorldOffset;
    8. void EvaluateMeasures_float(float3 position, float3 triangleNormal, out float humidity, out float temperature, out float magic, out float slope, out float altitude)
    9. {
    10.     float measureValues[5];
    12.     //For each Measure
    13.     for (int i = 0; i < MS_I_MeasureNoiseLayersLength; i++)
    14.     {
    15.         //Prepare layers array
    16.         NoiseLayerArray noiseLayers;
    17.         NoiseLayer newLayers[4];
    18.         for (int j = 0; j < 4; j++)
    19.         {
    20.             newLayers[j] = MS_I_MeasureNoiseLayers[4 * i + j];
    21.         }
    22.         noiseLayers.layers = newLayers;
    24.         //Evaluate noise
    25.         measureValues[i] = EvaluateNoiseLayers(MS_I_NoiseSettings[i], 0, noiseLayers, position);
    26.     }
    28.     //Slope
    29.     measureValues[3] = DotProduct(float3(0, 1, 0), triangleNormal);
    31.     //Altitude
    32.     measureValues[4] = position.y;
    34.     humidity = Clamp01(measureValues[0]);
    35.     temperature = measureValues[1];
    36.     magic = measureValues[2];
    37.     slope = measureValues[3];
    38.     altitude = measureValues[4];

    Because my ShaderGraph uses a CustomFunction referencing MeasureSampler.hlsl, it includes it and the lines below :

    Code (CSharp):
    1. RWStructuredBuffer<NoiseSettings> MS_I_NoiseSettings;
    2. RWStructuredBuffer<NoiseLayer> MS_I_MeasureNoiseLayers;
    3. int MS_I_MeasureNoiseLayersLength;
    4. float3 MS_I_WorldOffset;
    Which are the settings I use to sample noise GPU-Side. I set them in my foliage generator (which includes the same MeasureSampler.hlsl) just before dispatching my foliage compute buffer that generate foliage transform, and it works.
    The problem is that I don't know how to pass these noise configurations to the material using my shader so that my terrain material has the data it needs to sample noises correctly.

    A little screenshot can't hurt :

    I realize my description is confused, I am not yet proficient with shader code. Apologies in advance, don't hesitate to ask for any more information.

    Attached Files: