投影纹理和衰减

我很了解投影纹理如何工作。 我成功实现了以下nvidia文档的着色器

我所面临的主要问题是,在这种实现方式下,投影机的平截头体仅用于确定投影空间中的纹理坐标,但是它并不夹在投影平截体体积之外的任何东西。

换句话说,如果我有一台投影机指向一个物体,即使物体在其平截头体之外,纹理也将被投射在它上面。 此外,当投影机几乎与投影物体平行时,纹理拉伸太明显,我想淡化它。

现在,我想了解Unity如何处理内置的投影机 。 我发现这个例子 。 这是顶点和片段的相关代码:

 v2f vert (float4 vertex : POSITION) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, vertex); o.uvShadow = mul (_Projector, vertex); o.uvFalloff = mul (_ProjectorClip, vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow)); texS.rgb *= _Color.rgb; texS.a = 1.0-texS.a; fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff)); fixed4 res = texS * texF.a; return res; } 

我认为_Projectormatrix是将顶点坐标转换成投影机空间的经典matrix。 (实际上片段只是使用变换后的坐标来对投影纹理进行采样)。

我真的缺less的是如何构建_ProjectionClipmatrix。 转换后的顶点坐标用于采样衰减纹理(我认为这是我真正需要的)。

有谁知道_ProjectionClip是如何构建的? 或者如何达到类似的效果?

注意:我在计算聚光灯衰减时做了类似的工作,但是在顶点着色器中使用单个matrix乘法将顶点转换为光空间,在片段着色器中使用平方距离计算纹理坐标以查找衰减纹理。

为了裁剪视锥体之外的像素,可以使用启用了边框模式和黑色边框的纹理。 (或直接在纹理中创建一个黑色的1像素边框)。 或者,在添加混合通道中,如果UV位于单位正方形之外,则可以向着色器添加代码以discard像素。

当投影物体接近平行时,为了使投影退色,普通照明N·L因素将主要考虑到这一点。 你可以通过稍稍偏置N·L因子来使事情变得更快。

就Unity着色器而言,我的猜测是,它只是让你对主纹理和衰减纹理有不同的比例。 例如,主要纹理可能是一些图像,衰减纹理可能是一个白色的圆形,渐变成黑色背景,与主要纹理相乘,并限制它只出现在该圆形中。 用户可以独立调整两个纹理的沮丧感。

换句话说, _ProjectionClipmatrix只是另一个经典的投影matrix,可能用不同的参数构建。 它不会奇迹般地夹住任何东西; 只是一些因素的组合将光色减less到所需的平截头体以外的零。