http://www.michaelwalczyk.com/blog/2017/5/25/ray-marching
https://kosmonautblog.wordpress.com/2017/05/01/signed-distance-field-rendering-journey-pt-1/
http://martindevans.me/game-development/2016/12/27/Dual-Contouring-In-2D/
https://static1.squarespace.com/static/559921a3e4b02c1d7480f8f4/t/596773e9f7e0ab3d29bb102f/1499952110561/Mroz+Michael_746.pdf
这篇硕士论文比较详细 很难找
sdf是个函数 input 是一个point output是离这个点最近的任意表面的距离 如果在surface内部是负数
存在3dtexture里面
raymarching distance field是个后处理
要了解sdf需要几个依赖
1.sdf func 下面是个球的例子
// params:
// p: arbitrary point in 3D space
// c: the center of our sphere
// r: the radius of our sphere
float distance_from_sphere(in vec3 p, in vec3 c, float r)
{
return length(p - c) - r;
}
2.ray marching(sphere tracing)
view 到 light 直线上 按照起始点(view)为圆心 起始点存的distance值为半径做圆 同样的方式迭代一直到到达light 如果能到达的话(也就是说空间的任何一个点都存有distance了)
3.mesh distance field 如何得到 用1里面的基本图元合起来的 合的方式也是各种各样
下面这个是暴力算法
Foreach GridCell in DistanceFieldGrid:
Foreach Triangle in Mesh:
Find distance from Triangle to GridCell, save the closest one
(从上面这段也可以推知场景空间每个cell都存了距离)
ue4是这个算法用cpu 可以用kd-tree优化
也可以用gpu computeshader来算 mTec
心情真的很不好呢
http://flafla2.github.io/2016/10/01/raymarching.html
===============================================================
fixed4 raymarch(float3 ro, float3 rd) {
fixed4 ret = fixed4(0,0,0,0);
const int maxstep = 64;
float t = 0; // current distance traveled along ray
for (int i = 0; i < maxstep; ++i) {
float3 p = ro + rd * t; // World space position of sample
float d = map(p); // Sample of distance field (see map())
// If the sample <= 0, we have hit something (see map()).
if (d < 0.001) {
// Lambertian Lighting
float3 n = calcNormal(p);
ret = fixed4(dot(-_LightDir.xyz, n).rrr, 1);
break;
}
// If the sample > 0, we haven't hit anything yet so we should march forward
// We step forward by distance d, because d is the minimum distance possible to intersect
// an object (see map()).
t += d;
}
return ret;
}
fixed4 frag (v2f i) : SV_Target
{
// ray direction
float3 rd = normalize(i.ray.xyz);
// ray origin (camera position)
float3 ro = _CameraWS;
fixed3 col = tex2D(_MainTex,i.uv); // Color of the scene before this shader was run
fixed4 add = raymarch(ro, rd);
// Returns final color using alpha blending
return fixed4(col*(1.0 - add.w) + add.xyz * add.w,1.0);
}
做光照的
{
for (int i = 0; i<maxSteps; i++)
{
float S = GetSdfDistNoSun(P,radius,cullIndex);
//float S = combinedSDFNoSun(P);
closestPass = min(closestPass, (multiplier*S / radius));
//radius+=S;
// radius+= max( S, 0.02);
radius += clamp(S, 0.02, 0.1);
dist += max(minS, S);
P += d*max(minS, S);
steps = i;
if (dist >= lightDist || dist>maxDist ) {
break;
}
if(S < cutoff)
{
closestPass =0.0;
break;
}
}
}
return clamp(closestPass, 0, 1);
}
==
softshadow的 迭代多次lightmarch的距离dist 如果能到达light 不形成阴影
如果大于maxDist也不形成阴影意思是当前点50以外到light方向都无遮挡也不形成阴影
sdf<cutoff 内部不形成阴影
soft这部分用这个min(closestPass, (multiplier*S / radius))
=================================================================
ao