Skip to content

Instantly share code, notes, and snippets.

@domitry

domitry/quest.glsl

Created Apr 12, 2015
Embed
What would you like to do?
#ifdef GL_ES
precision highp float;
#endif
//---------------------------------------------------------
// MACROS
//---------------------------------------------------------
#define EPS 0.0001
#define ROOTTHREE 1.73205081
#define EQUALS(A,B) ( length((abs(A))-(abs(B))) < EPS )
#define EQUALSZERO(A) ( (length(abs(A))<EPS) )
//---------------------------------------------------------
// CONSTANTS
//---------------------------------------------------------
// 32 48 64 96 128
#define MAX_STEPS 128
//---------------------------------------------------------
// SHADER VARS
//---------------------------------------------------------
varying vec2 vUv;
varying vec3 vPos0; // position in world coords
varying vec3 vPos1; // position in object coords
varying vec3 vPos1n; // normalized 0 to 1, for texture lookup
// Categorized texture
uniform sampler2D uTex;
uniform vec3 uTexDim;
uniform float fPerRow;
uniform float fPerColumn;
// Float Texture
uniform sampler2D fuTex;
uniform vec3 fuTexDim;
uniform float ffPerRow;
uniform float ffPerColumn;
uniform vec3 uCamPos;
uniform int frame;
uniform vec4 displayColor;
float gStepSize;
vec3 toLocal(vec3 p) {
return p + vec3(0.5);
}
vec4 getPos(vec3 pos, vec3 dim, float per_r, float per_c, float zSlice){
float x0 = mod(floor(zSlice), per_r)*dim.x +
pos.x*(dim.x-1.0) +
0.5;
float y0 = floor(floor(zSlice)/per_r)*dim.y +
pos.z*(dim.y-1.0) +
0.5;
float width = dim.x*per_r;
float height = dim.y*per_c;
float uni_x0 = min(x0/width, 1.0);
float uni_y0 = min(y0/height, 1.0);
float uni_x1;
float uni_y1;
if(mod(floor(zSlice)+1.0, per_r) == 0.0){
uni_x1 = min((pos.x*(dim.x-1.0) + 0.5)/width, 1.0);
uni_y1 = min((y0 + dim.y)/height, 1.0);
}else{
uni_x1 = min((x0 + dim.x)/width, 1.0);
uni_y1 = uni_y0;
}
return vec4(uni_x0, uni_y0, uni_x1, uni_y1);
}
vec4 sampleCategorized(vec3 pos){
float zSlice = (1.0-pos.y)*(uTexDim.z-1.0);
vec4 tex_pos = getPos(pos, uTexDim, fPerRow, fPerColumn, zSlice);
vec4 z0 = texture2D(uTex, tex_pos.xy);
vec4 z1 = texture2D(uTex, tex_pos.zw);
return mix(z0, z1, fract(zSlice));
}
float sampleVolTex(vec3 pos) {
float zSlice = (1.0-pos.y)*(fuTexDim.z-1.0);
vec4 tex_pos = getPos(pos, fuTexDim, ffPerRow, ffPerColumn, zSlice);
float z0 = texture2D(fuTex, tex_pos.xy).a;
float z1 = texture2D(fuTex, tex_pos.zw).a;
return mix(z0, z1, fract(zSlice));
}
vec4 raymarchTransparent(vec3 ro, vec3 rd){
vec3 step = rd*gStepSize;
vec4 prevColor = sampleCategorized(ro);
vec3 pos = ro + step;
vec4 col = vec4(0.0);
for (int i=0; i<MAX_STEPS; ++i) {
vec4 volColor = sampleCategorized(pos);
if((!EQUALSZERO(volColor.rbg) && EQUALSZERO(prevColor.rbg)) ||
(EQUALSZERO(volColor.rbg) && !EQUALSZERO(prevColor.rbg)))
col += vec4(0.2);
if((length(abs(displayColor - volColor)) < 0.013)){
if((length(abs(sampleVolTex(pos))) - 0.1 < 100.0)){
return vec4(1.0, 0.0, 0.0, 1.0);
}
}
pos += step;
prevColor = volColor;
if (pos.x > 1.0 || pos.x < 0.0 ||
pos.y > 1.0 || pos.y < 0.0 ||
pos.z > 1.0 || pos.z < 0.0)
break;
}
return col;
}
void main() {
vec3 ro = vPos1n;
vec3 rd = normalize( ro - toLocal(uCamPos) );
gStepSize = ROOTTHREE / float(MAX_STEPS);
if(
frame == 1 &&
(abs(length(abs(vPos1.xy) - vec2(0.5))) < 0.01 ||
abs(length(abs(vPos1.yz) - vec2(0.5))) < 0.01 ||
abs(length(abs(vPos1.xz) - vec2(0.5))) < 0.01 )
){
gl_FragColor = vec4(1.0);
}else{
gl_FragColor = raymarchTransparent(ro, rd);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment