700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色

Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色

时间:2019-10-21 19:58:26

相关推荐

Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色

材质面板截图

功能实现(URP渲染管线下):

1、进一步优化Shader结构和算法;

2、包含PBR材质;

3、投射和接收阴影,并升级支持自定义阴影颜色

4、支持点光源照射(但不支持点光源阴影)。

通用渲染截图

自定义阴影颜色截图

完整代码:

//嘿皮土豆 制作;有问题请留言;//欢迎联系作者邮箱:wz_ftf_private@Shader "ShaderLearn/URP_PBR_AddShadow"{Properties{_MainColor("Main Color", Color) = (1,1,1,0)_MainTeture("Main Teture", 2D) = "white" {}_RoughnessMap("RoughnessMap", 2D) = "white" {}_Metallic("Metallic", Range( 0 , 1)) = 0.2_Gloss("Gloss", Range( 0 , 1)) = 0.3_NormalIntensity("NormalIntensity", Range( 0.001 , 2)) = 1_NormalMap("Normal Map", 2D) = "bump" {}[HDR]_Emission("Emission", Color) = (0,0,0,0)_ShadowMainColor("ShadowMainColor", color) = (0,0,0,1)//调整Shadow的接受阴影的XYZ位置,不影响投射出去的位置调整//_ShadowCoordAddX("ShadowCoordAddX", Range(0,0.1)) = 0//_ShadowCoordAddY("ShadowCoordAddY", Range(0,0.1)) = 0//_ShadowCoordAddZ("ShadowCoordAddZ", Range(0,0.1)) = 0}SubShader{LOD 100Tags {"RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" "Queue"="Geometry" }Cull OffAlphaToMask OffPass{Name "Forward"Tags {"LightMode"="UniversalForward" }HLSLPROGRAM//接受物体投射出来的阴影#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE//增加点光照明效果#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS _ADDITIONAL_OFF#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS//软阴影#pragma multi_compile _ _SHADOWS_SOFT#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float4 texcoord1 : TEXCOORD1;float4 texcoord : TEXCOORD0;};struct v2f{float4 clipPos : SV_POSITION;float4 shadowCoord : TEXCOORD2;float4 tSpace0 : TEXCOORD3;float4 tSpace1 : TEXCOORD4;float4 tSpace2 : TEXCOORD5;float4 uv : TEXCOORD7;};CBUFFER_START(UnityPerMaterial)float4 _NormalMap_ST;float4 _MainColor;float4 _MainTeture_ST;float4 _Emission;float4 _RoughnessMap_ST;float _NormalIntensity;float _Metallic;float _Gloss;CBUFFER_ENDfloat4 _ShadowMainColor;sampler2D _NormalMap;sampler2D _MainTeture;sampler2D _RoughnessMap;//float _ShadowCoordAddX;//float _ShadowCoordAddY;//float _ShadowCoordAddZ;v2f vert(a2v v){v2f o = (v2f)0;//初始化 o;//v2f o;o.uv.xy = v.texcoord.xy;//UVo.uv.zw = 0;float3 positionWS = TransformObjectToWorld( v.vertex.xyz );float3 positionVS = TransformWorldToView( positionWS );float4 positionCS = TransformWorldToHClip( positionWS );VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);o.tSpace0 = float4(normalInput.normalWS, positionWS.x);o.tSpace1 = float4(normalInput.tangentWS, positionWS.y);o.tSpace2 = float4(normalInput.bitangentWS, positionWS.z);half3 vertexLight = VertexLighting( positionWS, normalInput.normalWS );#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)VertexPositionInputs a2v = (VertexPositionInputs)0;a2v.positionWS = positionWS;a2v.positionCS = positionCS;o.shadowCoord = GetShadowCoord( a2v );#endifo.clipPos = positionCS;return o;}half4 frag(v2f i) : SV_Target{float3 WorldNormal = normalize(i.tSpace0.xyz);float3 WorldTangent = i.tSpace1.xyz;float3 WorldBiTangent = i.tSpace2.xyz;float3 WorldPosition = float3(i.tSpace0.w,i.tSpace1.w,i.tSpace2.w);float3 WorldViewDirection = _WorldSpaceCameraPos.xyz - WorldPosition;float4 ShadowCoords = float4(0, 0, 0, 0);//调整Shadow的接受阴影的XYZ位置,不影响投射出去的位置调整//float4 ShadowcooordAdd = float4(_ShadowCoordAddX,_ShadowCoordAddY,_ShadowCoordAddZ,0);//ShadowCoords = TransformWorldToShadowCoord( WorldPosition ) + ShadowcooordAdd;ShadowCoords = TransformWorldToShadowCoord( WorldPosition );WorldViewDirection = SafeNormalize( WorldViewDirection );float2 uv_NormalMap = i.uv.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;float3 tex2DNode13 = UnpackNormalScale( tex2D(_NormalMap, uv_NormalMap ), 1);float2 appendResult30 = (float2(tex2DNode13.r, tex2DNode13.g));float dotResult36 = dot(appendResult30, appendResult30);float3 appendResult40 = (float3(( _NormalIntensity * appendResult30) , sqrt((1 - saturate(dotResult36)))));float3 NormalMap47 = appendResult40;float3 normalizeResult147 = normalize(BlendNormal(WorldNormal, NormalMap47));float3 normalizeResult145 = normalize(_MainLightPosition.xyz);float dotResult146 = dot(normalizeResult147, normalizeResult145);float halfLambert95 = ((dotResult146 * 0.5) + 0.5);float2 uv_MainTeture = i.uv.xy * _MainTeture_ST.xy + _MainTeture_ST.zw;float4 MainColor50 = (_MainColor * tex2D(_MainTeture, uv_MainTeture));float2 uv_RoughnessMap = i.uv.xy * _RoughnessMap_ST.xy + _RoughnessMap_ST.zw;float3 Albedo = MainColor50.rgb;float3 Normal = NormalMap47;float3 Emission = _Emission.rgb;float3 Specular = 0.5;float Metallic = _Metallic;float Smoothness = (_Gloss * tex2D(_RoughnessMap, uv_RoughnessMap).g);float Occlusion = 1;float Alpha = 1;float AlphaClipThreshold = 0.5;float AlphaClipThresholdShadow = 0.5;float3 BakedGI = 0;float3 RefractionColor = 1;float RefractionIndex = 1;float3 Transmission = 1;float3 Translucency = 1;InputData inputData;inputData.positionWS = WorldPosition;inputData.viewDirectionWS = WorldViewDirection;inputData.shadowCoord = ShadowCoords;inputData.normalWS = TransformTangentToWorld(Normal, half3x3( WorldTangent, WorldBiTangent, WorldNormal ));float3 SH = SampleSH(inputData.normalWS.xyz);inputData.bakedGI = SAMPLE_GI( i.lightmapUVOrVertexSH.xy, SH, inputData.normalWS );inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(i.clipPos);inputData.shadowMask = SAMPLE_SHADOWMASK(i.lightmapUVOrVertexSH.xy);//改变阴影的颜色,求出阴影部分和非阴影部分,分别表示为0 和 1;float4 SHADOW_COORDS = TransformWorldToShadowCoord(inputData.positionWS);Light mainLight = GetMainLight(SHADOW_COORDS);half shadow_coord = mainLight.shadowAttenuation;half4 color = UniversalFragmentPBR(inputData, Albedo, Metallic, Specular, Smoothness, Occlusion, Emission, Alpha);float4 ColorResult = lerp(_ShadowMainColor * color, color, shadow_coord);//return color;//不需自定义阴影颜色的选项return ColorResult;}ENDHLSL}Pass{Name "ShadowCaster"Tags {"LightMode"="ShadowCaster" }HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 clipPos : SV_POSITION;};float3 _LightDirection;v2f vert( a2v v ){v2f o;float3 positionWS = TransformObjectToWorld(v.vertex.xyz);float3 normalWS = TransformObjectToWorldDir(v.normal);//float4 clipPos = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection));//===================以下范围内代码等效上面的一行代码;===================float invNdotL = 1.0 - saturate(dot(_LightDirection, normalWS));float scale = invNdotL * _ShadowBias.y;// normal bias is negative since we want to apply an inset normal offsetpositionWS = normalWS * scale.xxx + positionWS;float4 clipPos = mul(UNITY_MATRIX_VP, float4(positionWS, 1));//=====================================================================o.clipPos = clipPos;return o;}half4 frag(v2f i) : SV_TARGET{return 0;}ENDHLSL}}}

写在最后:

1、在我的上一篇文章中有一个不完美的、功能几乎相同Shader,请参见最新版本即可;

2、在优化编写过程中,也是在不断的学习,记得长按 “F12” ;

3、本Shader大部分其实针对的初级用户群体,所以很多的写法会比较 “通俗”;

4、关于本 Shader 的不完善的部分,欢迎各路神仙留言指点,感激不尽;

开源伟大!

希望有所贡献!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。