95 lines
2.3 KiB
GLSL
95 lines
2.3 KiB
GLSL
#version 450
|
|
|
|
struct Material {
|
|
vec3 albedo;
|
|
float specular;
|
|
};
|
|
|
|
// Variables
|
|
layout(location=0) in vec2 _InUV;
|
|
layout(location=0) out vec4 _OutColor;
|
|
|
|
layout(set=0,binding=0) uniform Uniforms {
|
|
mat4 _ViewMatrix;
|
|
mat4 _ProjMatrixInv;
|
|
vec3 _CamPos;
|
|
vec3 _SunDir;
|
|
float _Time;
|
|
};
|
|
layout(set=1,binding=0) uniform usampler3D _NodesTexture;
|
|
layout(set=2,binding=0) uniform usampler3D _BricksTexture;
|
|
layout(set=3, binding=0) uniform Materials {
|
|
Material _Materials[256];
|
|
};
|
|
|
|
// Defines
|
|
#define EPSILON 0.00000001
|
|
#define SCALE 1.0
|
|
#define NODE_TEX_SIZE 48
|
|
#define BLOCK_TEX_SIZE 64
|
|
#define BLOCK_SIZE 32
|
|
|
|
|
|
// Include
|
|
#include "structs.cginc"
|
|
#include "shading.cginc"
|
|
#include "raycasting.cginc"
|
|
|
|
|
|
float seed;
|
|
float random(float s) {
|
|
return fract(sin(seed++ + s)*43758.5453123);
|
|
}
|
|
|
|
vec3 randomHemisphere(vec3 dir)
|
|
{
|
|
vec3 uu = normalize(cross(dir, vec3(0.0,1.0,1.0)));
|
|
vec3 vv = cross(uu, dir);
|
|
|
|
vec2 rv2 = vec2(random(1), random(2));
|
|
|
|
float ra = sqrt(rv2.y);
|
|
float rx = ra*cos(6.2831*rv2.x);
|
|
float ry = ra*sin(6.2831*rv2.x);
|
|
float rz = sqrt(1.0-rv2.y);
|
|
vec3 rr = vec3(rx*uu + ry*vv + rz*dir );
|
|
|
|
return normalize(rr);
|
|
}
|
|
|
|
vec3 solve()
|
|
{
|
|
// Calculate ray direction
|
|
vec3 view_dir = (_ProjMatrixInv * vec4(_InUV, 0, 1)).xyz;
|
|
vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz;
|
|
Ray primaryRay = Ray((_CamPos + vec3(16, 0, 16)) / SCALE, rayDir);
|
|
|
|
// Raycast
|
|
HitResult primary = castNodes(primaryRay, 100);
|
|
if(primary.data > 0)
|
|
{
|
|
vec3 color = applyLighting(primary.pos, primaryRay.dir, primary.normal, primary.data);
|
|
vec3 hitPos = primary.pos-primary.normal*EPSILON;
|
|
|
|
// Shadow ray
|
|
Ray shadowRay = Ray(hitPos, _SunDir);
|
|
HitResult shadow = castNodes(shadowRay, 50);
|
|
if(shadow.data > 0) color *= 0.1;
|
|
|
|
// Secondary ray
|
|
// Ray secondRay = Ray(hitPos, randomHemisphere(primary.normal));
|
|
// HitResult second = castNodes(secondRay, 25);
|
|
// if(second.data > 0) color += getAlbedo(second.data) * 0.8;
|
|
|
|
return color;
|
|
}
|
|
|
|
float up = clamp(dot(primaryRay.dir, vec3(0, 1, 0)) + 0.1, 0, 1);
|
|
return vec3(0.176, 0.592, 0.901) * up;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
seed = 420 * _InUV.x + 1337 * _InUV.y + _Time * 1234;
|
|
_OutColor = vec4(solve(), 1);
|
|
} |