zoukankan      html  css  js  c++  java
  • 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)来解决。最后是这样子:

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

  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/shenyibo/p/14501685.html
Copyright © 2011-2022 走看看