ray marching shader 2:viewspace 转换 worldspace

shadertoy上的第二个关于ray marching的教程

关于viewspace 转 worldspace 的推导:http://blog.csdn.net/silangquan/article/details/50987196

float minDist=0.0;
float maxDist=100.0;


/**
 * Signed distance function for a cube centered at the origin
 * with width = height = length = 2.0
 */
float cubeSDF(vec3 p) {
    // If d.x < 0, then -1 < p.x < 1, and same logic applies to p.y, p.z
    // So if all components of d are negative, then p is inside the unit cube
    vec3 d = abs(p) - vec3(1.0, 1.0, 1.0);
    
    // Assuming p is inside the cube, how far is it from the surface?
    // Result will be negative or zero.
    float insideDistance = min(max(d.x, max(d.y, d.z)), 0.0);
    
    // Assuming p is outside the cube, how far is it from the surface?
    // Result will be positive or zero.
    float outsideDistance = length(max(d, 0.0));
    
    return insideDistance + outsideDistance;
}


float getDist(vec3 cameraOrign , vec3 dir ){
    
   float depth=minDist; 
   
   for(int i =0;i<255;i+=1){
     vec3 rayPosition=cameraOrign+depth*dir;
     
     
     float dist=cubeSDF(rayPosition);
     
     if(dist<0.01){
      return depth; 
        
     }
       
     depth+=dist;
 		
     if(depth>=maxDist){
       return maxDist;
     
     }
       
   }
    return maxDist;
    
}

/**
 * Return a transform matrix that will transform a ray from view space
 * to world coordinates, given the eye point, the camera target, and an up vector.
 *
 * This assumes that the center of the camera is aligned with the negative z axis in
 * view space when calculating the ray marching direction. See rayDirection.
 */
mat4 viewMatrix(vec3 eye, vec3 center, vec3 up) {
    // Based on gluLookAt man page
    vec3 f = normalize(center - eye);
    vec3 s = normalize(cross(f, up));
    vec3 u = cross(s, f);
    return mat4(
        vec4(s, 0.0),
        vec4(u, 0.0),
        vec4(-f, 0.0),
        vec4(0.0, 0.0, 0.0, 1)
    );
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 size=	iResolution.xy;
   
    
    vec2 rayMarchXY=fragCoord-size/2.;
    
    float fieldOfView=45.0;

    float z = size.y / tan(radians(fieldOfView) / 2.0);
    
    vec3 rayDir=normalize( vec3(rayMarchXY,-z) );
    
 
    
    vec3 cameraOrign=vec3( -8,5 , 20);
    mat4 viewToWorld = viewMatrix(cameraOrign, vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0));
    vec3 worldDir = (viewToWorld * vec4(rayDir, 0.0)).xyz;
    
    
    float dist=getDist(cameraOrign,worldDir);  
 
    if(dist>maxDist-0.001){
    fragColor=vec4(0.0,0.0,0.0,1.0);
    return;
    }
    
    vec3 p = cameraOrign + dist * worldDir;
    vec3 K_a = vec3(0.2, 0.2, 0.2);
    vec3 K_d = vec3(0.7, 0.2, 0.2);
    vec3 K_s = vec3(1.0, 1.0, 1.0);
    float shininess = 10.0;
    
    
    
    vec3 color = vec3 (0.25,0.25,0.25);
    
    vec3 light1Pos = vec3(4.0 * sin(iGlobalTime),
                          2.0,
                          4.0 * cos(iGlobalTime));
    
    float EPSILON=0.001;
    vec3 N = normalize(vec3(
        cubeSDF(vec3(p.x + EPSILON, p.y, p.z)) - cubeSDF(vec3(p.x - EPSILON, p.y, p.z)),
        cubeSDF(vec3(p.x, p.y + EPSILON, p.z)) - cubeSDF(vec3(p.x, p.y - EPSILON, p.z)),
        cubeSDF(vec3(p.x, p.y, p.z  + EPSILON)) - cubeSDF(vec3(p.x, p.y, p.z - EPSILON))
    ));
    vec3 L = normalize(light1Pos - p);
    
    float dotLN = dot(L, N);
    
    if (dotLN < 0.0) {
        color+= vec3(0.0, 0.0, 0.0);
    } 
    
   
    color+= vec3( dotLN,dotLN,dotLN);
 
    
    fragColor = vec4(color, 1.0);
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值