URP平面阴影合批处理 shadow

news2024/9/20 22:23:35

  闲谈 

       相信大家在日常工作中发现了一个问题 , urp下虽然可以做到3个Pass 去写我们想要的效果,但是,不能合批(不能合批,那不是我们CPU要干冒烟~!)

      好家伙,熊猫老师的偏方来了 ,教大家如何在URP渲染管线下做到多pass也能合批,干货满满。  

一:合并公共预设 

        方便我们多Pass状态下 ,更快的实现,也能让代码更加专业。

如图所示: 

     我们在Subshader下用 HLSLINCLUDE  和 ENDHLSL 去实现。

 其次 咱们在第二个Pass  “影子渲染pass”里面添加Tags  并对LightMode 复制渲染层为 “XiongMaoWuDao”

如图所示:

    

   Pass
        {

		Name "XiongMaoWuDao"
		Tags{
	   
	    	"LightMode" = "XiongMaoWuDao"
		}

二:URP  Add Renderer Feature 

如图步骤:

 

添加Renderer Feature  设置如下:

   

好了,现在我们来看看多物件下影子Pass是否合批。

上才艺:

  

Shader "XiongMaoWuDao/Shadow"
{
    Properties
    {
	    
	    [MainColor] _BaseColor("BaseColor", Color) = (1,1,1,1)
        [MainTexture] _BaseMap("BaseMap", 2D) = "white" {}
	    //影子处理
		//影子淡出处理
        _ShadowColor("Color", Color) = (0, 0, 0, 1)
        _LightDir ("Light Direction", Vector) = (0, 1, 0, 0)
        _PlaneY ("Plane Height", Float) = 0	
		_ShadowFalloff ("ShadowFalloff ",Range (0,1)) = 0.5

    }
    SubShader
    {
		Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "Queue" = "Opaque"}
	  HLSLINCLUDE
		  #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

	         TEXTURE2D(_BaseMap);
             SAMPLER(sampler_BaseMap);

           CBUFFER_START(UnityPerMaterial)
		
            float4 _BaseMap_ST;
            half4 _BaseColor;
		    float4 _ShadowColor;
            half3 _LightDir;
			half _PlaneY;
			half _ShadowFalloff;

            CBUFFER_END
        ENDHLSL

		pass 
		{
			Name "Forward"
       
            Tags {
		  
			}
		  HLSLPROGRAM
		    #pragma vertex vert
            #pragma fragment frag
		    #pragma multi_compile_instancing
			  struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
				 UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;   
                float4 vertex : SV_POSITION;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

			   v2f vert (appdata v)
            {
                v2f o;
				  UNITY_SETUP_INSTANCE_ID(v);
				  UNITY_TRANSFER_INSTANCE_ID(v, o);
                o.vertex = TransformObjectToHClip(v.vertex.xyz);;
                o.uv = TRANSFORM_TEX(v.uv, _BaseMap);
           
                return o;
            }

            half4 frag (v2f i) : SV_Target
            {
                 UNITY_SETUP_INSTANCE_ID(i);
             return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv) * _BaseColor;
            }
	
			ENDHLSL
		}
        Pass
        {

		Name "XiongMaoWuDao"
		Tags{
	   
	    	"LightMode" = "XiongMaoWuDao"
		}
		//添加模板缓冲区是解决影子重叠问题(降低透明度就能发现)
		  Stencil
    {
        Ref 1  //和模板缓冲区的值进行比较。
        Comp NotEqual   //比较函数, 决定参考值和模板缓冲区的值如何比较 (是否相等) NotEqual
        Pass Replace   //模板测试通过时候的操作 。  Replace 模板缓冲区中的值设为参考值。Replace
        Fail Keep    //模板测试失败时候的操作 。    keep是保持缓冲区当前的值
		//ZFail Keep  
		
    }
		Blend SrcAlpha OneMinusSrcAlpha
		//	ZWrite off
       //     Offset -1 , 0
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
		
      
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;   
                float4 vertex : SV_POSITION;
		    	float4 color : COLOR;
            };
		

			  //阴影方向计算。
        float3 PlanarShadowPos(float3 posWS)
        {
          float3 L = normalize(_LightDir);
          float3 N = float3(0, 1, 0);

          float d1 = dot(L, N);
          float d2 = posWS.y - _PlaneY;

          // 阴影坐标沿法线方向偏移一点,防止与平面重叠时出现z-fighting的问题
          float3 offsetByNormal = N * 0.001;
          return posWS - L * (d2 / d1) + offsetByNormal;

          }


            v2f vert (appdata v)
            {
                v2f o;
				 // 顶点坐标,转世界坐标
                float3 posWS = TransformObjectToWorld(v.vertex.xyz);
               // 世界顶点坐标转为平面坐标
                posWS = PlanarShadowPos(posWS);
                o.vertex = TransformWorldToHClip(posWS);
                o.uv =v.uv;         
		
			   //得到中心点世界坐标
		    	float3 center = float3(unity_ObjectToWorld[0].w,  _PlaneY, unity_ObjectToWorld[2].w);
		    	//计算阴影衰减
				float falloff = 1 - saturate(distance(posWS, center) * _ShadowFalloff);
 
			   	o.color = _ShadowColor;
				o.color.a *=falloff;
                return o;
            }



            half4 frag (v2f i) : SV_Target
            {
                return i.color;
            }
            ENDHLSL
        }

  }}

