当前位置: 首页 > news >正文

SRP——聚光灯的阴影

https://catlikecoding.com/unity/tutorials/scriptable-render-pipeline/spotlight-shadows/
https://zhuanlan.zhihu.com/p/83499311?from_voters_page=true

什么是texture sampler?
在老的GLSL代码中,我们使用sampler2D来定义texture和sampler state。但他们是不同的东西,两者都占用资源。
sampler state是独立于texture单独存在。 我们可以复用一个sampler state去采样不同的texture。
具体参考:
https://forum.unity.com/threads/sampler-count-limit-for-pixel-shader-in-shader-model-5-0.452957/
https://docs.unity3d.com/Manual/SL-SamplerStates.html

1、投射纹理的shader:
加入一个"LightMode" = "ShadowCaster"的pass
顶点着色器的计算方法:

float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
output.clipPos = mul(unity_MatrixVP, worldPos); //齐次坐标

投射的时候,加上bias,让其有一定的影子偏移,这里是投射的时候,加在了深度上:

#if UNITY_REVERSED_Z
	output.clipPos.z -= _ShadowBias;
	output.clipPos.z = min(output.clipPos.z, output.clipPos.w * UNITY_NEAR_CLIP_VALUE);
#else

UNITY_REVERSED_Z近处为1,远处为0,减去_ShadowBias,说明要让其写入的参考值小一点,比如如说原先写入的是0.5,我们对于0.49的这个点的深度,那么经过比较,发现0.49这个点,在阴影中。
而此时如果加上bias,0.5-0.02=0.48,写参考值为0.48
那么0.49大于0.48,表示这个点,不在阴影中,所以使得那些出现影子游泳的点,现在全都是被照亮的。

#if defined(UNITY_REVERSED_Z)
	#define UNITY_NEAR_CLIP_VALUE (1.0)
#else
	#define UNITY_NEAR_CLIP_VALUE (-1.0)
#endif

片段着色器,则直接返回0即可。

float4 ShadowCasterPassFragment (VertexOutput input) : SV_TARGET 
{
	return 0;
}

2、影子的绘制
判断当前有个多少个影响物体的灯光。

CullResults.Cull(ref cullingParameters, context, ref cull);
if (cull.visibleLights.Count > 0)
{
	……
}

这个当前场景可见的灯光总数。

for (int i = 0; i < cull.visibleLights.Count; i++)
{
	if (light.lightType == LightType.Spot)
	{}
}

初始化灯光。

判断灯光照射的区域,是否物体,如果没有则这个灯是无效的。

 if (shadowLight.shadows != LightShadows.None &&cull.GetShadowCasterBounds(i, out shadowBounds))

设置好灯光之后。

把不同的灯光,绘制的map放在不同的位置。
有效的灯光,加入有4个,那么需要将整个rt分为2行2列。

float tileOffsetX = tileIndex % split;
float tileOffsetY = tileIndex / split;
tileViewport.x = tileOffsetX * tileSize;
tileViewport.y = tileOffsetY * tileSize;
if (split > 1)
{
    shadowBuffer.SetViewport(tileViewport);
    shadowBuffer.EnableScissorRect(new Rect(tileViewport.x + 4f, tileViewport.y + 4f,tileSize - 8f, tileSize - 8f));
}

+4的偏移,详见原文。
得到灯光的矩阵:

if (!cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData))
{
    ……
}
shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
shadowBuffer.SetGlobalFloat(shadowBiasId, cull.visibleLights[i].light.shadowBias);
context.ExecuteCommandBuffer(shadowBuffer);
shadowBuffer.Clear();

相关文章:

  • CSS——背景图像区域
  • Tex2DArray的使用举例
  • Linux中查看系统资源占用情况的命令
  • unity中草实现举例
  • MySQL 并发事务问题以及事务的隔离级别
  • 四元数转矩阵
  • Activator.CreateInstance with parameters
  • 再谈DrawMeshInstancedIndirect的参数问题
  • Sitecore 8.2 防火墙规则的权威指南
  • unity烘焙参数的程序化配置
  • 苗条的生成树 Slim Span--洛谷
  • 关于ADB 执行报错问题-db server version (31) doesn't match this client (40); killing...
  • 如何查看srp中的shader文件
  • 项目Beta冲刺(6/7)(追光的人)(2019.5.28)
  • Constant Buffers
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • CentOS6 编译安装 redis-3.2.3
  • CentOS7简单部署NFS
  • ComponentOne 2017 V2版本正式发布
  • css选择器
  •  D - 粉碎叛乱F - 其他起义
  • Golang-长连接-状态推送
  • java多线程
  • Java-详解HashMap
  • magento 货币换算
  • Mysql5.6主从复制
  • PAT A1092
  • PhantomJS 安装
  • Python学习笔记 字符串拼接
  • 机器学习 vs. 深度学习
  • 面试总结JavaScript篇
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 转载:[译] 内容加速黑科技趣谈
  • 《码出高效》学习笔记与书中错误记录
  • 关于Android全面屏虚拟导航栏的适配总结
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #《AI中文版》V3 第 1 章 概述
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (floyd+补集) poj 3275
  • (Java数据结构)ArrayList
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (三) diretfbrc详解
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)Sublime Text3配置Lua运行环境
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET Framework .NET Core与 .NET 的区别