9 // ////////////////////////////////////////////////////////////////////////// //
10 // raymarch global vars
11 public __gshared
float worldtime
= 0; // seconds
12 public __gshared Vec3 vrp
; // view reference point
13 public __gshared Vec3 vuv
; // view up vector
14 public __gshared Vec3 prp
; // camera position
17 immutable Vec3 eps
= Vec3(0.001f, 0.0f, 0.0f);
18 immutable Vec3 exyy
= eps
.xyy
;
19 immutable Vec3 eyxy
= eps
.yxy
;
20 immutable Vec3 eyyx
= eps
.yyx
;
23 // ////////////////////////////////////////////////////////////////////////// //
24 Vec3
calcNormal() (in auto ref Vec3 pos
) {
26 mapWorld(pos
+exyy
)-mapWorld(pos
-exyy
),
27 mapWorld(pos
+eyxy
)-mapWorld(pos
-eyxy
),
28 mapWorld(pos
+eyyx
)-mapWorld(pos
-eyyx
)
33 float calcAO() (in auto ref Vec3 pos
, in auto ref Vec3 nor
) {
36 for (int i
= 0; i
< 5; ++i
) {
37 float hr
= 0.01f+0.12f*cast(float)i
/4.0f;
38 Vec3 aopos
= nor
*hr
+pos
;
39 float dd = mapWorld(aopos
);
43 return clamp(1.0f-3.0f*occ
, 0.0f, 1.0f);
47 float castRay() (ref int obj
, out float dx
, ref Vec3 ro
, in auto ref Vec3 rd
, float tmin
, float tmax
) {
50 float precis
= 0.002f;
54 for (int i
= 0; i
< 50; ++i
) {
56 float res
= mapWorld(ro
, obj
);
58 if (res
< precis || t
> tmax
) break;
61 if (t
> tmax
) obj
= -1;
66 float shadow() (in auto ref Vec3 ro
, in auto ref Vec3 rd
, float mint
, float tmax
) {
67 import std
.algorithm
: min
;
70 for (int i
= 0; i
< 16; ++i
) {
71 float h
= mapWorld(ro
+rd
*t
);
72 t
+= clamp(h
, 0.02f, 0.10f);
73 if (h
< 0.001f || t
> tmax
) return 0.0f;
79 float softshadow() (in auto ref Vec3 ro
, in auto ref Vec3 rd
, float mint
, float tmax
, float k
=8.0f) {
80 import std
.algorithm
: min
;
83 for (int i
= 0; i
< 16; ++i
) {
84 float h
= mapWorld(ro
+rd
*t
);
85 res
= min(res
, k
*h
/t
);
86 t
+= clamp(h
, 0.02f, 0.10f);
87 if (h
< 0.001f || t
> tmax
) break;
89 return clamp(res
, 0.0f, 1.0f);
93 // ////////////////////////////////////////////////////////////////////////// //
96 public void raymarch() (/*float x, float y,*/ in auto ref Vec3 rd
, in auto ref Vec3 L
, ref Vec3 color
) @nogc {
97 import std
.math
: exp
, pow
;
99 enum maxd
= 100.0f; // max depth
101 //Vec3 col = Vec3(0.7f, 0.9f, 1.0f)+rd.y*0.8;
106 float t
= castRay(obj
, dx
, pos
, rd
, 1.0f, maxd
);
108 // did we hit something?
110 // get primitive color
111 auto col
= getObjColor(pos
, obj
);
113 Vec3 nor
= calcNormal(pos
);
114 Vec3 refl
= rd
.reflect(nor
);
117 float occ
= calcAO(pos
, nor
);
118 //Vec3 lig = Vec3(-0.6f, 0.7f, -0.5f).normalize;
119 Vec3 lig
= L
.normalized
;
120 float amb
= clamp(0.5f+0.5f*nor
.y
, 0.0f, 1.0f);
121 float dif
= clamp(nor
.dot(lig
), 0.0f, 1.0f);
122 float bac
= clamp(nor
.dot(Vec3(-lig
.x
, 0.0f, -lig
.z
).normalize
), 0.0f, 1.0f)*clamp(1.0f-pos
.y
, 0.0f, 1.0f);
123 float dom
= smoothstep(-0.1f, 0.1f, refl
.y
);
124 float fre
= pow(clamp(1.0f+nor
.dot(rd
), 0.0f, 1.0f), 2.0f);
125 float spe
= pow(clamp(refl
.dot(lig
), 0.0f, 1.0f), 16.0f);
127 dif
*= softshadow(pos
, lig
, 0.02f, maxd
);
128 dom
*= softshadow(pos
, refl
, 0.02f, maxd
);
130 Vec3 lin
= Vec3(0.0f, 0.0f, 0.0f);
131 lin
+= Vec3(1.00f, 0.85f, 0.55f)*(1.20f*dif
);
132 lin
+= Vec3(1.00f, 0.85f, 0.55f)*(1.20f*spe
)*dif
;
133 lin
+= Vec3(0.50f, 0.70f, 1.00f)*(0.20f*amb
)*occ
;
134 lin
+= Vec3(0.50f, 0.70f, 1.00f)*(0.30f*dom
)*occ
;
135 lin
+= Vec3(0.25f, 0.25f, 0.25f)*(0.30f*bac
)*occ
;
136 lin
+= Vec3(1.00f, 1.00f, 1.00f)*(0.40f*fre
)*occ
;
138 col
= mix(col
, Vec3(0.8f, 0.9f, 1.0f), 1.0f-exp(-0.002f*t
*t
));
142 color
= Vec3(0.7f, 0.9f, 1.0f)+rd
.y
*0.8f;