vertex shader:
in vec3 position;
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 cameraPos;
out vec3 vOrigin;
out vec3 vDirectivertex shader:on;
void main() {
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
vOrigin = vec3(inverse(modelMatrix) * vec4(cameraPos, 1.0)).xyz;
vDirection = position - vOrigin;
gl_Position = projectionMatrix * mvPosition;
}
fragment shader:
precision highp float;
precision highp sampler3D;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
in vec3 vOrigin;
in vec3 vDirection;
out vec4 color;
uniform sampler3D map;
uniform float threshold;
uniform float steps;
vec2 hitBox(vec3 orig, vec3 dir) {
const vec3 box_min = vec3(-0.5);
const vec3 box_max = vec3(0.5);
vec3 inv_dir = 1.0 / dir;
vec3 tmin_tmp = (box_min - orig) * inv_dir;
vec3 tmax_tmp = (box_max - orig) * inv_dir;
vec3 tmin = min(tmin_tmp, tmax_tmp);
vec3 tmax = max(tmin_tmp, tmax_tmp);
float t0 = max(tmin.x, max(tmin.y, tmin.z));
float t1 = min(tmax.x, min(tmax.y, tmax.z));
return vec2(t0, t1);
}
float sample1(vec3 p) {
return texture(map, p).r;
}
#define epsilon .0001
vec3 normal(vec3 coord) {
if(coord.x < epsilon)
return vec3(1.0, 0.0, 0.0);
if(coord.y < epsilon)
return vec3(0.0, 1.0, 0.0);
if(coord.z < epsilon)
return vec3(0.0, 0.0, 1.0);
if(coord.x > 1.0 - epsilon)
return vec3(-1.0, 0.0, 0.0);
if(coord.y > 1.0 - epsilon)
return vec3(0.0, -1.0, 0.0);
if(coord.z > 1.0 - epsilon)
return vec3(0.0, 0.0, -1.0);
float step = 0.01;
float x = sample1(coord + vec3(-step, 0.0, 0.0)) - sample1(coord + vec3(step, 0.0, 0.0));
float y = sample1(coord + vec3(0.0, -step, 0.0)) - sample1(coord + vec3(0.0, step, 0.0));
float z = sample1(coord + vec3(0.0, 0.0, -step)) - sample1(coord + vec3(0.0, 0.0, step));
return normalize(vec3(x, y, z));
}
void main() {
vec3 rayDir = normalize(vDirection);
vec2 bounds = hitBox(vOrigin, rayDir);
if(bounds.x > bounds.y)
discard;
bounds.x = max(bounds.x, 0.0);
vec3 p = vOrigin + bounds.x * rayDir;
vec3 inc = 1.0 / abs(rayDir);
float delta = min(inc.x, min(inc.y, inc.z));
delta /= steps;
for(float t = bounds.x; t < bounds.y; t += delta) {
float d = sample1(p + 0.5);
if(d > threshold) {
color.rgb = normal(p + 0.5) * 0.5 + (p * 1.5 + 0.25);
color.a = 1.;
break;
}
p += rayDir * delta;
}
if(color.a == 0.0)
discard;
}
I’m using raymaching to intersect with a box. How can I bend the box to a spherical cube like below?