技术美术TA之URP下的光照(额外光源)

如何在URP里面获取到额外光源光照?
感觉相对URP下灵活方便,代码也很简洁
之前流程都是固定的,比如前向渲染还得写 ForwadBase ForwadAdd之类的。。

流程如下:
1.确保管线配置开启
在这里插入图片描述

2.代码中处理

 //多光源宏定义
 #pragma shader_feature _AdditionalLights

//片段着色器
half4 frag(Varyings i) : SV_Target
{

    #ifdef _AdditionalLights
          //获取额外灯的数量
          //  不超过 Lighing->PerObjectLimit
          int addLightCount = GetAdditionalLightsCount();
          for (int lightIndex = 0; lightIndex < addLightCount; ++lightIndex)
          {
             	// 获取额外光源信息
                Light addLight = GetAdditionalLight(lightIndex, i.positionWS);
                
                ...
          }
    #endif
    
}

代码实现如下:

LightingLambertLightingSpecular 是内置方法如下:

//文件:
// Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl

///
//                      Lighting Functions                                   //
///
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)
{
    half NdotL = saturate(dot(normal, lightDir));
    return lightColor * NdotL;
}
half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)
{
    float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
    half NdotH = half(saturate(dot(normal, halfVec)));
    half modifier = pow(NdotH, smoothness);
    half3 specularReflection = specular.rgb * modifier;
    return lightColor * specularReflection;
}

完整代码:

Shader "Custom/TA_URP/MultiLight"
{
    Properties
    {
        _Color("Color", Color)= (1,1,1,1)
        _BaseMap("BaseMap", 2D) = "white" {}
        _SpecularColor("SpecularColor(RGB) Smoothness(A)", Color) = (1,1,1,1)
        [HDR]_EmissionColor("EmissionColor", Color) = (0,0,0,1)
        [Toggle(_AdditionalLights)] _AddLights ("AddLights", Float) = 1
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //多光源宏定义
            #pragma shader_feature _AdditionalLights

            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct Attributes
            {
                float3 positionOS : POSITION;
                float2 uv : TEXCOORD0;
                float3 normalOS : NORMAL;
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 normalWS : TEXCOORD1;
                float3 positionWS : TEXCOORD2;
            };

            CBUFFER_START(UnityPerMaterial)
                half4 _Color;
                float4 _BaseMap_ST;
                half4 _SpecularColor;
                half4 _EmissionColor;
            CBUFFER_END

            SAMPLER(sampler_BaseMap);
            TEXTURE2D(_BaseMap);

            Varyings vert(Attributes v)
            {
                Varyings o;
                o.positionCS = TransformObjectToHClip(v.positionOS);
                o.uv = TRANSFORM_TEX(v.uv, _BaseMap);
                o.normalWS = TransformObjectToWorldNormal(v.normalOS);
                o.positionWS = TransformObjectToWorld(v.positionOS);
                return o;
            }

            half4 frag(Varyings i) : SV_Target
            {
                half3 baseCol = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv).rgb;
                half3 albedo = baseCol * _Color.rgb;

                half3 ambient = _GlossyEnvironmentColor.rgb;

                Light mainLight = GetMainLight();
                half3 mainLightCol = mainLight.color;
                half3 mainLightDir = mainLight.direction;

                half3 normalWS = normalize(i.normalWS);
                half3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.positionWS);

                half3 diffuse = LightingLambert(mainLightCol, mainLightDir, normalWS);

                // 计算其他光源
                #ifdef _AdditionalLights
                //获取额外灯的数量
                //  不超过 Lighing->PerObjectLimit
                int addLightCount = GetAdditionalLightsCount();
                for (int lightIndex = 0; lightIndex < addLightCount; ++lightIndex)
                {
                    Light addLight = GetAdditionalLight(lightIndex, i.positionWS);
                    //处理衰减
                    half3 addLightColAtten = addLight.color * addLight.distanceAttenuation;
                    // 叠加光照
                    diffuse += LightingLambert(addLightColAtten, addLight.direction, normalWS);
                }
                #endif

                //把0-1 映射到一定范围
                half smoothness = exp(10 * _SpecularColor.a + 1);
                half3 specular = LightingSpecular(mainLightCol, mainLightDir, normalWS,
                    viewDir, _SpecularColor, smoothness);

                //emission
                half3 emission = _EmissionColor.rgb;

                return half4(albedo * (ambient + diffuse + specular) + emission, 1);
            }
            ENDHLSL
        }
    }
    FallBack "Hidden/Shader Graph/FallbackError"
}

效果如图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值