SRP中的光照

news/2025/2/11 5:31:25/

SRP中的光照

在SRP中,首先我们需要使用CBUFFER来存储光照相关的信息:

CBUFFER_START(_LightBuffer)float4 _VisibleLightColors[MAX_VISIBLE_LIGHTS];float4 _VisibleLightDirections[MAX_VISIBLE_LIGHTS];
CBUFFER_END

当然,这些数据是从C#中塞过去的,首先需要在C#中定义shader中用到的cbuffer属性,以及存放对应数据的数组:

static int visibleLightColorsId =Shader.PropertyToID("_VisibleLightColors");
static int visibleLightDirectionsId =Shader.PropertyToID("_VisibleLightDirections");Vector4[] visibleLightColors = new Vector4[maxVisibleLights];
Vector4[] visibleLightDirections = new Vector4[maxVisibleLights];

CommandBuffer类中提供了传递数据的接口:

cameraBuffer.SetGlobalVectorArray(visibleLightColorsId, visibleLightColors
);
cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsId, visibleLightDirections
);

light相关的数据可以从CullingResults中获取:

for (int i = 0; i < cull.visibleLights.Count; i++) {VisibleLight light = cull.visibleLights[i];visibleLightColors[i] = light.finalColor;Vector4 v = light.localToWorld.GetColumn(2);v.x = -v.x;v.y = -v.y;v.z = -v.z;visibleLightDirections[i] = v;
}

对于平行光来说,它的光照方向取决于它的local z轴的方向,因此我们只要取出这个向量即可,由于Unity的向量是列向量,所以矩阵的第2列(下标从0开始)就是这个local z轴。

SRP中的光照1

SRP中的光照2

对于点光源来说,它并不存在某一个具体的光照方向,而是需要具体的位置信息。因此,在C#层需要对数据结构稍微修改:

static int visibleLightDirectionsOrPositionsId =Shader.PropertyToID("_VisibleLightDirectionsOrPositions");Vector4[] visibleLightDirectionsOrPositions = new Vector4[maxVisibleLights];

传递数据的地方也要修改:

cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsOrPositionsId, visibleLightDirectionsOrPositions
);

在塞数据的时候,需要对光源的类型进行区分:

if (light.lightType == LightType.Directional) 
{Vector4 v = light.localToWorld.GetColumn(2);v.x = -v.x;v.y = -v.y;v.z = -v.z;visibleLightDirectionsOrPositions[i] = v;
}
else 
{visibleLightDirectionsOrPositions[i] =light.localToWorld.GetColumn(3);
}

也很好理解,点光源的位置保存在矩阵的最后一列中。

同样地,在shader中也要对CBUFFER里的定义进行修改:

CBUFFER_START(_LightBuffer)float4 _VisibleLightColors[MAX_VISIBLE_LIGHTS];float4 _VisibleLightDirectionsOrPositions[MAX_VISIBLE_LIGHTS];
CBUFFER_END

那么,shader中要如何区分平行光源和点光源呢?平行光源传入的是向量,用float4来表示,最后一位分量w是0,而点光源传入的是位置,用float4表示的话最后一位分量w是1。在计算光源方向时,可以统一用下面一行代码计算:

float3 lightVector = lightPositionOrDirection.xyz - worldPos * lightPositionOrDirection.w;

点光源的range信息也可以从VisibleLight数据结构中获取:

attenuation.x = 1f /Mathf.Max(light.range * light.range, 0.00001f);

然后我们就可以传到shader中,去实现我们自定义的衰减逻辑了:

float rangeFade = dot(lightVector, lightVector) * lightAttenuation.x;
rangeFade = saturate(1.0 - rangeFade * rangeFade);
rangeFade *= rangeFade;float distanceSqr = max(dot(lightVector, lightVector), 0.00001);
diffuse *= rangeFade / distanceSqr;

SRP中的光照3

最后是聚光灯,它更复杂一些,既需要方向信息,也需要位置信息。除此之外,它还有个能被照亮的最大角度,超出该角度范围里的物体是不会被照亮的,这个衰减是过渡的,我们假设聚光灯方向与聚光灯到物体的方向夹角为 θ \theta θ,聚光灯开始衰减的角度为 θ 0 \theta_0 θ0,彻底衰减时的角度为 θ 1 \theta_1 θ1,那么衰减如下计算:
F = c o s θ − c o s θ 1 c o s θ 0 − c o s θ 1 F = \dfrac{cos\theta - cos\theta_1}{cos\theta_0 - cos\theta_1} F=cosθ0cosθ1cosθcosθ1
c o s θ cos\theta cosθ的值是在shader中计算的,其余部分是常量,可以在C#层预先计算好传进去:

float outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
float outerCos = Mathf.Cos(outerRad);
float outerTan = Mathf.Tan(outerRad);
float innerCos =Mathf.Cos(Mathf.Atan(((46f / 64f) * outerTan)));
float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
attenuation.z = 1f / angleRange;
attenuation.w = -outerCos * attenuation.z;

SRP中的光照4

如果你觉得我的文章有帮助,欢迎关注我的微信公众号 我是真的想做游戏啊

Reference
[1] Lights


http://www.ppmy.cn/news/186054.html

相关文章

服务器硬件防火墙和软件防火墙的功能和区别

随着近年来对网络数据安全的要求越来越高&#xff0c;许多第一次使用服务器的客户经常问我们:你的机房有防火墙吗&#xff1f;我们还需要重新部署和安装防火墙吗&#xff1f;有服务器硬件防火墙吗&#xff1f;事实上&#xff0c;普通机房配备了硬件防火墙。为了更大程度地保证数…

WatchGuard Firebox X50硬件防火墙

报价48900. 至于价格高&#xff0c;原因在于&#xff0c;软件防火墙只有包过滤的功能&#xff0c;硬件防火墙中可能还有除软件防火墙以外的其他功能&#xff0c;例如CF&#xff08;内容过滤&#xff09;IDS&#xff08;入侵侦测&#xff09;IPS&#xff08;入侵防护&#xff0…

害死人的ddos,价格屠夫安易ES系列抗DDOS硬件防火墙

安易网址&#xff1a; www.ezsafe.cn 联系人&#xff1a; 杨柳庭联系电话&#xff1a;0668-2990666 安易&#xff08;www.ezsafe.cn )硬件防火墙可彻底防御各种DDoS攻击,保证网络稳定运行,安易信息技术公司成功为国内外大中型IDC用户提供抗DDOS安全产品及打包安全解决方案,销售…

服务器硬件防火墙与软件防火墙的作用和区别

随着近几年网络数据安全的要求越来越高&#xff0c;很多初次使用服务器的客户经常问我们&#xff1a;你们的机房有防火墙吗?我们还需要再部署和安装防火墙吗&#xff1f;有没有服务器硬件防火墙&#xff1f;其实一般的机房都是有部署硬件防火墙的。而为了更大程度上保障数据安…

选择硬件防火墙应注意的几点事宜

摘要&#xff1a;防火墙可以对关键网络任务进行管理。在选择基于硬件的防火墙解决方案时&#xff0c;要考虑到公司的需求和预算情况&#xff0c;确定是否应该由防火墙管理内容过滤功能。选择硬件防火墙应注意几点事宜。下面本文就来为大家阐述 防火墙对于公司网络安全来说&am…

防火墙概述

#一、防火墙概述* **1-1 **防火墙概念 区域划分&#xff1a; 1.公共外部网络&#xff0c;如 Internet 2.内联网&#xff08;Intranet&#xff09;&#xff0c;如某公司或组织专用网络&#xff0c;网络访问限制在组织内部 3.外联网&#xff08;Exranet&#xff09;&#xff0…

孤军大作战!疯狂DIY 1U硬件防火墙实录(转)

硬件防火墙是指把防火墙程序做到芯片里面&#xff0c;由硬件执行这些功能&#xff0c;能减少CPU的负担&#xff0c;使路由更稳定。硬件防火墙是保障内部网络安全的一道重要屏障。它的安全和稳定&#xff0c;直接关系到整个内部网络的安全。目前市场上的防火墙种类繁多&#xff…

硬件防火墙选购指南

防火墙是用于防止网络环境中非法访问的安全设备&#xff0c;其基本工作原理是对各种类型的恶意访问进行筛选和过滤。防火墙产品可以通过软件、硬件或二者相结合的方式来实现&#xff0c;通常硬件防火墙的性能要强于软件防火墙&#xff0c;并且连接、使用比较方便&#xff0c;而…