能看见我在场景中做了4个材质球且用了不同的贴图,但是  能看见第一个pass对颜色渲染已经合批成一个了(除了地面用了默认的材质球外,忽略)。 第二个Pass影子也全部合并成一个渲染层渲染,完美解决问题。 鼓掌~~~!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数值方法-Python实现】Crout分解+追赶法实现

涉及Crout分解、追赶法的线性方程组求解方法的Python实现。 原文链接:https://www.cnblogs.com/aksoam/p/18366119 Codes def CroutLU(A:np.ndarray)->Tuple[np.ndarray,np.ndarray]:"""Crout LU分解算法,ALUinput:A: (n,n) np.ndarray,方阵out…

DrissionPage自动化获取城市数据内容

一、获取页面内容 二、最终结果 上海市 约收录140个指标 查看98075次 人均GDP 153299元 公交车 17899辆 户籍人口 1469.3万人 三、代码 from DrissionPage._pages.chromium_page import ChromiumPage import time page ChromiumPage() page.get(https://www.swguancha.com/…

【Delphi】中多显示器操作基本知识点

提要: 目前随着计算机的发展,4K显示器已经逐步在普及,笔记本的显示器分辨率也都已经超过2K,多显示器更是普及速度很快。本文介绍下Delphi中操作多显示器的基本知识点(Windows系统),这些知识点在…

UniFab 是一款由人工智慧驅動的視訊增強器+ crack

UniFab 是一款功能强大的视频处理工具,包括 10 个基于 AI 的功能。使用 UniFab,您可以提高视频和音频质量、将视频转换为不同的格式、根据自己的喜好编辑视频等等。以下是适用于 Windows 的 UniFab 程序的简要说明: 视频转换器。UniFab 支持 1000 多种视频格式的转换,包括 …

构建自己的图数据集

代码: import warnings warnings.filterwarnings("ignore") import torch from torch_geometric.data import Datax torch.tensor([[2,1],[5,6],[3,7],[12,0]],dtypetorch.float) y torch.tensor([0,1,0,1],dtypetorch.float)#定义边 edge_index torc…

⌈ 传知代码 ⌋ DETR[端到端目标检测]

💛前情提要💛 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间,对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

Leetcode3232. 判断是否可以赢得数字游戏

Every day a Leetcode 题目来源:3232. 判断是否可以赢得数字游戏 解法1:3232. 判断是否可以赢得数字游戏 用一个 sum1 统计个位数的和,sum2 统计十位数的和。 只要 sum1 和 sum2 不相等,Alice 拿大的就能赢得这场游戏。 代码…

【论文阅读】HuatuoGPT-II, One-stage Training for Medical Adaption of LLMs

总体概要 本文深入探讨了一款专为医疗领域设计的大规模语言模型——HuatuoGPT-II的创新、性能与应用。HuatuoGPT-II采用统一的单阶段训练流程,将传统的继续预训练和监督微调整合,有效解决了医疗数据的异质性问题,包括语言、体裁和格式差异&a…

【STM32单片机_(HAL库)】3-2-1【中断EXTI】【电动车报警器项目】继电器定时开闭

1.硬件 STM32单片机最小系统继电器模块 2.软件 继电器模块alarm驱动文件添加GPIO常用函数main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "alarm.h"int main(void) {HAL_Init(); …

硬件面试经典 100 题(71~90 题)

71、请问下图电路的作用是什么? 该电路实现 IIC 信号的电平转换(3.3V 和 5V 电平转换),并且是双向通信的。 上下两路是一样的,只分析 SDA 一路: 1) 从左到右通信(SDA2 为输入状态&…

同一台电脑同时连接使用Gitee(码云)和Github

1、添加对应的密钥 ssh-keygen -t rsa -C "your_emailexample.com" -f ~/.ssh/github_id-rsa //生成github秘钥 ssh-keygen -t rsa -C "your_emailexample.com" -f ~/.ssh/gitee_id-rsa //生成码云秘钥 2、在 ~/.ssh 文件里会生成对应的文件 文件夹里会…

[k8s源码]12.远程调试dlv

在Windows/Mac宿主机上,使用GoLand的IDE进行开发,但是如何将这些代码直接运行在k8s集群中并看到运行效果呢,这里有一个远程调试工具dlv。 图中展示了dlv的工作方式。GoLand IDE中包含Editor(编辑器)和Debugger(调试器)组件,其中De…

深度学习基础之前馈神经网络

目录 基本结构和工作原理 神经元和权重 激活函数 深度前馈网络 应用场景 优缺点 深度前馈神经网络与卷积神经网络(CNN)和循环神经网络(RNN)的具体区别和联系是什么? 具体区别 联系 如何有效解决前馈神经网络…

探索Python的工业通信之光:pymodbus的奇妙之旅

文章目录 探索Python的工业通信之光:pymodbus的奇妙之旅背景:为何选择pymodbus?pymodbus是什么?如何安装pymodbus?5个简单的库函数使用方法3个场景使用示例常见bug及解决方案总结 探索Python的工业通信之光&#xff1a…

炒作将引发人工智能寒冬

我们似乎经常看到人工智能的进步被吹捧为机器真正变得智能的一大飞跃。我将在这里挑选其中的一个例子,并确切解释为什么这种态度会为人工智能的未来埋下隐患。 这很酷,这是一个非常困难且非常具体的问题,这个团队花了3 年时间才解决。他们一定…

结合GPT与Python实现端口检测工具(含多线程)

端口检测器是一个非常实用的网络工具,它主要用于检测服务器或本地计算机上的特定端口是否处于开放状态。通过这个工具,你可以快速识别和诊断网络连接问题,确保关键服务的端口能够正常接收和处理数据。这对于网络管理员和开发者来说是一个不可…

【Linux修行路】基础I/O——重定向的实现原理

目录 ⛳️推荐 一、再来理解重定向 1.1 输出重定向效果演示 1.2 重定向的原理 1.3 dup2 1.4 输入重定向效果演示 1.5 输入重定向代码实现 二、再来理解标准输出和标准错误 2.1 同时对标准输出和标准错误进行重定向 2.2 将标准输出和标准错误重定向到同一个文件 三、…

版本更新 《坚持学习计时器》软件V3.1 更新内容:自动实时显出

🌟 嗨,我是命运之光! 🌍 2024,每日百字,记录时光,感谢有你一路同行。 🚀 携手启航,探索未知,激发潜能,每一步都意义非凡。 版本更新 《坚持学习…

【统计字符数量】统计出每种字符的数量

输入一行字符&#xff0c;分别统计出其中英文字母、空格、数字和其他字符的个数&#xff0c;使用C语言实现&#xff0c; 具体代码&#xff1a; #include<stdio.h>int main(){char c;int letters0,space0,digit0,others0;printf("请输入一行字符&#xff1a; "…

SpringBoot整合Junit单元测试(解决空指针异常)

1.依赖 依赖只需要导入Spring-Boot-starter、Spring-Boot-test&#xff08;不需要另导入junit依赖&#xff09; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test…