# Begin ray marching in unreal engine 4【第二卷:开始加入光照】
先看下我们加的简单光照吧(左边是我们ray marching出来的,用的简单的兰伯特光照,右边是引擎的PBR的)
![img](raymarchinginunreal_2.assets/v2-fbf805ada1a630e1ccd583f5af011631_hd.jpg)
当然也可以加入多盏灯光
![img](raymarchinginunreal_2.assets/v2-04c7abfbf7397fda0a88eb552c453424_b.jpg)
首先我们先拿出我们的代码框架
```text
//距离场元素
float sphere(float3 p, float3 c, float r)
{
}
float cube( float3 p, float3 b, float r )
{
}
//------------------------------------------------------------------
//对距离场进行并集或者非交集运算
float opS(float d1, float d2)
{
}
float opU(float d1, float d2)
{
}
//------------------------------------------------------------------
//构建距离度场
float scene(float3 rp)
{
}
//------------------------------------------------------------------
//计算法线
float3 normal(float3 ro)
{
}
//------------------------------------------------------------------
//raymarching函数
float4 raymarching(float3 ro, float3 rd)
{
}
//主函数
float4 MainImage(float3 ro, float3 rd, 其他需要传入的参数)
{
//这里会进行光照计算等
}
```
在上一节代码的基础上,我们把render函数改为raymarching函数。ray marching函数只负责找到hit的位置。
下面的问题就是如何找到法线了。
```text
float3 normal(float3 ro)
{
float2 eps = float2(0.002,0.0);
return normalize(float3(
scene(ro + eps.xyy) - scene(ro - eps.xyy),
scene(ro + eps.yxy) - scene(ro - eps.yxy),
scene(ro + eps.yyx) - scene(ro - eps.yyx)
));
}
```
在普通的模型渲染中,模型顶点数据中有法线信息,然后经过法线贴图映射来扰动表面我们再用uv去采,就可以拿到法线。ray marching中因为没用顶点法线信息,所以我们只有通过梯度的概念拿到法线。我们先找到x方向上梯度衰减最快的方向
![img](raymarchinginunreal_2.assets/v2-3a33f1149f3012231a3ae4a320e7d15a_hd.jpg)
同理Y轴上
![img](raymarchinginunreal_2.assets/v2-5793cbc1882971ad8623abdc51d5ee30_hd.jpg)
Z轴也是这个道理,然后三个轴合在一起就是我们的法线了
![img](raymarchinginunreal_2.assets/v2-065d5d5c284ad035241b3aba386e3a39_hd.jpg)
然后我们就可以算光照啦。下一节我们再来加入一些其他东西。现在的光照模型还是太简单了,后面一点一点把它变复杂。
如果你已经迫不及待想看看自己ray marching的PBR效果,可以考虑直接让虚幻来帮你算,因为现在我们已经有法线了呀!
![img](raymarchinginunreal_2.assets/v2-230ae8ba45f5172275e528d85c3e43d2_b.jpg)
![img](raymarchinginunreal_2.assets/v2-7407177d9f8e38d0dac46a94c831551d_b.jpg)
Enjoy it!!!