105 lines
4.0 KiB
GLSL
105 lines
4.0 KiB
GLSL
bool intersectsAABB(vec3 ro, vec3 rd, vec3 aabbMin, vec3 aabbMax) {
|
|
vec3 t0 = (aabbMin - ro) / rd;
|
|
vec3 t1 = (aabbMax - ro) / rd;
|
|
|
|
vec3 tMin = min(t0, t1);
|
|
vec3 tMax = max(t0, t1);
|
|
|
|
float m0 = max(max(tMin.x, tMin.y), tMin.z);
|
|
float m1 = min(min(tMax.x, tMax.y), tMax.z);
|
|
|
|
return m1 > max0(m0);
|
|
}
|
|
|
|
bool intersectsParallelogram(vec3 ro, vec3 rd, vec3 v0, vec3 v1, vec3 v2, float tMin, out float t, out vec2 uv, inout vec3 normal) {
|
|
vec3 a = v1 - v0, n = cross(a, v2 - v0);
|
|
|
|
t = dot(v0 - ro, n) / dot(n, rd);
|
|
if (t < 0.0 || t > tMin) return false;
|
|
|
|
vec3 b = v2 - v1;
|
|
vec3 c = ro + rd * t - v0;
|
|
|
|
uv = vec2(dot(c, a) / dot(a, a), dot(c, b) / dot(b, b));
|
|
if (uv.x < 0.0 || uv.y < 0.0 || uv.x > 1.0 || uv.y > 1.0) return false;
|
|
|
|
normal = normalize(n);
|
|
return true;
|
|
}
|
|
|
|
void CheckQuadAt(int i, vec3 playerPos, vec3 rayDir, inout vec3 albedo, inout float tMin, inout vec3 normal, inout float emissionOut) {
|
|
int i0 = 3 * i, i1 = 3 * i + 1, i2 = 3 * i + 2;
|
|
|
|
vec3 v0 = playerVerticesSSBO.vertexPositions[i0];
|
|
vec3 v1 = playerVerticesSSBO.vertexPositions[i1];
|
|
vec3 v2 = playerVerticesSSBO.vertexPositions[i2];
|
|
|
|
float t;
|
|
vec2 uv;
|
|
|
|
vec3 colorP;
|
|
vec3 color;
|
|
float emission = 0.0;
|
|
float smoothnessD, smoothnessG;
|
|
if (intersectsParallelogram(playerPos, rayDir, v0, v1, v2, tMin, t, uv, normal)) {
|
|
vec2 texCoord0 = playerVerticesSSBO.vertexData[i0];
|
|
vec2 texCoord1 = playerVerticesSSBO.vertexData[i1];
|
|
vec2 texCoord2 = playerVerticesSSBO.vertexData[i2];
|
|
|
|
vec2 quadTexCoord = mix(texCoord0, texCoord1, uv.x) + uv.y * (texCoord2 - texCoord1);
|
|
vec4 playerAtlasSample = texelFetch(playerAtlas_sampler, ivec2(64 * quadTexCoord), 0);
|
|
|
|
vec3 colorP = playerAtlasSample.rgb;
|
|
vec3 color = playerAtlasSample.rgb;
|
|
|
|
#ifdef SPACEAGLE17
|
|
#include "/lib/materials/specificMaterials/others/SpacEagle17.glsl"
|
|
#endif
|
|
if (playerAtlasSample.a > 0.2) {albedo = color * (emission * 0.2 + 1.0); tMin = t; emissionOut = emission;}
|
|
}
|
|
}
|
|
|
|
bool rayTracePlayer(vec3 playerPos, vec3 rayDir, float wsrTraceLength, out vec3 albedo, out vec3 normal, out float emission) {
|
|
float tMin = wsrTraceLength;
|
|
vec3 aabbPos = playerPos * 1000.0;
|
|
|
|
// Head
|
|
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.headMin, playerVerticesSSBO.bounds.headMax)) {
|
|
for (int i = 0; i < 12; i++) {
|
|
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
|
}
|
|
}
|
|
// Right Hand
|
|
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.rightHandMin, playerVerticesSSBO.bounds.rightHandMax)) {
|
|
for (int i = 12; i < 24; i++) {
|
|
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
|
}
|
|
}
|
|
// Left Leg
|
|
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.leftLegMin, playerVerticesSSBO.bounds.leftLegMax)) {
|
|
for (int i = 24; i < 36; i++) {
|
|
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
|
}
|
|
}
|
|
// Left Hand
|
|
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.leftHandMin, playerVerticesSSBO.bounds.leftHandMax)) {
|
|
for (int i = 36; i < 48; i++) {
|
|
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
|
}
|
|
}
|
|
// Right leg
|
|
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.rightLegMin, playerVerticesSSBO.bounds.rightLegMax)) {
|
|
for (int i = 48; i < 60; i++) {
|
|
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
|
}
|
|
}
|
|
// Torso
|
|
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.torsoMin, playerVerticesSSBO.bounds.torsoMax)) {
|
|
for (int i = 60; i < 72; i++) {
|
|
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
|
}
|
|
}
|
|
|
|
return tMin < wsrTraceLength;
|
|
}
|