struct EyeMatrices {
	mat4 view;
	mat4 projection;
	
	mat4 model;
	mat4 previous;

	mat4 iView;
	mat4 iProjection;
	
	vec4 eyePos;
};

struct Viewport {
	mat4 view;
	mat4 projection;
};

struct Cursor {
	vec2 position;
	vec2 radius;
	vec4 color;
};

struct Ray {
	vec3 origin;
	vec3 direction;

	vec3 position;
	float distance;
};

struct Space {
	vec3 eye;
	vec3 world;
};

struct Light {
	mat4 view;
	mat4 projection;
	
	vec3 position;
	float radius;
	
	vec3 color;
	float power;
	
	int type;
	int typeMap;
	int indexMap;
	float depthBias;
};

struct Material {
	vec4 colorBase;
	vec4 colorEmissive;

	float factorMetallic;
	float factorRoughness;
	float factorOcclusion;
	float factorAlphaCutoff;

	int indexAlbedo;
	int indexNormal;
	int indexEmissive;
	int indexOcclusion;
	
	int indexMetallicRoughness;
	int indexCubemap;
	int modeCull;
	int modeAlpha;
};

struct Texture {
	int index;
	int samp;
	int remap;
	float blend;

	vec4 lerp;
};

struct DrawCommand {
	uint indices; // triangle count
	uint instances; // instance count
	uint indexID; // starting triangle position
	uint vertexID; // starting vertex position

	uint instanceID; // starting instance position
	float padding1; //
	float padding2; // material to use for this draw call
	uint vertices; // number of vertices used
};

struct Bounds {
	vec3 min;
	float padding1;
	vec3 max;
	float padding2;
	vec3 center;
	float padding3;
	vec3 extent;
	float padding4;
};

struct LOD {
	uint indices;
	uint indexID;
	uint vertexID;
	uint vertices;
};

struct LODMetadata {
	LOD levels[4];
};

struct Instance {
	uint materialID;
	uint primitiveID;
	uint meshID;
	uint objectID;

	 int jointID;
	 int lightmapID;
	 int cubemapID;
	uint auxID;

	Bounds bounds;
//	InstanceAddresses addresses;
};

struct InstanceAddresses {
	uint64_t vertex;
	uint64_t index;
	
	uint64_t indirect;
	uint drawID;
	uint padding0;

	uint64_t position;
	uint64_t uv;

	uint64_t color;
	uint64_t st;

	uint64_t normal;
	uint64_t tangent;

	uint64_t joints;
	uint64_t weights;
};

struct Object {
	mat4 model;
	mat4 previous;

	vec4 color;
};

struct SurfaceMaterial {
	vec4 albedo;
	vec4 indirect;

	float metallic;
	float roughness;
	float occlusion;
	bool lightmapped;
};

struct Surface {
	uint pass;
	uint subID;

	vec3 uv;
	vec3 st;
	Space position;
	Space normal;
	Space tangent;
	mat3 tbn;
	vec3 barycentric;
	vec2 motion;
	vec2 dUvDx;
	vec2 dUvDy;
	vec2 dStDx;
	vec2 dStDy;
	
	Ray ray;
	
	SurfaceMaterial material;
	Instance instance;
	Object object;

	vec4 light;
	vec4 fragment;
	vec2 fragCoord;
} surface;

// MSAA info
#if MULTISAMPLING
struct MSAA {
	int currentID;
	float depth;
	uvec2 IDs[MAX_MSAA_SAMPLES];
	vec4 fragment;
	vec4 fragments[MAX_MSAA_SAMPLES];
} msaa;
#endif
// UBO settings
struct SettingsLengths {
	uint lights;
	uint materials;
	uint textures;
	uint drawCommands;
};
struct SettingsMode {
	vec4 parameters;
	uint type;
	uint scalar;
	uint msaa;
	uint frameNumber;	
};
struct SettingsLighting {
	vec3 ambient;
	uint indexSkybox;

	uint maxShadows;
	uint shadowSamples;
	uint useLightmaps;
};
struct SettingsFog {
	vec3 color;
	float stepScale;

	vec3 offset;
	float densityScale;

	vec2 range;
	float densityThreshold;
	float densityMultiplier;
	
	float absorbtion;
	float padding1;
	float padding2;
	float padding3;
};
struct SettingsBloom {
	float exposure;
	float gamma;
	float threshold;
	uint padding;
};
struct SettingsVxgi {
	mat4 matrix;

	float cascadePower;
	float granularity;
	float voxelizeScale;
	float occlusionFalloff;

	float traceStartOffsetFactor;
	uint shadows;
	uint padding2;
	uint padding3;
};
struct SettingsRayTrace {
	vec2 defaultRayBounds;
	float alphaTestOffset;
	float padding1;

	uint samples;
	uint paths;
	uint frameAccumulationMinimum;
	uint padding2;
};

struct Settings {
	SettingsLengths lengths;
	SettingsMode mode;
	SettingsLighting lighting;
	SettingsFog fog;
	SettingsBloom bloom;
	SettingsVxgi vxgi;
	SettingsRayTrace rt;
};
struct Voxel {
	uvec2 id;
	vec3 position;
	vec3 normal;
	vec2 uv;
	vec4 color;
};
struct VoxelInfo {
	vec3 min;
	vec3 max;

	float mipmapLevels;
	float radianceSize;
	float radianceSizeRecip;
	uint state; // yuck
} voxelInfo;

// Raytrace stuff

struct Vertex {
	vec3 position;
	vec2 uv;
	uint color;
	vec2 st;
	vec3 normal;
	vec4 tangent;
	uvec2 joints;
	vec4 weights;
};

struct Triangle {
	Vertex point;
	
	vec3 geomNormal;
	
	uint instanceID;
};

struct RayTracePayload {
	bool hit;
	uint instanceID;
	uint primitiveID;
	vec2 attributes;
//	Triangle triangle;
};