首页 > 其他分享 >Unity URP Shader之标准的BlinnPhong光照模型

Unity URP Shader之标准的BlinnPhong光照模型

时间:2023-01-01 23:46:22浏览次数:77  
标签:normalize mainLight BlinnPhong Shader Unity pragma addLight NdotL float3

shader如下:

  1 Shader "MyURP/Kerry/URPBlinnPhong"
  2 {
  3     Properties
  4     {
  5         _BaseMap("Base Map", 2D) = "white" {}
  6         _NormalMap("Normal Map", 2D) = "bump" {}
  7         _SpecGloss("Specular Gloss", Range(1, 20)) = 8
  8     }
  9 
 10     SubShader
 11     {
 12         Tags
 13         {
 14             "RenderType" = "Opaque"
 15             "RenderPipeline" = "UniversalPipeline"
 16         }
 17 
 18         Pass
 19         {
 20             Tags
 21             {
 22                 "LightMode" = "UniversalForward"
 23             }
 24 
 25             HLSLPROGRAM
 26 
 27             // Universal Pipeline keywords
 28             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
 29             #pragma multi_compile _ _ADDITIONAL_LIGHTS
 30             #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
 31 
 32             #pragma vertex vert
 33             #pragma fragment frag
 34             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 35             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
 36 
 37             TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
 38             TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
 39             float _SpecGloss;
 40 
 41             struct appdata
 42             {
 43                 float4 vertex : POSITION;
 44                 float2 uv : TEXCOORD0;
 45                 float4 normal : NORMAL;
 46                 float4 tangent : TANGENT;
 47             };
 48 
 49             struct v2f
 50             {
 51                 float4 pos : SV_POSITION;
 52                 float2 uv : TEXCOORD0;
 53                 float3 worldNormal : TEXCOORD1;
 54                 float3 worldTangent : TEXCOORD2;
 55                 float3 worldBinormal : TEXCOORD3;
 56                 float3 worldPos : TEXCOORD4;
 57                 float4 shadowCoord : TEXCOORD5;
 58             };
 59 
 60             v2f vert(appdata v)
 61             {
 62                 v2f o;
 63                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 64                 o.uv = v.uv;
 65                 o.worldNormal = normalize(mul(v.normal, unity_WorldToObject).xyz);
 66                 o.worldTangent = normalize(mul(unity_ObjectToWorld, v.tangent).xyz);
 67                 o.worldBinormal = normalize(cross(o.worldNormal, o.worldTangent) * v.tangent.w);
 68                 o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
 69                 o.shadowCoord = TransformWorldToShadowCoord(o.worldPos);
 70                 return o;
 71             }
 72 
 73             half4 frag(v2f i) : SV_TARGET
 74             {
 75                 // get info
 76                 float3 worldNormal = normalize(i.worldNormal);
 77                 float3 worldTangent = normalize(i.worldTangent);
 78                 float3 worldBinormal = normalize(i.worldBinormal);
 79                 float3 worldPos = i.worldPos;
 80 
 81                 // sample texture
 82                 half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv);
 83                 half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv);
 84                 half3 normalData = UnpackNormal(normalMap);
 85 
 86                 // 法线
 87                 float3x3 matrixTNB = float3x3(worldTangent, worldBinormal, worldNormal);
 88                 float3 normal = mul(normalData, matrixTNB);
 89 
 90                 // 主光源光照计算
 91                 float4 shadowCoord = i.shadowCoord;
 92                 float3 worldView = GetWorldSpaceNormalizeViewDir(worldPos);
 93                 half3 finalLightCol = half3(0, 0, 0);
 94                 {
 95                     Light mainLight = GetMainLight(shadowCoord);
 96                     // diffuse
 97                     float NdotL = dot(normal, mainLight.direction);
 98                     NdotL = saturate(NdotL * 0.5 + 0.5);
 99                     half3 diffuse = baseMap.rgb * mainLight.color * NdotL
100                                     * mainLight.shadowAttenuation * mainLight.distanceAttenuation;
101 
102                     // specular
103                     float3 halfVL = normalize(mainLight.direction + worldView);
104                     float NdotH = saturate(dot(normal, halfVL));
105                     half3 specular = baseMap.rgb * mainLight.color * pow(NdotH, _SpecGloss)
106                                     * mainLight.shadowAttenuation * mainLight.distanceAttenuation;
107 
108                     finalLightCol = diffuse + specular;
109                 }
110 
111                 // 其它光源光照计算
112                 #if defined(_ADDITIONAL_LIGHTS)
113                 uint addLightCount = GetAdditionalLightsCount();
114                 for(uint lightIndex = 0;lightIndex < addLightCount;++lightIndex)
115                 {
116                     Light addLight = GetAdditionalLight(lightIndex, worldPos, shadowCoord);
117 
118                     // diffuse
119                     float NdotL = dot(normal, addLight.direction);
120                     NdotL = saturate(NdotL * 0.5 + 0.5);
121                     half3 diffuse = baseMap.rgb * addLight.color * NdotL
122                                      * addLight.shadowAttenuation * addLight.distanceAttenuation;
123 
124                     // specular
125                     float3 halfVL = normalize(addLight.direction + worldView);
126                     float NdotH = saturate(dot(normal, halfVL));
127                     half3 specular = baseMap.rgb * addLight.color * pow(NdotH, _SpecGloss)
128                                     * addLight.shadowAttenuation * addLight.distanceAttenuation;
129 
130                     finalLightCol += (diffuse + specular);
131                 }
132                 #endif
133 
134                 half4 col = half4(finalLightCol, 1);
135                 return col;
136             }
137 
138             ENDHLSL
139         }
140 
141         Pass
142         {
143             Name "ShadowCaster"
144             Tags{"LightMode" = "ShadowCaster"}
145 
146             ZWrite On
147             ZTest LEqual
148             ColorMask 0
149             Cull[_Cull]
150 
151             HLSLPROGRAM
152             #pragma exclude_renderers gles gles3 glcore
153             #pragma target 4.5
154 
155             // -------------------------------------
156             // Material Keywords
157             #pragma shader_feature_local_fragment _ALPHATEST_ON
158             #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
159 
160             //--------------------------------------
161             // GPU Instancing
162             #pragma multi_compile_instancing
163             #pragma multi_compile _ DOTS_INSTANCING_ON
164 
165             // -------------------------------------
166             // Universal Pipeline keywords
167 
168             // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
169             #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
170 
171             #pragma vertex ShadowPassVertex
172             #pragma fragment ShadowPassFragment
173 
174             #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
175             #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
176             ENDHLSL
177         }
178     }
179 
180     FallBack "Hidden/Universal Render Pipeline/FallbackError"
181 }

