raymarching

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

 

 

 
posted on 2018-07-03 16:59  minggoddess  阅读(462)  评论(0编辑  收藏  举报