eyou121 发表于 2024-7-15 18:02

《Unity Shader 入门精要》从Bulit-in 到URP (HLSL)Chapter15.3-基于噪声纹理的全局雾效

前言:

已经进入“高级篇”啦,但愿大师多多撑持,多多存眷,这将对我发生非常愉悦的正反馈~

“《Unity Shader 入门精要》从Bulit-in 到URP”是一个辅佐Unity Shader学习者以冯乐乐女神《Unity Shader 入门精要》为基础学习用HLSL语言编写URP着色器的案例教学系列。

作者自学能力有限,抛砖引玉,如有建议和问题请各位大佬和同仁交流斧正。
Bulit-in版:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader ”Unity Shaders Book/Chapter 15/Fog With Noise” {
        Properties {
                _MainTex (”Base (RGB)”, 2D) = ”white” {}
                _FogDensity (”Fog Density”, Float) = 1.0
                _FogColor (”Fog Color”, Color) = (1, 1, 1, 1)
                _FogStart (”Fog Start”, Float) = 0.0
                _FogEnd (”Fog End”, Float) = 1.0
                _NoiseTex (”Noise Texture”, 2D) = ”white” {}
                _FogXSpeed (”Fog Horizontal Speed”, Float) = 0.1
                _FogYSpeed (”Fog Vertical Speed”, Float) = 0.1
                _NoiseAmount (”Noise Amount”, Float) = 1
        }
        SubShader {
                CGINCLUDE
               
                #include ”UnityCG.cginc”
               
                float4x4 _FrustumCornersRay;
               
                sampler2D _MainTex;
                half4 _MainTex_TexelSize;
                sampler2D _CameraDepthTexture;
                half _FogDensity;
                fixed4 _FogColor;
                float _FogStart;
                float _FogEnd;
                sampler2D _NoiseTex;
                half _FogXSpeed;
                half _FogYSpeed;
                half _NoiseAmount;
               
                struct v2f {
                        float4 pos : SV_POSITION;
                        float2 uv : TEXCOORD0;
                        float2 uv_depth : TEXCOORD1;
                        float4 interpolatedRay : TEXCOORD2;
                };
               
                v2f vert(appdata_img v) {
                        v2f o;
                        o.pos = UnityObjectToClipPos(v.vertex);
                       
                        o.uv = v.texcoord;
                        o.uv_depth = v.texcoord;
                       
                        #if UNITY_UV_STARTS_AT_TOP
                        if (_MainTex_TexelSize.y < 0)
                                o.uv_depth.y = 1 - o.uv_depth.y;
                        #endif
                       
                        int index = 0;
                        if (v.texcoord.x < 0.5 && v.texcoord.y < 0.5) {
                                index = 0;
                        } else if (v.texcoord.x > 0.5 && v.texcoord.y < 0.5) {
                                index = 1;
                        } else if (v.texcoord.x > 0.5 && v.texcoord.y > 0.5) {
                                index = 2;
                        } else {
                                index = 3;
                        }
                        #if UNITY_UV_STARTS_AT_TOP
                        if (_MainTex_TexelSize.y < 0)
                                index = 3 - index;
                        #endif
                       
                        o.interpolatedRay = _FrustumCornersRay;
                                      
                        return o;
                }
               
                fixed4 frag(v2f i) : SV_Target {
                        float linearDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv_depth));
                        float3 worldPos = _WorldSpaceCameraPos + linearDepth * i.interpolatedRay.xyz;
                       
                        float2 speed = _Time.y * float2(_FogXSpeed, _FogYSpeed);
                        float noise = (tex2D(_NoiseTex, i.uv + speed).r - 0.5) * _NoiseAmount;
                                       
                        float fogDensity = (_FogEnd - worldPos.y) / (_FogEnd - _FogStart);
                        fogDensity = saturate(fogDensity * _FogDensity * (1 + noise));
                       
                        fixed4 finalColor = tex2D(_MainTex, i.uv);
                        finalColor.rgb = lerp(finalColor.rgb, _FogColor.rgb, fogDensity);
                       
                        return finalColor;
                }
               
                ENDCG
               
                Pass {                 
                        CGPROGRAM
                       
                        #pragma vertex vert
                        #pragma fragment frag
                          
                        ENDCG
                }
        }
        FallBack Off
}

URP版:

