[C] hua →→→→→进入此内容的聊天室

来自 J, 2024-10-18, 写在 C, 查看 89 次. [paste_expire] 1 秒.
URL http://www.code666.cn/view/4a5636f9
  1. #include<stdio.h>
  2. #include<math.h>
  3.  
  4. const int max_iterations = 128;
  5. const float stop_threshold = 0.01f;
  6. const float grad_step = 0.01f;
  7. const float clip_far = 10.0f;
  8.  
  9. const float PI = 3.14159265359f;
  10. const float PI2 = 6.28318530718f;
  11. const float DEG_TO_RAD = PI / 180.0f;
  12.  
  13. typedef struct { float x, y; }vec2;
  14. typedef struct { float x, y,z; }vec3;
  15. typedef struct { float m[9]; }mat3;
  16.  
  17. const vec3 light_pos = { 20.0f,50.0f,20.0f };
  18.  
  19. float min(float a, float b){return a < b ? a : b;}
  20. float max(float a, float b){return a > b ? a : b;}
  21. float clamp(float f, float a, float b) { return max(min(f, b), a); }
  22. vec2 make2(float x, float y) { vec2 r = { x,y }; return r; }
  23. vec2 add2(vec2 a, vec2 b) { vec2 r = { a.x + b.x,a.y + b.y }; return r; }
  24. vec2 sub2(vec2 a, vec2 b) { vec2 r = { a.x - b.x,a.y - b.y }; return r; }
  25. float dot2(vec2 a, vec2 b) { return a.x * b.x + a.y * b.y; }
  26. float length2(vec2 v) { return sqrt(dot2(v, v)); }
  27. vec3 make3(float x, float y, float z) { vec3 r = { x,y,z }; return r; }
  28. vec3 add3(vec3 a, vec3 b) { vec3 r = { a.x + b.x,a.y + b.y,a.z + b.z }; return r; }
  29. vec3 sub3(vec3 a, vec3 b) { vec3 r = { a.x - b.x,a.y - b.y,a.z - b.z }; return r; }
  30. vec3 mul3(vec3 a, vec3 b) { vec3 r = { a.x * b.x,a.y * b.y,a.z * b.z }; return r; }
  31. vec3 scale3(vec3 v, float s) { vec3 r = { v.x * s,v.y * s,v.z * s }; return r; }
  32. float dot3(vec3 a, vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
  33. float length3(vec3 v) { return sqrt(dot3(v, v)); }
  34. vec3 normalize3(vec3 v) { return scale3(v, 1.0f / length3(v)); }
  35. vec3 mul(mat3 m, vec3 v) {
  36.         return make3(
  37.                 m.m[0] * v.x + m.m[3] * v.y + m.m[6] * v.z,
  38.                 m.m[1] * v.x + m.m[4] * v.y + m.m[7] * v.z,
  39.                 m.m[2] * v.x + m.m[5] * v.y + m.m[8] * v.z );
  40. }
  41.  
  42. mat3 rotationXY(float x, float y) {
  43.         vec2 c = { cos(x),cos(y) }, s = { sin(x),sin(y) };
  44.         mat3 m = {
  45.                 c.y   ,0.0f,-s.y,
  46.                 s.y * s.x,c.x,c.y * s.x,
  47.                 s.y * c.x,-s.x,c.y * c.x
  48.         };
  49.         return m;
  50. }
  51.  
  52. float opI(float d1, float d2) { return max(d1, d2); }
  53. float opU(float d1, float d2) { return min(d1, d2); }
  54. float opS(float d1, float d2) { return max(-d1, d2); }
  55.  
  56. float sdPetal(vec3 p, float s) {
  57.         p = add3(mul3(p, make3(0.8f, 1.5f, 0.8f)), make3(0.1f, 0.0f, 0.0f));
  58.         vec2 q = make2(length2(make2(p.x, p.z)), p.y);
  59.  
  60.         float lower = length2(q) - 1.0f;
  61.         lower = opS(length2(q) - 0.97f, lower);
  62.         lower = opI(lower, q.y);
  63.  
  64.         float upper = length2(sub2(q, make2(s, 0.0f))) + 1.0f - s;
  65.         upper = opS(upper, length2(sub2(q, make2(s, 0.0f))) + 0.97f - s);
  66.         upper = opI(upper, -q.y);
  67.         upper = opI(upper, q.x - 2.0f);
  68.  
  69.         float region = length3(sub3(p, make3(1.0f, 0.0f, 0.0f))) - 1.0f;
  70.         return opI(opU(upper, lower), region);
  71. }
  72.  
  73. float map(vec3 p) {
  74.         float d = 1000.0f, s = 2.0f;
  75.         mat3 r = rotationXY(0.1f, PI2 * 0.618034f);
  76.         r.m[0] *= 1.08f; r.m[1] *= 1.08f; r.m[2] *= 1.08f;
  77.         r.m[3] *= 0.995f; r.m[4] *= 0.995f; r.m[5] *= 0.995f;
  78.         r.m[6] *= 1.08f; r.m[7] *= 1.08f; r.m[8] *= 1.08f;
  79.         for (int i = 0; i < 21; i++) {
  80.                 d = opU(d, sdPetal(p, s));
  81.                 p = mul(r, p);
  82.                 p = add3(p, make3(0.0, -0.02, 0.0));
  83.                 s *= 1.05f;
  84.         }
  85.         return d;
  86. }
  87.  
  88. vec3 gradient(vec3 pos) {
  89.         const vec3 dx = { grad_step,0.0,0.0 };
  90.         const vec3 dy = { 0.0,grad_step,0.0 };
  91.         const vec3 dz = { 0.0,0.0,grad_step };
  92.         return normalize3(make3(
  93.                 map(add3(pos, dx)) - map(sub3(pos, dx)),
  94.                 map(add3(pos, dy)) - map(sub3(pos, dy)),
  95.                 map(add3(pos, dz)) - map(sub3(pos, dz))));
  96. }
  97.  
  98. float ray_marching(vec3 origin, vec3 dir, float start, float end) {
  99.         float depth = start;
  100.         for (int i = 0; i < max_iterations; i++) {
  101.                 float dist = map(add3(origin, scale3(dir, depth)));
  102.                 if (dist < stop_threshold)
  103.                         return depth;
  104.                 depth += dist * 0.3;
  105.                 if (depth >= end)
  106.                         return end;
  107.         }
  108.         return end;
  109. }
  110.  
  111. float shading(vec3 v, vec3 n, vec3 eye) {
  112.         vec3 ev = normalize3(sub3(v, eye));
  113.         vec3 vl = normalize3(sub3(light_pos, v));
  114.         float diffuse = dot3(vl, n) * 0.5f + 0.5f;
  115.         vec3 h = normalize3(sub3(vl, ev));
  116.         float rim = pow(1.0f - max(-dot3(n, ev), 0.0f), 2.0f) * 0.15f;
  117.         float ao = clamp(v.y * 0.5f + 0.5f, 0.0f, 1.0f);
  118.         return(diffuse + rim) * ao;
  119. }
  120.  
  121. vec3 ray_dir(float fov, vec2 pos) {
  122.         vec3 r = { pos.x,pos.y,-tan((90.0f - fov * 0.5f) * DEG_TO_RAD) };
  123.         return normalize3(r);
  124. }
  125.        
  126. float f(vec2 fragCoord) {
  127.         vec3 dir = ray_dir(45.0f, fragCoord);
  128.         vec3 eye = { 0.0f,0.0f,4.5f };
  129.         mat3 rot = rotationXY(-1.0f, 1.0f);
  130.  
  131.         dir = mul(rot, dir);
  132.         eye = mul(rot, eye);
  133.  
  134.         float depth = ray_marching(eye, dir, 0.0f, clip_far);
  135.         vec3 pos = add3(eye, scale3(dir, depth));
  136.         if (depth >= clip_far)
  137.                 return 0.0f;
  138.         else
  139.                 return shading(pos, gradient(pos), eye);
  140. }
  141.  
  142. int main() {
  143.         puts("\033[91m");
  144.                 for (int y=0;y<80;y++){
  145.                         for (int x = 0; x < 160; x++)
  146.                                 putchar(".,-:;+=*#@"[(int)(f(make2((x / 160.0f - 0.5f )*2.0f,(y/80.0f-0.5f)*-2.0f))*12.0f)]);
  147.                         putchar('\n');
  148.                 }
  149. }

回复 "hua"

这儿你可以回复上面这条便签

captcha