unity通用渲染管线(urp)实现逐像素光照

在参阅《shader入门精要》的时候敲了一遍逐顶点光照的代码发现物体呈现紫色(渲染丢失),最后发现此代码在内置渲染管线中正常,但在hdrp/urp中出现问题,最后解决办法是将cg代码用hlsl重写(HDRP/URP自带的着色器也是用HLSL实现的)。

重写后的hlsl代码如下:

Shader "Custom/Blinnphong"{
    
    Properties{
        _Maintex ("Maintex", 2D) = "white"{}
        _Cubemap ("Cubemap ", CUBE) = "_Skybox"{}
        [Normal]_Normal ("Normal", 2D) = "bump"{}
        _Bumpscale ("Bumpscale", range(0,1)) = 1
        [HDR]_DiffuseColor ("DiffuseColor", Color)= (1,1,1,1)
        [HDR]_SpecularColor ("specularColor", Color)= (1,1,1,1)
        _Gloss("Gloss", Range(1,255)) = 20
        _EnvScale("EnvScale", Range(0,1))=0.5
    }
    SubShader{
       
        Pass{

            Tags { "LightMode" = "UniversalForward"} 
            HLSLPROGRAM
     
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            CBUFFER_START(UnityPerMaterial)
            float4 _Maintex_ST;
            float4 _Normal_ST;
            float4 _Bumpscale;
            float _Gloss;
            float _EnvScale;
            float4 _DiffuseColor;
            float4 _SpecularColor;
            CBUFFER_END
            sampler2D _Maintex;
            //TEXTURE2D (_MainTex);
            //SAMPLER(sampler_MainTex);       
            sampler2D _Normal;
            samplerCUBE _Cubemap;

            struct a2v {
                float4 positionOS : POSITION;
                float4 normalOS : NORMAL;
                float4 tangentOS : TANGENT;
                float2 uv : TEXCOORD0;
            };
            struct v2f{
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float4 normalWS : NORMAL;
                float4 tangentWS : TANGENT;
                float4 biotangentWS : TEXCOORD1;
            };
        
            v2f vert(a2v v){
                v2f o;
                o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
                float3 positionWS = TransformObjectToWorld(v.positionOS.xyz);
                //float3 positionWS =v.positionOS;
                o.normalWS.xyz = normalize(TransformObjectToWorldNormal(v.normalOS.xyz));
                o.tangentWS.xyz =normalize(TransformObjectToWorldDir(v.tangentOS.xyz));
                o.biotangentWS.xyz =normalize(cross(o.normalWS.xyz,o.tangentWS.xyz) * v.tangentOS.w);
                o.normalWS.w=positionWS.x;
                o.tangentWS.w=positionWS.y;
                o.biotangentWS.w=positionWS.z;
                o.uv= TRANSFORM_TEX(v.uv, _Maintex);
                return o;
            }
           
            half4 frag(v2f i) : SV_Target {
                Light light = GetMainLight();
                half3 Clight=light.color;
                float3 L = normalize(light.direction);
                float3 positionWS=float3(i.normalWS.w,i.tangentWS.w,i.biotangentWS.w);
                float3 V=SafeNormalize(_WorldSpaceCameraPos.xyz - positionWS);
                float3 mainColor = tex2D( _Maintex, i.uv).xyz;
                // float3 mainColor = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv).rgb;
                float3 H=SafeNormalize(V+L);
                //计算法线(把法线从贴图的切线空间转换到世界空间下)                
                float3x3 TtoW={i.tangentWS.xyz,i.biotangentWS.xyz,i.normalWS.xyz};  
                TtoW=transpose(TtoW);                           
                half3 NormalTS = UnpackNormalScale(tex2D( _Normal, i.uv),_Bumpscale);
                // half3 NormalTS = UnpackNormal(tex2D( _Normal, i.uv));
                // NormalTS.xy*=_Bumpscale;
                NormalTS.z=sqrt(1-saturate(dot(NormalTS.xy,NormalTS.xy)));
                float3 N=normalize(mul(TtoW,NormalTS));

                //漫反射
                float3 diffuse=Clight*mainColor*_DiffuseColor*saturate(dot(L,N));

                //高光反射
                float3 specular=Clight*mainColor*_SpecularColor*pow(max(0,dot(H,N)),_Gloss);

                //环境光
                float3 reflWS=reflect(-V,i.normalWS.xyz);
                float3 envreflColor=texCUBE(_Cubemap,reflWS).rgb*_EnvScale;

                float3 finalcolor=diffuse+specular+envreflColor;


                return float4(finalcolor,1.0f);
            }           
            ENDHLSL
        }
    }
}

最终实现效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值