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

这篇具有很好参考价值的文章主要介绍了Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

材质面板截图

urp阴影颜色,Unity Shader 笔记,unity,学习,游戏引擎,图形渲染

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

1、进一步优化Shader结构和算法;
2、包含PBR材质;
3、投射和接收阴影,并升级支持自定义阴影颜色
4、支持点光源照射(但不支持点光源阴影)。

通用渲染截图

urp阴影颜色,Unity Shader 笔记,unity,学习,游戏引擎,图形渲染

自定义阴影颜色截图

urp阴影颜色,Unity Shader 笔记,unity,学习,游戏引擎,图形渲染

完整代码:

//嘿皮土豆 制作;有问题请留言;
//欢迎联系作者邮箱:wz_ftf_private@163.com
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 100
		Tags { "RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" "Queue"="Geometry" }
		Cull Off
		AlphaToMask Off

		Pass
		{
			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_END

			float4 _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;//UV
				o.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 );
				#endif
				
				o.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 offset
				positionWS = 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 的不完善的部分,欢迎各路神仙留言指点,感激不尽;文章来源地址https://www.toymoban.com/news/detail-531081.html

开源伟大!
希望有所贡献!

到了这里,关于Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity SRP 管线【第四讲:URP 阴影】

    在UniversalRenderer.cs/ line 505行处 此处已经准备好了所有渲染数据(所有数据全部存储在了renderingData中) 我们只用renderingData中的数据初设置mainLightShadows 进入函数 m_MainLightShadowCasterPass.Setup(ref renderingData); 在UniversalRenderer管线创建的时候,我们已经做了创建 我们设置MainLightShado

    2024年02月03日
    浏览(47)
  • Unity3D学习记录01:URP渲染管线以及3D游戏场景设置

    以下内容所使用的版本均为Unity2022.3 先在 Window-Package Manager-Unity Registry 里面搜索添加Universal RP   Unity中,创建渲染管线的方式为Asset文件夹下右键 Create-Readering-URP Asset(with Universal Asset) 会创建以下两个Pipeline:  接着在图中的设置里添加这两个渲染管线(Project Setting在Edit窗口下

    2024年02月08日
    浏览(63)
  • Unity URP渲染管线与内置渲染管线的性能差别

    首先,我们来了解一下Unity的内置渲染管线。内置渲染管线是Unity较早版本中使用的默认渲染管线,它使用的是传统的图形渲染技术。内置渲染管线提供了一系列的渲染功能,如阴影、反射、抗锯齿等。但是,由于其较为庞大且复杂的设计,它的性能相对较低。在高质量图形效

    2024年02月08日
    浏览(41)
  • Unity升级到URP渲染管线,

    首先 需要安装URP的包 安装后 然后打开ProjectSettings 替换 上一步创建 URP的配置文件 这个时候有些材质就会变成洋红色 选择RenderPipelineConverter 等待转换完成即可,

    2024年02月15日
    浏览(54)
  • Unity内置渲染管线升级URP教程

    URP全称为Universal Render Pipeline(通用渲染管线),可以提供更加灵活的渲染方案,通过添加Render Feature实现各种渲染效果。并且可以针对移动平台进行专门的优化,同时还提供了SRPBatcher提高渲染效率。Unity的一些工具,比如ShaderGraph,也是必须在URP管线下才可以使用,可以说许多方

    2024年02月16日
    浏览(56)
  • Unity shader 入门之渲染管线一、总览

     如下示意图 应用阶段(ApplicationStage):准备场景信息(视景体,摄像机参数)、粗粒度剔除、定义每个模型的渲染命令(材质,shader)——由开发者定义,不做讨论。 几何阶段(GemetryStage):顶点着色器、曲面细分着色器、几何着色器、裁剪、屏幕映射; 光栅化阶段(Rasterizer

    2024年02月11日
    浏览(48)
  • 【Unity URP渲染管线下设置灯光数量上限_灯光不显示问题案例分享】

    1.我的这个项目是在URP渲染管线下,我在场景里创建了六个点灯,转动物体的时候,发现灯显示不全,会一闪一闪的出现。 2.在RenderPipelineAsset配置文件中查看灯光数量上限,首先在EditProject Setting 3.在Project Setting里选Quality,在Rendering找到UniversalRP Asset 4.选中UniversalRP Asset文件

    2024年02月16日
    浏览(47)
  • Unity | HDRP高清渲染管线学习笔记:Volume

    目录 一、Volume框架 二、Volume Profile 三、Volume重载 1.Visual Environment(环境设置) 1.1 Sky type 1.2 Ambient Mode 2.Sky 2.1 HDRI Sky(HDRI天空) 2.2 Gradient Sky(渐变天空) 2.3 Physically Based Sky(基于物理的天空) 3.Exposure(屏幕曝光) 3.1 Mode 3.2 Metering Mode(测光模式) 3.3 Limit Min和Limit Max 3.

    2024年02月11日
    浏览(42)
  • Unity | HDRP高清渲染管线学习笔记:示例场景解析

    目录 一、HDRP入门 1.HDRP设置  1.1 HDRP配置文件中的全部设置项         1.1.1 Rendering下的Lit Shader Mode         1.1.2 Lighting 下的Volumetrics(体积光)和Screen Space Reflection(屏幕空间反射) 2.离线渲染VS实时渲染 3.Volume组件 3.1Sky and Fog Volume 天空雾效 4.光照贴图烘焙 5.HDRP材质和

    2024年02月08日
    浏览(102)
  • Unity | HDRP高清渲染管线学习笔记:基本操作

    目录 一、场景整体环境光强度 1.HDRI Sky 2.Shadows 二、屏幕后处理效果(Post Processing) 1.Exposure 2.Post-processing/Tonemapping 三、抗锯齿 四、添加光源 1.Light Explorer窗口 2.光照探针组 3.反射探针 4.烘焙光照贴图 本文主要是了解HDRP基本操作: 如何为一个已经摆放好模型的场景添加环境光等

    2024年02月16日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包