Files
konabot/konabot/plugins/marchtoy/shaders/raymarch.sksl
alcoholicgirl 81e0c05686 文件夹结构
2026-04-25 01:59:29 +08:00

74 lines
1.8 KiB
Plaintext

uniform float2 u_resolution;
const float EPS = 0.001;
const int MAX_ITER = 64;
struct sdQuery {
float value;
int obj_id;
};
float sdCube(float3 p, float3 b) {
p = abs(p) - b;
return length(max(p, 0.0)) + min(max(p.x, max(p.y, p.z)), 0.0);
}
float sdSphere(float3 p, float r) {
return length(p) - r;
}
sdQuery sd(float3 p) {
sdQuery qry;
qry.value = 100000000.0;
qry.obj_id = -1;
<SDF_BLOCK>
return qry;
}
float3 nrm(float3 p) {
float2 d = float2(EPS, 0.0);
return normalize(float3(
sd(p + d.xyy).value - sd(p - d.xyy).value,
sd(p + d.yxy).value - sd(p - d.yxy).value,
sd(p + d.yyx).value - sd(p - d.yyx).value
));
}
float4 materialColor(int obj_id) {
<COLOR_BLOCK>
return float4(1.0);
}
float4 color(float3 p, int obj_id) {
float3 normal = nrm(p);
float3 light_dir = normalize(float3(0.5, 0.8, -0.6));
float light = 0.2 + 0.8 * max(dot(normal, light_dir), 0.0);
float4 base = materialColor(obj_id);
return float4(base.rgb * light, base.a);
}
float4 march(float3 p, float3 r) {
sdQuery qry;
float4 col = float4(0.0);
for(int i = 0; i < MAX_ITER; ++i) {
qry = sd(p);
if(qry.value < EPS){
col = color(p, qry.obj_id);
break;
}
p += qry.value * r;
}
return col;
}
half4 main(float2 fragCoord) {
float2 uv = -2. * (fragCoord / u_resolution - .5) * float2(u_resolution.x / u_resolution.y, 1.);
float3 c_p = float3(<CAM_POS>);
float3 c_z = normalize(float3(<CAM_DIR>));
float3 world_up = abs(c_z.y) > 0.999 ? float3(0., 0., 1.) : float3(0., 1., 0.);
float3 c_x = normalize(cross(c_z, world_up));
float3 c_y = normalize(cross(c_x, c_z));
float3x3 view = float3x3(c_x, c_y, c_z);
float3 r = normalize(float3(uv, <CAM_FOCUS>));
return half4(march(c_p, view * r));
}