content/hifi-public/sam/hack/hack0.fs
Dale Glass 0d14e5a379 Initial data.
Needs a lot of cleanup. Data has been de-duplicated, and where identical copies existed, one of them
has been replaced with a symlink.

Some files have been excluded, such as binaries, installers and debug dumps. Some of that may still
be present.
2022-02-13 18:59:11 +01:00

283 lines
8.1 KiB
GLSL

#line 102
// Grabbed from the binaries, the code that exposes the TransformCamera
struct TransformCamera {
mat4 _view;
mat4 _viewInverse;
mat4 _projectionViewUntranslated;
mat4 _projection;
mat4 _projectionInverse;
vec4 _viewport;
};
layout(std140) uniform transformCameraBuffer {
TransformCamera _camera;
};
TransformCamera getTransformCamera() {
return _camera;
}
vec2 windowToClipSpace(TransformCamera cam, vec2 viewportPos) {
vec2 viewportSize = cam._viewport.zw;
// Detect stereo case
if (gl_FragCoord.x > viewportSize.x) {
return ((viewportPos - vec2(viewportSize.x,0.0) - cam._viewport.xy) / cam._viewport.zw) * 2.0 - vec2(1.0);
} else {
return ((viewportPos - cam._viewport.xy) / cam._viewport.zw) * 2.0 - vec2(1.0);
}
}
vec3 clipToEyeSpace(TransformCamera cam, vec3 clipPos) {
return vec3(cam._projectionInverse * vec4(clipPos.xyz, 1.0));
}
vec3 eyeToWorldSpace(TransformCamera cam, vec3 eyePos) {
return vec3(cam._viewInverse * vec4(eyePos.xyz, 1.0));
}
vec3 eyeToWorldSpaceDir(TransformCamera cam, vec3 eyePos) {
return vec3(cam._viewInverse * vec4(eyePos.xyz, 0.0));
}
////////////////////////////////////////////////////////////////
// Math Primitives
////////////////////////////////////////////////////////////////
void evalRayToBoxCords( in vec3 rayO, in vec3 rayD, out vec3 T0, out vec3 T1) {
vec3 C0 = vec3(-1.0);
vec3 C1 = vec3(1.0);
T0 = (C0 - rayO) / rayD;
T1 = (C1 - rayO) / rayD;
}
vec2 evalRayToBoxInOut(in vec3 rayO, in vec3 rayD) {
vec3 T0;
vec3 T1;
evalRayToBoxCords(rayO, rayD, T0, T1);
vec3 Tm = min(T0, T1);
vec3 TM = max(T0, T1);
vec2 io;
if (Tm.x > Tm.y) {
if (Tm.x > Tm.z)
io.x = (Tm.x);
else
io.x = (Tm.z);
} else {
if (Tm.y > Tm.z)
io.x = (Tm.y);
else
io.x = (Tm.z);
}
if (TM.x < TM.y) {
if (TM.x < TM.z)
io.y = (TM.x);
else
io.y = (TM.z);
} else {
if (TM.y < TM.z)
io.y = (TM.y);
else
io.y = (TM.z);
}
return io;
}
////////////////////////////////////////////////////////////////
// Volume Shape
////////////////////////////////////////////////////////////////
const float VOLUME_MAX_LEN = 2.0;
const float VOLUME_SCALE = 1.0;
void evalBoxVolumeRay(in vec3 fragPos, out vec3 rayIn, out vec3 rayOut, out vec3 rayDir, out float rayLen) {
TransformCamera camera = getTransformCamera();
vec3 oriPosW = iWorldPosition;
vec2 pixPos = windowToClipSpace(camera, gl_FragCoord.xy);
vec3 eyePosE = clipToEyeSpace(camera, vec3(pixPos, 0.0));
vec3 eyePosW = eyeToWorldSpace(camera, eyePosE);
vec3 eyeDirW = eyeToWorldSpaceDir(camera, eyePosE);
vec3 fragPosV = _position.xyz * VOLUME_SCALE;
vec3 oriToEyeW = eyePosW - oriPosW;
vec3 eyePosV = oriToEyeW * VOLUME_SCALE / (0.5 * iWorldScale);
rayDir = normalize(eyeDirW);
vec2 rayIO = evalRayToBoxInOut(eyePosV, rayDir);
// detect if inside the volume
if (rayIO.x < 0)
rayIO.x = 0;
rayIn = eyePosV + rayIO.x * rayDir;
rayOut = eyePosV + rayIO.y * rayDir;
rayLen = rayIO.y - rayIO.x;
}
////////////////////////////////////////////////////////////////
// Volume Scene
////////////////////////////////////////////////////////////////
// Simple
////////////////
vec4 fetchSimpleScene(vec3 pos) {
if (pos.y < 0)
return vec4(0);
float time = 0.75 + 0.25 * cos(iGlobalTime);
float radius2 = time * 1.0 - dot(pos, pos);
return vec4(pos * radius2, radius2);
}
// Spheres
////////////////
vec4 fetchSphere(vec3 pos, vec4 sphere, vec4 color) {
vec3 posS = pos - sphere.xyz;
float r2 = dot(posS,posS);
float sr2 = sphere.w*sphere.w;
if (r2 > sphere.w*sphere.w)
return vec4(0.0);
return vec4(color.xyz, color.w * (1 - (r2 / sr2)));
}
const int numSpheres = 6;
const float invNumSpheres = 1.0 / float(numSpheres);
const int numVec4PerSphere = 2;
const vec4 spheres[numSpheres * numVec4PerSphere] = vec4[numSpheres * numVec4PerSphere](
vec4(0.5, 0.5, 0.5, 0.3), vec4(1.0, 1.0, 0.0, 1.0),
vec4(-0.5, 0.5, 0.5, 0.2), vec4(1.0, 0.0, 0.0, 1.0),
vec4(0.5, -0.5, 0.5, 0.1), vec4(0.0, 1.0, 0.0, 1.0),
vec4(-0.5, -0.5, -0.5, 0.5), vec4(vec3(51.0, 226.0, 77.0) / 255.0, 0.9),
vec4(0.0, 0.0, 0.0, 1.0), vec4(vec3(51.0, 77.0, 226.0) / 255.0, 0.8),
vec4(0.5, 0.5, -0.5, 0.3), vec4(0.0, 1.0, 1.0, 1.0) );
const vec4 oneSphere = vec4(0.5, 0.5, 0.5, 0.3);
vec4 fetchSpheresScene(vec3 pos) {
vec4 result = vec4(0.0);
for (int s = 0; s < numSpheres; s++) {
//for (int s = 0; s < 2; s++) {
//result += fetchSphere(pos, spheres[s * numVec4PerSphere], spheres[s * numVec4PerSphere + 1]);
result = max(result, fetchSphere(pos, spheres[s * numVec4PerSphere], spheres[s * numVec4PerSphere + 1]));
}
result *= invNumSpheres;
return result;
}
// Texture
////////////////
const int NUM_SLICES_PER_AXIS = 10;
const vec2 MAP_DIM = vec2(10, 10);
const vec2 INV_MAP_DIM = 1.0 / MAP_DIM;
vec4 fetchTextureScene(vec3 pos) {
vec3 npos = pos * 0.5 + vec3(0.5);
float sliceCoord = npos.y * INV_MAP_DIM.x * INV_MAP_DIM.x;
int sliceIndex = int(floor(sliceCoord));
float ycoordOffset = float(sliceIndex / NUM_SLICES_PER_AXIS);
float xcoordOffset = float(sliceIndex % NUM_SLICES_PER_AXIS);
vec2 texcoord2D = vec2((npos.x + xcoordOffset) * INV_MAP_DIM.x , (npos.z + ycoordOffset) * INV_MAP_DIM.y);
return vec4(texcoord2D, 0.0, 0.1);
float density = texture(iChannel0, texcoord2D).x;
return vec4(density);
}
vec4 fetchVolume(vec3 pos) {
//return fetchSimpleScene(pos);
//return fetchSpheresScene(pos);
return fetchTextureScene(pos);
}
////////////////////////////////////////////////////////////////
// Ray tracing
////////////////////////////////////////////////////////////////
const float MAX_NUM_STEPS = 100;
const float STEP_LEN = VOLUME_MAX_LEN / MAX_NUM_STEPS; // worse case is 2 / MAX_NUM_STEPS
const float ALPHA_TRESHOLD = 0.1;
bool blendSample(vec4 value, inout vec4 result) {
if (value.a >= ALPHA_TRESHOLD) {
result.rgb += (1.0-result.a)*value.a*value.rgb;
result.a += (1.0-result.a)*value.a;
if (result.a >= 1.0) {
result.a = 1;
return true;
}
}
return false;
}
vec4 rayTrace(vec3 rayIn, vec3 rayDir, float rayLen, vec3 rayOut) {
float numSteps = min(floor(rayLen / STEP_LEN), float(MAX_NUM_STEPS));
float stepLen = STEP_LEN;
vec4 result = vec4(0.0);
vec4 value = vec4(0.0);
vec3 samplePos = rayIn;
int tracedSteps = 0;
for (int i=0; i < numSteps; i++) {
value = fetchVolume(samplePos);
samplePos = rayIn + i * stepLen * rayDir;
if (blendSample(value, result)) {
i = int(numSteps);
}
tracedSteps ++;
}
if (result.a < 1) {
value = fetchVolume(rayIn + rayLen * rayDir);
blendSample(value, result);
}
// if ( gl_FragCoord.x > 900)
return result;
return vec4(vec3(tracedSteps / float(numSteps)), 1.0);
}
////////////////////////////////////////////////////////////////
// Setup & Main
////////////////////////////////////////////////////////////////
vec4 getProceduralColor() {
// discard;
vec3 rayInV;
vec3 rayOutV;
vec3 rayDirV;
float rayLenV;
evalBoxVolumeRay(_position.xyz, rayInV, rayOutV, rayDirV, rayLenV);
// now step in the volume
vec4 rayColor = rayTrace(rayInV, rayDirV, rayLenV, rayOutV);
if (rayColor.a < 0.001) {
discard;
}
return rayColor;
}
float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) {
diffuse = vec3(1.0);
vec4 result = getProceduralColor();
specular = result.xyz;
shininess = 0.5;
return result.a;
}