Search Unity

Question BUILT-IN SHADER TO URP

Discussion in 'Shaders' started by hugolammens, Mar 22, 2023.

  1. hugolammens

    hugolammens

    Joined:
    Sep 20, 2022
    Posts:
    17
    Hi guys, i have some problem with my shader in unity urp, i create an atmosphere like that (cf first picture) then i converted my project into urp and now, i have this things , i show you my shader script :

    Shader "Hidden/Atmosphere"
    {
    Properties
    {
    _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
    // No culling or depth
    Cull Off ZWrite Off ZTest Always
    Pass
    {
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"
    #include "../Includes/Math.cginc"
    //
    struct appdata {
    float4 vertex : POSITION;
    float4 uv : TEXCOORD0;
    };
    struct v2f {
    float4 pos : SV_POSITION;
    float2 uv : TEXCOORD0;
    float3 viewVector : TEXCOORD1;
    };
    v2f vert (appdata v) {
    v2f output;
    output.pos = UnityObjectToClipPos(v.vertex);
    output.uv = v.uv;
    // Camera space matches OpenGL convention where cam forward is -z. In unity forward is positive z.
    // (https://docs.unity3d.com/ScriptReference/Camera-cameraToWorldMatrix.html)
    float3 viewVector = mul(unity_CameraInvProjection, float4(v.uv.xy * 2 - 1, 0, -1));
    output.viewVector = mul(unity_CameraToWorld, float4(viewVector,0));
    return output;
    }
    float2 squareUV(float2 uv) {
    float width = _ScreenParams.x;
    float height =_ScreenParams.y;
    //float minDim = min(width, height);
    float scale = 1000;
    float x = uv.x * width;
    float y = uv.y * height;
    return float2 (x/scale, y/scale);
    }
    sampler2D _BlueNoise;
    sampler2D _MainTex;
    sampler2D _BakedOpticalDepth;
    //sampler2D _CameraDepthTexture;
    UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
    float4 params;
    float3 dirToSun;
    float3 planetCentre;
    float atmosphereRadius;
    float oceanRadius;
    float planetRadius;
    // Paramaters
    int numInScatteringPoints;
    int numOpticalDepthPoints;
    float intensity;
    float4 scatteringCoefficients;
    float ditherStrength;
    float ditherScale;
    float densityFalloff;

    float densityAtPoint(float3 densitySamplePoint) {
    float heightAboveSurface = length(densitySamplePoint - planetCentre) - planetRadius;
    float height01 = heightAboveSurface / (atmosphereRadius - planetRadius);
    float localDensity = exp(-height01 * densityFalloff) * (1 - height01);
    return localDensity;
    }

    float opticalDepth(float3 rayOrigin, float3 rayDir, float rayLength) {
    float3 densitySamplePoint = rayOrigin;
    float stepSize = rayLength / (numOpticalDepthPoints - 1);
    float opticalDepth = 0;
    for (int i = 0; i < numOpticalDepthPoints; i ++) {
    float localDensity = densityAtPoint(densitySamplePoint);
    opticalDepth += localDensity * stepSize;
    densitySamplePoint += rayDir * stepSize;
    }
    return opticalDepth;
    }
    float opticalDepthBaked(float3 rayOrigin, float3 rayDir) {
    float height = length(rayOrigin - planetCentre) - planetRadius;
    float height01 = saturate(height / (atmosphereRadius - planetRadius));
    float uvX = 1 - (dot(normalize(rayOrigin - planetCentre), rayDir) * .5 + .5);
    return tex2Dlod(_BakedOpticalDepth, float4(uvX, height01,0,0));
    }
    float opticalDepthBaked2(float3 rayOrigin, float3 rayDir, float rayLength) {
    float3 endPoint = rayOrigin + rayDir * rayLength;
    float d = dot(rayDir, normalize(rayOrigin-planetCentre));
    float opticalDepth = 0;
    const float blendStrength = 1.5;
    float w = saturate(d * blendStrength + .5);

    float d1 = opticalDepthBaked(rayOrigin, rayDir) - opticalDepthBaked(endPoint, rayDir);
    float d2 = opticalDepthBaked(endPoint, -rayDir) - opticalDepthBaked(rayOrigin, -rayDir);
    opticalDepth = lerp(d2, d1, w);
    return opticalDepth;
    }

    float3 calculateLight(float3 rayOrigin, float3 rayDir, float rayLength, float3 originalCol, float2 uv) {
    float blueNoise = tex2Dlod(_BlueNoise, float4(squareUV(uv) * ditherScale,0,0));
    blueNoise = (blueNoise - 0.5) * ditherStrength;

    float3 inScatterPoint = rayOrigin;
    float stepSize = rayLength / (numInScatteringPoints - 1);
    float3 inScatteredLight = 0;
    float viewRayOpticalDepth = 0;
    for (int i = 0; i < numInScatteringPoints; i ++) {
    float sunRayLength = raySphere(planetCentre, atmosphereRadius, inScatterPoint, dirToSun).y;
    float sunRayOpticalDepth = opticalDepthBaked(inScatterPoint + dirToSun * ditherStrength, dirToSun);
    float localDensity = densityAtPoint(inScatterPoint);
    viewRayOpticalDepth = opticalDepthBaked2(rayOrigin, rayDir, stepSize * i);
    float3 transmittance = exp(-(sunRayOpticalDepth + viewRayOpticalDepth) * scatteringCoefficients);

    inScatteredLight += localDensity * transmittance;
    inScatterPoint += rayDir * stepSize;
    }
    inScatteredLight *= scatteringCoefficients * intensity * stepSize / planetRadius;
    inScatteredLight += blueNoise * 0.01;
    // Attenuate brightness of original col (i.e light reflected from planet surfaces)
    // This is a hacky mess, TODO: figure out a proper way to do this
    const float brightnessAdaptionStrength = 0.15;
    const float reflectedLightOutScatterStrength = 3;
    float brightnessAdaption = dot (inScatteredLight,1) * brightnessAdaptionStrength;
    float brightnessSum = viewRayOpticalDepth * intensity * reflectedLightOutScatterStrength + brightnessAdaption;
    float reflectedLightStrength = exp(-brightnessSum);
    float hdrStrength = saturate(dot(originalCol,1)/3-1);
    reflectedLightStrength = lerp(reflectedLightStrength, 1, hdrStrength);
    float3 reflectedLight = originalCol * reflectedLightStrength;
    float3 finalCol = reflectedLight + inScatteredLight;

    return finalCol;
    }
    float4 frag (v2f i) : SV_Target
    {
    float4 originalCol = tex2D(_MainTex, i.uv);
    float sceneDepthNonLinear = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
    float sceneDepth = LinearEyeDepth(sceneDepthNonLinear) * length(i.viewVector);

    float3 rayOrigin = _WorldSpaceCameraPos;
    float3 rayDir = normalize(i.viewVector);

    float dstToOcean = raySphere(planetCentre, oceanRadius, rayOrigin, rayDir);
    float dstToSurface = min(sceneDepth, dstToOcean);

    float2 hitInfo = raySphere(planetCentre, atmosphereRadius, rayOrigin, rayDir);
    float dstToAtmosphere = hitInfo.x;
    float dstThroughAtmosphere = min(hitInfo.y, dstToSurface - dstToAtmosphere);

    if (dstThroughAtmosphere > 0) {
    const float epsilon = 0.0001;
    float3 pointInAtmosphere = rayOrigin + rayDir * (dstToAtmosphere + epsilon);
    float3 light = calculateLight(pointInAtmosphere, rayDir, dstThroughAtmosphere - epsilon * 2, originalCol, i.uv);
    return float4(light, 1);
    }
    return originalCol;
    }
    ENDCG
    }
    }
    }


    I'm a beginner in unity so i hope you will be able to help me in order to make my atmosphere shader works in urp. Thanks .
     

    Attached Files:

  2. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,059
  3. hugolammens

    hugolammens

    Joined:
    Sep 20, 2022
    Posts:
    17
    Thanks for the answer but im not looking for create a new one , i just want to convert this one ;(
     
  4. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,059
    If you dont know how to make 1, you probably cannot convert one.
    I also cannot give you a car and a new frame and say "lets now put the engine from 1 in the other"
     
  5. hugolammens

    hugolammens

    Joined:
    Sep 20, 2022
    Posts:
    17
    I know how to make one in built in but i have no idea of what i have to change for urp and i can"t find any tutorial which shows this.
     
  6. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    You can google the built-in functions that URP throws errors, for example, search "UnityObjectToClipPos() URP" and you can find that it has changed to "TransformObjectToHClip()" in URP.
     
  7. hugolammens

    hugolammens

    Joined:
    Sep 20, 2022
    Posts:
    17
    Thats what i did but now i have this mistake :

    SampleBias': no matching 3 parameter intrinsic method; Possible intrinsic methods are: Texture2D<float4>.
    SampleBias(SamplerState, float2|half2|min10float2|min16float2, float1|half1|min10float1|min16float1)
    Texture2D<float4>.SampleBias(SamplerState, float2|half2|min10float2|min16float2, float1|half1|min10float1|min16float1, int2)
    Texture2D<float4>.SampleBias(SamplerState, float2|half2|min10float2|min16float2, float1|half1|min10float1|min16float1, int2, float1|half1|min10float1|min16float1)
    Texture2D<float4>.SampleBias(SamplerState, float2|half2|min10float2|min16float2, float1|half1|min10float1|min16float1, int2, float1|half1|min10float1|min16float1, out uint status) at line 245 (on d3d11)

    at this line :

    float sceneDepthNonLinear = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,sampler_CameraDepthTexture,i.uv);
     
  8. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    UNITY_DECLARE_DEPTH_TEXTURE() and SAMPLE_DEPTH_TEXTURE() do not exist in URP.

    you can either include URP's "DeclareDepthTexture.hlsl" (link is for 2023.2a) or manually declare the depth texture and sample it.

    TEXTURE2D_X_FLOAT(_CameraDepthTexture);
    SAMPLER(sampler_CameraDepthTexture);
    Note (ignore if it's a skybox shader): Looks like your shader is an opaque shader. The depth texture may not be ready if the copy depth is not set to "Force Prepass". (check the Frame Debugger)

    Please also check the shader includes in URP's shader library folder (link is for 2023.2a).
     
    Last edited: Mar 23, 2023
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The work to "convert" a shader from the BIRP to URP, especially one using some of the features this shader is using like the depth texture, essentially requires rewriting the shader from scratch. There are also a lot of helper functions now included with the URP that can replace parts of that shader if you look through the URP shader code.
     
  10. hugolammens

    hugolammens

    Joined:
    Sep 20, 2022
    Posts:
    17
    This shader is very complex so i don't know if i have to recreate everything but you think i should ?
     
  11. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Not everything, no. But it might not be as simple as find and replace. The custom functions should all work as is with no modification. But anything to do with sampling built in textures or calculating the view ray may not work without more significant changes.
     
  12. hugolammens

    hugolammens

    Joined:
    Sep 20, 2022
    Posts:
    17
    Ok, i see what you mean, but i'm a beginner, is that possible for you to help me if you have time ? Because i have no error on unity so i don't know what i have to change.
     
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The link @DevDunk posted in his first reply should give you all the information you need to convert this shader. Feel free to post further questions if you get stuck, but go through that information first.