• URP下快速实现高度雾


    高度雾的实现思路非常简单,通过深度图还原出来的世界坐标的y值来做fog的lerp参数。

    代码使用之前的体积光代码的基础上做了个加法,方便快速使用。

    代码如下:

    Shader "Unlit/VolumetricLightingShader"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _Intensity("Intensity",float) = 1
            _FogColor("Fog Color",Color) = (1,1,1,1)
            _FogHeight("Fog Height",float) = 1
                _HeightPower("Fog Height Power",float) = 1
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" }
            LOD 100
    
            Pass
            {
                HLSLPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #define MAIN_LIGHT_CALCULATE_SHADOWS
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
                #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
                #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
                #define STEP_TIME 64
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float3 worldPos:TEXCOORD1;
                    float4 screenPos :TEXCOORD2;
                };
    
                TEXTURE2D_X_FLOAT(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
                TEXTURE2D(_CameraOpaqueTexture); SAMPLER(sampler_CameraOpaqueTexture);
                TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
                float _Intensity;
                half4 _FogColor;
                float _FogHeight;
                float _HeightPower;
                v2f vert (appdata v)
                {
                    v2f o;
                    
                    o.vertex = TransformObjectToHClip(v.vertex);
                    o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                    o.screenPos = ComputeScreenPos(o.vertex);
                    return o;
                }
    
                half4 frag (v2f i) : SV_Target
                {
                    half2 screenPos = i.screenPos.xy / i.screenPos.w;
                    //rebuild world position according to depth
                    float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture,sampler_CameraDepthTexture, screenPos).r;
                    depth = Linear01Depth(depth, _ZBufferParams);
                    float2 positionNDC = screenPos * 2 - 1;
                    float3 farPosNDC = float3(positionNDC.xy,1)*_ProjectionParams.z;
                    float4 viewPos = mul(unity_CameraInvProjection,farPosNDC.xyzz);
                    viewPos.xyz *= depth;
                    float4 worldPos = mul(UNITY_MATRIX_I_V,viewPos);
                    
                    float noise = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, screenPos*3).r;
                    float3 startPos = i.worldPos;
                    float3 dir = normalize(worldPos - startPos);
                    startPos += dir * noise;
                    worldPos.xyz += dir * noise;
                    float len = length(worldPos - startPos);
                    float3 stepLen = dir * len / STEP_TIME;
                    half3 color = 0;
    
                    half3 sceneColor = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, screenPos).rgb;
                    
                    UNITY_LOOP
                    for (int i = 0; i < STEP_TIME; i++)
                    {
                        startPos += stepLen;
                        float4 shadowPos = TransformWorldToShadowCoord(startPos);
                        float intensity = MainLightRealtimeShadow(shadowPos)*_Intensity;
                        color += intensity*_MainLightColor.rgb;
                    }
                    
                    color /= STEP_TIME;
                    color += sceneColor;
    
                    float heightOffset = pow(max((_FogHeight - worldPos.y)/_FogHeight,0), _HeightPower);
                    color += heightOffset * _FogColor;
                    return half4(color.xyz,1);
                }
                ENDHLSL
            }
        }
    }

    使用方法还是像之前一样在摄像机前面放一个片,快速的查看效果。

    效果如下:

     我们能看到天空已经曝的不成样子,通过tonemapping(aces)来解决。最后是这样子:

     非常的有意境~哈哈哈哈,程序员觉得好看的美术可能看起来是一坨粑粑。

  • 相关阅读:
    resin实现热部署配置
    tomcat实现域名访问步骤
    springboot学习笔记2---配置拦截器:
    springboot学习笔记2:搭建web项目
    springboot学习笔记1:springboot入门
    重识maven
    shiro学习笔记:remeberMe,多次登录锁死账号
    shiro学习笔记:授权管理
    springmvc定时任务及RequestBody注解
    springmvc处理异常
  • 原文地址:https://www.cnblogs.com/shenyibo/p/14501685.html
Copyright © 2020-2023  润新知