shadertoy上的第一篇关于ray marching的教程,实现了在屏幕上绘制一个3D球体
float minDist=0.0;
float maxDist=100.0;
float getDist(vec3 cameraOrign , vec3 dir ){
float depth=minDist;
for(int i =0;i<255;i+=1){
vec3 rayPosition=cameraOrign+depth*dir;
float sphereSDF=1.0;
float dist=length(rayPosition)-1.0;
if(dist<0.01){
return depth;
}
depth+=dist;
if(depth>=maxDist){
return maxDist;
}
}
return maxDist;
}
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( 0,0 , 5);
float dist=getDist(cameraOrign,rayDir);
if(dist>maxDist-0.001){
fragColor=vec4(0.0,0.0,0.0,1.0);
return;
}
vec3 p = cameraOrign + dist * rayDir;
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(
length(vec3(p.x + EPSILON, p.y, p.z)) - length(vec3(p.x - EPSILON, p.y, p.z)),
length(vec3(p.x, p.y + EPSILON, p.z)) - length(vec3(p.x, p.y - EPSILON, p.z)),
length(vec3(p.x, p.y, p.z + EPSILON)) - length(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);
}