Unity项目源码:
Shader ”Unlit/Chapter15-FogWithNoise”
{
    Properties {
                _MainTex (”Base (RGB)”, 2D) = ”white” {}
                _FogDensity (”Fog Density”, Float) = 1.0
                _FogColor (”Fog Color”, Color) = (1, 1, 1, 1)
                _FogStart (”Fog Start”, Float) = 0.0
                _FogEnd (”Fog End”, Float) = 1.0
                _NoiseTex (”Noise Texture”, 2D) = ”white” {}
                _FogXSpeed (”Fog Horizontal Speed”, Float) = 0.1
                _FogYSpeed (”Fog Vertical Speed”, Float) = 0.1
                _NoiseAmount (”Noise Amount”, Float) = 1
        }
    SubShader {
      Tags {”RenderPipeline” = ”UniversalPipeline”}
                HLSLINCLUDE
               
                #include ”Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl”
                #include ”Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”

      CBUFFER_START(UnityPerMaterial)
            half4 _MainTex_TexelSize;
            half _FogDensity;
            half4 _FogColor;
            float _FogStart;
            float _FogEnd;
            half _FogXSpeed;
            half _FogYSpeed;
            half _NoiseAmount;
            float4x4 _FrustumCornersRay;
      CBUFFER_END
                       
                        TEXTURE2D(_MainTex);                           SAMPLER(sampler_MainTex);
            TEXTURE2D(_CameraDepthTexture);                SAMPLER(sampler_CameraDepthTexture);
            TEXTURE2D(_NoiseTex);                        SAMPLER(sampler_NoiseTex);
               
      struct appdata{
            float4 vertex : POSITION;
            float2 texcoord : TEXCOORD0;
      };

                struct v2f {
                        float4 pos : SV_POSITION;
                        float2 uv : TEXCOORD0;
                        float2 uv_depth : TEXCOORD1;
                        float4 interpolatedRay : TEXCOORD2;
                };
               
                v2f vert(appdata v) {
                        v2f o;
                        o.pos = TransformObjectToHClip(v.vertex);
                       
                        o.uv = v.texcoord;
                        o.uv_depth = v.texcoord;
                       
                        #if UNITY_UV_STARTS_AT_TOP
                        if (_MainTex_TexelSize.y < 0)
                                o.uv_depth.y = 1 - o.uv_depth.y;
                        #endif
                       
                        int index = 0;
                        if (v.texcoord.x < 0.5 && v.texcoord.y < 0.5) {
                                index = 0;
                        } else if (v.texcoord.x > 0.5 && v.texcoord.y < 0.5) {
                                index = 1;
                        } else if (v.texcoord.x > 0.5 && v.texcoord.y > 0.5) {
                                index = 2;
                        } else {
                                index = 3;
                        }
                        #if UNITY_UV_STARTS_AT_TOP
                        if (_MainTex_TexelSize.y < 0)
                                index = 3 - index;
                        #endif
                       
                        o.interpolatedRay = _FrustumCornersRay;
                                      
                        return o;
                }
               
                half4 frag(v2f i) : SV_Target {
                        float linearDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.uv_depth), _ZBufferParams);
                        float3 worldPos = _WorldSpaceCameraPos + linearDepth * i.interpolatedRay.xyz;
                       
                        float2 speed = _Time.y * float2(_FogXSpeed, _FogYSpeed);
                        float noise = (SAMPLE_TEXTURE2D(_NoiseTex, sampler_NoiseTex, i.uv + speed).r - 0.5) * _NoiseAmount;
                                       
                        float fogDensity = (_FogEnd - worldPos.y) / (_FogEnd - _FogStart);
                        fogDensity = saturate(fogDensity * _FogDensity * (1 + noise));
                       
                        half4 finalColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
                        finalColor.rgb = lerp(finalColor.rgb, _FogColor.rgb, fogDensity);
                       
                        return finalColor;
                }
               
                ENDHLSL
               
                Pass {                 
                        HLSLPROGRAM
                       
                        #pragma vertex vert
                        #pragma fragment frag
                          
                        ENDHLSL
                }
        }
        FallBack ”Packages/com.unity.render-pipelines.universal/FallbackError”
}
效果图:



如有收获,请留下“存眷”和“附和”
页: [1]
查看完整版本: 《Unity Shader 入门精要》从Bulit-in 到URP (HLSL)Chapter15.3-基于噪声纹理的全局雾效