文章目录
自学Raymarching汇总: Unity Shader - Ray Marching Study Summary - 学习汇总
前一篇得到了表面的法线后,那么光照着色就不成问题了。
核心代码
...
float4 _LightInfo; // 点光源信息:.xyz = pos, .w = 1/range
...
fixed4 getColor(v2f i) {
float3 ori = i.ray; // 射线起点
float3 dir = normalize(i.ray); // 射线方向
float3 pos; // 当前步进到的位置
float dist; // 当前步进到的最近距离
float d; // 当前最近距离
float far = _ProjectionParams.z; // far
ori += _WorldSpaceCameraPos.xyz; // 偏移,加上相机位置
pos = ori; // 从起点出发
float3 lightPos = _LightInfo.xyz; // 灯光位置
float lightRange = _LightInfo.w; // 灯光范围
float rangeEnable = step(EPSILON, lightRange);
UNITY_LOOP
for (int it = 0; it < MAX_STEP_TIMES; it++) {
d = sceneDF(pos); // 获取当前几何体集合中最近的距离
dist += d; // 调整当前步进到的最近距离
pos = ori + dir * dist; // 调整当前的步进位置
if (d < EPSILON) { // 有碰撞
float3 p2l = lightPos - pos; // 碰撞点指向光源向量
float distWithL = length(p2l); // 与灯光距离
float atten = rangeEnable * 1 - clamp(distWithL * lightRange, 0, 1); // 灯光衰减
float3 l = normalize(p2l); // 灯光方向
float3 n = getNormal(pos); // 法线方向
float NdotL = max(0, dot(n, l)); // 漫反射,diffuse
return NdotL * atten;
}
if (dist > far) {
return 0;
}
}
return 0;
}
运行效果
Project
backup : T4_LightingSurface