URP - 简单光照

要点

 

公式中的相关变量的获取

1) 顶点法线方向

  VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS.xyz);
  OUT.normalWS = normalInputs.normalWS;

 2) 光线方向

  Light light = GetMainLight();
  float3 lightDirWS = light.direction;

 3) 视角方向

  VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);
  OUT.viewDirWS = GetCameraPositionWS() - positionInputs.positionWS;

 

复制代码
Shader "My/URP_SimpleLit" {
    Properties {
        _BaseMap("Texture", 2D) = "white" {} //主贴图
        _BaseColor("Tint Color", Color) = (1, 1, 1, 1) //混合颜色

        _Specular("Specular", Color) = (1, 1, 1, 1) //高光反射颜色
        _Gloss("Gloss", Range(8.0, 256)) = 20 //高光区域大小
    }

    SubShader {
        Tags {
            "RenderPipeline" = "UniversalPipeline" //用于URP的shader
            "Queue" = "Geometry" //URP中不再决定渲染顺序(以前是序号越小越先渲染), 而仅仅是一个类别id
            "RenderType" = "Opaque"
        }

        HLSLINCLUDE

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

        //所有属性都要缓存到CBuffer中, 这样才能兼容SRP Batcher
        CBUFFER_START(UnityPerMaterial)
            float4 _BaseMap_ST;
            float4 _BaseColor;
            float4 _Specular;
            float _Gloss;
        CBUFFER_END

        ENDHLSL

        Pass {
            Tags { "LightMode" = "UniversalForward" } //该pass为渲染pass

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

            #pragma vertex vert //指定顶点着色器函数
            #pragma fragment frag //指定片元着色器函数

            struct Attributes { //程序传入顶点着色器的数据
                float4 positionOS : POSITION; //用模型空间顶点坐标填充该变量
                float4 normalOS : NORMAL; //用模型空间法线方向填充该变量
                float2 uv : TEXCOORD0; //用模型的第一套纹理坐标(uv)填充该变量
            };

            struct Varings { //顶点着色器传入片元着色器的数据
                float4 positionCS : SV_POSITION; //该变量存放了裁剪空间的顶点坐标
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
                float3 viewDirWS : TEXCOORD2;
                float3 normalWS : TEXCOORD3;
            };

            //变量
            TEXTURE2D(_BaseMap);
            SAMPLER(sampler_BaseMap);

            Varings vert(Attributes IN) { //顶点着色器
                Varings OUT;

                VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz); //顶点坐标从模型空间转其他空间
                OUT.positionCS = positionInputs.positionCS;
                OUT.positionWS = positionInputs.positionWS;

                OUT.viewDirWS = GetCameraPositionWS() - positionInputs.positionWS; //视角方向

                VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS.xyz);
                OUT.normalWS = normalize(normalInputs.normalWS); //法线方向

                OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap); //应用贴图的tiling和offset
                return OUT;
            }

            float4 frag(Varings IN) : SV_Target { //片元着色器(逐像素)
                //计算主光(逐像素)
                Light light = GetMainLight();
                float3 lightDirWS = light.direction;
                half3 diffuse = LightingLambert(light.color, lightDirWS, IN.normalWS); //lambert方法计算漫反射比例
                half3 specular = LightingSpecular(light.color, lightDirWS, normalize(IN.normalWS), normalize(IN.viewDirWS), _Specular, _Gloss); //Blinn-Phong方法计算高光

                //计算附加光照(逐像素)
                uint pixelLightCount = GetAdditionalLightsCount();
                for (uint lightIndex = 0; lightIndex < pixelLightCount; ++lightIndex) {
                    Light light = GetAdditionalLight(lightIndex, IN.positionWS);
                    //叠加附加光照
                    diffuse += LightingLambert(light.color, light.direction, IN.normalWS);
                    specular += LightingSpecular(light.color, light.direction, normalize(IN.normalWS), normalize(IN.viewDirWS), _Specular, _Gloss);
                }

                half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); //根据纹理坐标获取像素颜色
                half3 albedo = texColor.rgb * _BaseColor.rgb; //物体本身颜色的最大反射率
                half3 c = albedo * diffuse + specular;
                return float4(c, 1);
            }
            ENDHLSL
        } // Pass
    } // SubShader
}
复制代码

 

参考

URP基础光照 - 简书

【Unity Shader】在URP里写Shader(三):URP简单光照Shader - 知乎

 

posted @   yanghui01  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示