效果如下:

 

 

转载请注明出处:https://www.cnblogs.com/jietian331/p/17019270.html

标签:normalize,mainLight,BlinnPhong,Shader,Unity,pragma,addLight,NdotL,float3
From: https://www.cnblogs.com/jietian331/p/17019270.html

相关文章

  • unity简单的小地图
    在Assets文件中右键->Create->RenderTexture,命名为map在Hierarchy面板中新建一个UI->RawImage命名为RawImageMap,该物体的Texture属性设置为第一步中的mapHierarchy......
  • 在Unity中创建有限状态机
    有限状态机(FSM)拥有有限数量的状态,每个状态可以根据输入决定迁移到哪个状态。在Unity中的你可以创建有限状态机来做一些事情,比如动画转换,简单的敌人AI,更好控制角色等。一个简......
  • UnityXR Pico和HTCVive判断手柄连没连接上
        方法一:用InputDevices.GetDevices(),PICO中使用的此方法           此方法获取当前连接的设备:           1.在Pico中连上哪个手柄就......
  • Unity —— Dropdown 多次重复点击返回事件 UI_AlwaysCallback_Dropdown (转)
    usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.EventSystems;usingUnityEngine.UI;///<summary>///每次都......
  • Unity 关于可寻址资源系统Addressables的使用和理解(一) 准备工作
    一、打开Unity的PackageManager,安装Addressables包二、打开分组面板,对未来要分类的资源包进行分组,并对组进行设置。1.菜单栏选择Window/AssetManagent/Addressables/Gro......
  • Unity3D_使用JsonUtility读取Json
    使用Unity内置的方法对json进行写入与读取,不依赖任何插件和dll使用到的API读取:JsonUtility.FromJson<T>(stringjson)JsonUtility.FromJsonOverwr......
  • unity 资源打包,MD5值计算注意点
    仅作记录:unity3d在修改资源时,有些类型的资源修改的是源文件,比如:fbx,mp3,.jpg,.png等。这些资源是外部资源导入unity3d中,untiy3d导入编译时,生成相应的meta文件,meta文件中保存......
  • Unity游戏开发——画出有物理效果的线
    usingSystem.Collections.Generic;usingSystem.Linq;usingUnityEngine;namespaceStarry{publicclassDrawLine:MonoBehaviour{publicMat......
  • Unity 检测FPS工具
    检测FPS工具publicclassFPS:MonoBehaviour{publicfloatf_UpdateInterval=0.5F;privatefloatf_LastInterval;privatein......
  • 参加MVP OpenDay 和2015 MVP Community Camp社区大课堂
    微软MVPOpenday1月30日在北京召开,到时全国上百位MVP专家将齐聚北京。当然还有亚太的其他国家地区的MVP也会来北京,1月31日微软MVP项目组主办的年度微软技术社区分享大......