【TA】假透光效果灯具

项目中经常用绘制Emission图来模仿灯光开灯后灯具透光的效果,但是部分透光效果(例如无论视角怎么转换始终在中心亮起)还是需要材质辅助才能实现。

本文为原创内容,转载请注明地址。

效果

img

原理

原理是,在视线空间中建立以物体朝向相机那一面为投影屏幕的垂直面,实时根据视角方向移动这一个投影面。再根据距离计算光照衰减,就可以做到无论怎么移动,都是中心亮起这一效果。

部分实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//获取模型空间下的相机坐标,也是视线方向
float3 newView = TransformWorldToObject(GetCameraPositionWS());
//normalize作为模型空间下的z轴方向// //
newView.y = 0;
// newView.y *=-1;
newView = -normalize(newView);

float x0 = dot((input.positionOS-_CenterOffest.xyz),newView);

float3 H = input.positionOS-_CenterOffest.xyz + x0*newView;
float3 newY = float3(0,1,0);
float3 newX = cross(newView,float3(0,1,0));


float newXPos = dot(newX,H);
float newYPos = dot(newY,H);

output.LightPos = float2(newXPos,newYPos);

如果需要中心的形状呈现贴图定制的样式,只需要把距离映射成UV值就好

1
2
3
float2 Oriuv = input.LightPos-_CenterOffest.xy;
float2 fakeUV = saturate((float2(0.5,0.5)+Oriuv*_FakeLightScale));
float3 fakeLightTex = SAMPLE_TEXTURE2D(_FakeLightTex, sampler_FakeLightTex, fakeUV);

扩展

实现了这个效果后的某天,在水知乎的时候发现了这篇文章:

如何在shader中找到一个平面用作UVcoordinates - 耶酱的文章 - 知乎 https://zhuanlan.zhihu.com/p/657240611

卧槽,原来实现的东西是UE自带的功能,不得不感叹UE的强大……