1
0
Fork 0

Compare commits

...

5 Commits

Author SHA1 Message Date
May B. 623cbb8724 World pass VK and GL Mipmap load 2020-10-17 18:47:54 +02:00
May B. 15f5b090b5 Voxel pass 2020-10-14 21:14:43 +02:00
May B. 74e156179f Indicator pass 2020-10-14 12:59:24 +02:00
May B. 7cdb3c636f Vk LodModel 2020-10-12 10:18:24 +02:00
May B. a774e99d7b WIP: Vulkan skybox (bug on intel mesa ???) 2020-10-11 11:59:32 +02:00
133 changed files with 1724 additions and 1079 deletions

BIN
resource/content/shaders/Color.vs.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Sky.fs.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Sky.vs.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Tris.vs.spv (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
resource/content/shaders/Voxel.fs.geo.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.fs.ins.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.fs.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.geo.fs.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/content/shaders/Voxel.geo.gs.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/content/shaders/Voxel.geo.ins.fs.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/content/shaders/Voxel.geo.ins.gs.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/content/shaders/Voxel.geo.ins.vs.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/content/shaders/Voxel.geo.vs.spv (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
resource/content/shaders/Voxel.gs.geo.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.ins.fs.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/content/shaders/Voxel.ins.vs.spv (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
resource/content/shaders/Voxel.vs.geo.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.vs.ins.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.vs.spv (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,11 @@
#version 450 core
layout(push_constant) uniform PushConstants {
mat4 MVP;
layout(binding = 0) uniform UniformBufferObject {
mat4 view;
mat4 proj;
} UBO;
layout(push_constant) uniform PushConst {
mat4 model;
} Push;
layout(location = 0) in vec3 Position_modelspace;
@ -10,7 +14,7 @@ layout(location = 1) in vec4 Color_model;
layout(location = 0) out vec4 Color;
void main(){
gl_Position = Push.MVP * vec4(Position_modelspace, 1);
gl_Position = UBO.proj * UBO.view * Push.model * vec4(Position_modelspace, 1);
Color = Color_model;
}

View File

@ -9,4 +9,5 @@ layout(location = 0) out vec4 color;
void main(){
color = texture(Texture, UV);
color = pow(color, vec4(2.2)); //TODO: Space brightness option
}

View File

@ -1,9 +1,9 @@
#version 450 core
layout(push_constant) uniform PushConstants {
mat4 View;
mat4 Projection;
} Push;
layout(binding = 0) uniform UniformBufferObject {
mat4 view;
mat4 proj;
} UBO;
layout (location = 0) in vec3 Position_modelspace;
@ -11,5 +11,7 @@ layout (location = 0) out vec3 UV;
void main(){
UV = Position_modelspace;
gl_Position = (Push.Projection * Push.View * vec4(Position_modelspace, 1.0)).xyww;
mat4 view = UBO.view;
view[3] = vec4(0.0f, 0.0f, 0.0f, 1.0f);
gl_Position = (UBO.proj * view * vec4(Position_modelspace, 1.0)).xyww;
}

View File

@ -2,20 +2,22 @@
#extension GL_ARB_separate_shader_objects : enable
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
} ubo;
} UBO;
layout(push_constant) uniform PushConst {
mat4 model;
} Push;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 0) in vec3 Position_modelspace;
layout(location = 1) in vec3 Color_model;
layout(location = 2) in vec2 TexCoord_model;
layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;
layout(location = 0) out vec3 Color;
layout(location = 1) out vec2 TexCoord;
void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor;
fragTexCoord = inTexCoord;
gl_Position = UBO.proj * UBO.view * Push.model * vec4(Position_modelspace, 1.0);
Color = Color_model;
TexCoord = TexCoord_model;
}

View File

@ -10,26 +10,17 @@ layout (constant_id = 4) const bool BLEND = true;
layout (constant_id = 16) const int UNIT_SIZE = 8;
layout (binding = 0) uniform UniformBufferObject {
vec3 FogColor;
float FogDepth;
mat4 view;
mat4 proj;
vec3 LightInvDirection_worldspace;
vec3 lightInvDirection_worldspace;
vec4 fog; //color.rgb depth.a
} UBO;
layout (binding = 1) uniform sampler2DArray TextureAtlas;
layout (binding = 2) uniform sampler2DArray NormalAtlas;
layout (binding = 3) uniform sampler2DArray HOSAtlas;
layout(push_constant) uniform PushConstants {
mat4 Proj;
mat4 View;
#ifndef INSTANCED
mat4 Model;
#endif
vec4 SphereProj;
float Curvature;
} Push;
#ifdef GEOMETRY
layout (location = 0) in GeometryData
#else
@ -52,7 +43,7 @@ layout (location = 0) in VertexData
float Depth;
} vs;
layout(location = 0) out vec3 color;
layout(location = 0) out vec4 color;
vec3 expand(vec3 v) {
return (v - 0.5) * 2;
@ -133,7 +124,7 @@ vec3 getTriTexture(sampler2DArray smpl, vec2 crdx, vec2 crdy, vec2 crdz, vec3 we
void main() {
float texScale = 1. / UNIT_SIZE;
vec3 tex, texN, worldNormal, texHOS;
vec3 tex, worldNormal, texHOS;
if(TRIPLANAR) {
// Triplanar
@ -147,7 +138,7 @@ if(TRIPLANAR) {
vec2 UVy = vs.Position_modelspace.zx * texScale;
vec2 UVz = vs.Position_modelspace.xy * texScale;
vec3 tex = getTriTexture(TextureAtlas, UVx, UVy, UVz, blendWeights);
tex = getTriTexture(TextureAtlas, UVx, UVy, UVz, blendWeights);
if(PBR) {
// Whiteout normal blend
@ -159,9 +150,9 @@ if(PBR) {
texNy = vec3(texNy.xy + vs.FaceNormal_worldspace.xz, abs(texNy.z) * vs.FaceNormal_worldspace.y);
texNz = vec3(texNz.xy + vs.FaceNormal_worldspace.xy, abs(texNz.z) * vs.FaceNormal_worldspace.z);
// Swizzle tangent normals to match world orientation and triblend
vec3 worldNormal = normalize(texNx.zyx * blendWeights.x + texNy.xzy * blendWeights.y +texNz.xyz * blendWeights.z);
worldNormal = normalize(texNx.zyx * blendWeights.x + texNy.xzy * blendWeights.y +texNz.xyz * blendWeights.z);
vec3 texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights);
texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights);
}
} else {
// Cheap planar
@ -169,16 +160,16 @@ if(PBR) {
vec3 nrm = normalize(pow(blendWeights, vec3(80 / sqrt(UNIT_SIZE))));
vec2 UV = (vec2(vs.Position_modelspace.xy * nrm.z) + vec2(vs.Position_modelspace.yz * nrm.x) + vec2(vs.Position_modelspace.zx * nrm.y)) * texScale;
vec3 tex = getTexture(TextureAtlas, UV).rgb;
tex = getTexture(TextureAtlas, UV).rgb;
if(PBR) {
vec3 texN = expand(getTexture(NormalAtlas, UV).rgb);
// Swizzle world normals into tangent space and apply Whiteout blend
// Swizzle tangent normals to match world orientation and triblend
vec3 worldNormal = normalize(vec3(texN.xy + vs.FaceNormal_worldspace.zy, abs(texN.z) * vs.FaceNormal_worldspace.x).zyx * blendWeights.x +
worldNormal = normalize(vec3(texN.xy + vs.FaceNormal_worldspace.zy, abs(texN.z) * vs.FaceNormal_worldspace.x).zyx * blendWeights.x +
vec3(texN.xy + vs.FaceNormal_worldspace.xz, abs(texN.z) * vs.FaceNormal_worldspace.y).xzy * blendWeights.y +
vec3(texN.xy + vs.FaceNormal_worldspace.xy, abs(texN.z) * vs.FaceNormal_worldspace.z).xyz * blendWeights.z);
vec3 texHOS = getTexture(HOSAtlas, UV).rgb;
texHOS = getTexture(HOSAtlas, UV).rgb;
}
}
@ -189,7 +180,7 @@ if(PBR) {
vec3 TextureAmbientColor = vec3(.1) * TextureDiffuseColor * texHOS.y;
vec3 TextureSpecularColor = vec3(.8) * texHOS.z;
vec3 Normal_cameraspace = normalize((Push.View * vec4(worldNormal,0)).xyz);
vec3 Normal_cameraspace = normalize((UBO.view * vec4(worldNormal,0)).xyz);
// Light emission properties
// You probably want to put them as uniforms
@ -222,22 +213,21 @@ if(PBR) {
// MAYBE: shadow
color =
tex =
// Ambient : simulates indirect lighting
TextureAmbientColor +
// Diffuse : "color" of the object
visibility * TextureDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) +
// Specular : reflective highlight, like a mirror
visibility * TextureSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance * distance);
} else {
color = tex;
}
if(FOG) {
float ratio = exp(vs.Depth * 0.69)-1;
color = mix(color, pow(UBO.FogColor, vec3(2.2)), clamp(ratio, 0, 1));
tex = mix(tex, UBO.fog.rgb, clamp(ratio, 0, 1));
}
color = pow(color, vec3(1.0 / 2.2));
if(color.r > 1 || color.g > 1 || color.b > 1) {
color = vec3(1, 0, 0); //TODO: bloom
}
//TODO: check gamma color = pow(color, vec3(1.0 / 2.2));
color = vec4(tex, 1);
/*if(color.r > 1 || color.g > 1 || color.b > 1) {
color = vec4(1, 0, 0, 1); //TODO: bloom
}*/
}

View File

@ -33,13 +33,15 @@ layout (location = 0) out GeometryData {
} gs;
void main() {
for(int j = 0; j < 3; j++) {
gs.Textures[j] = vs_in[j].Texture;
}
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position;
gs.Position_modelspace = vs_in[i].Position_modelspace;
gs.FaceNormal_modelspace = vs_in[i].FaceNormal_modelspace;
gs.Textures[i] = vs_in[i].Texture;
switch(int(mod(i,3))) {
case 0:
gs.TextureRatio = vec3(1,0,0);
@ -60,9 +62,6 @@ if(PBR) {
gs.EyeDirection_cameraspace = vs_in[i].EyeDirection_cameraspace;
gs.LightDirection_cameraspace = vs_in[i].LightDirection_cameraspace;
}
#ifdef SHADOW
gs.ShadowCoord = vs_in[i].ShadowCoord;
#endif
if(FOG) {
gs.Depth = vs_in[i].Depth;
}

View File

@ -8,21 +8,21 @@ layout (constant_id = 5) const bool DO_CURVATURE = false;
layout (constant_id = 6) const bool CURV_DEPTH = true;
layout (binding = 0) uniform UniformBufferObject {
vec3 FogColor;
float FogDepth;
mat4 view;
mat4 proj;
vec3 LightInvDirection_worldspace;
vec3 lightInvDirection_worldspace;
vec4 fog; //color.rgb depth.a
} UBO;
layout(push_constant) uniform PushConstants {
mat4 Proj; //MAYBE: move Proj View to UBO
mat4 View;
layout(push_constant) uniform PushConst {
#ifndef INSTANCED
mat4 Model;
mat4 model;
#endif
vec4 SphereProj;
float Curvature;
vec4 sphereProj;
float curvature;
} Push;
layout (location = 0) in vec3 Position_modelspace;
@ -47,27 +47,27 @@ layout (location = 0) out VertexData {
void main(){
#ifndef INSTANCED
mat4 Model = Push.Model;
mat4 Model = Push.model;
#endif
vs.Position_modelspace = Position_modelspace;
if(DO_CURVATURE) {
if(Push.Curvature > 0) {
vec3 Position_areaspace = Position_modelspace + Push.SphereProj.xyz;
if(Push.curvature > 0) {
vec3 Position_areaspace = Position_modelspace + Push.sphereProj.xyz;
vec2 sph = vec2(acos(Position_areaspace.z / length(Position_areaspace.xyz)), atan(Position_areaspace.y, Position_areaspace.x));
float radius = CURV_DEPTH ?
max(max(abs(Position_areaspace.x), abs(Position_areaspace.y)), abs(Position_areaspace.z)) :
Push.SphereProj.w;
vs.Position_modelspace = mix(vs.Position_modelspace, vec3(sin(sph.x)*cos(sph.y), sin(sph.x)*sin(sph.y), cos(sph.x)) * radius - Push.SphereProj.xyz, Push.Curvature);
Push.sphereProj.w;
vs.Position_modelspace = mix(vs.Position_modelspace, vec3(sin(sph.x)*cos(sph.y), sin(sph.x)*sin(sph.y), cos(sph.x)) * radius - Push.sphereProj.xyz, Push.curvature);
}
}
vec4 Position_cameraspace = Push.View * Model * vec4(vs.Position_modelspace, 1);
gl_Position = Push.Proj * Position_cameraspace;
vec4 Position_cameraspace = UBO.view * Model * vec4(vs.Position_modelspace, 1);
gl_Position = UBO.proj * Position_cameraspace;
if(FOG) {
vs.Depth = length(Position_cameraspace.xyz) / UBO.FogDepth;
vs.Depth = length(Position_cameraspace.xyz) / UBO.fog.a;
}
vs.Texture = Texture_model;
@ -82,6 +82,6 @@ if(PBR) {
vs.EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace.xyz;
// Vector that goes from the vertex to the light, in camera space
vs.LightDirection_cameraspace = (Push.View * vec4(UBO.LightInvDirection_worldspace,0)).xyz;
vs.LightDirection_cameraspace = (UBO.view * vec4(UBO.lightInvDirection_worldspace,0)).xyz;
}
}

View File

@ -22,12 +22,12 @@ $GLSL $BASEDIR/Sky.frag -o $TARGETDIR/Sky.fs.spv
# Voxel
$GLSL $BASEDIR/Voxel.vert -o $TARGETDIR/Voxel.vs.spv
$GLSL $BASEDIR/Voxel.frag -o $TARGETDIR/Voxel.fs.spv
$GLSL $BASEDIR/Voxel.vert -DINSTANCED -o $TARGETDIR/Voxel.vs.ins.spv
$GLSL $BASEDIR/Voxel.frag -DINSTANCED -o $TARGETDIR/Voxel.fs.ins.spv
$GLSL $BASEDIR/Voxel.vert -DINSTANCED -o $TARGETDIR/Voxel.ins.vs.spv
$GLSL $BASEDIR/Voxel.frag -DINSTANCED -o $TARGETDIR/Voxel.ins.fs.spv
$GLSL $BASEDIR/Voxel.vert -DGEOMETRY -o $TARGETDIR/Voxel.vs.geo.spv
$GLSL $BASEDIR/Voxel.geom -DGEOMETRY -o $TARGETDIR/Voxel.gs.geo.spv
$GLSL $BASEDIR/Voxel.frag -DGEOMETRY -o $TARGETDIR/Voxel.fs.geo.spv
$GLSL $BASEDIR/Voxel.vert -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.vs.geo.ins.spv
$GLSL $BASEDIR/Voxel.geom -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.gs.geo.ins.spv
$GLSL $BASEDIR/Voxel.frag -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.fs.geo.ins.spv
$GLSL $BASEDIR/Voxel.vert -DGEOMETRY -o $TARGETDIR/Voxel.geo.vs.spv
$GLSL $BASEDIR/Voxel.geom -DGEOMETRY -o $TARGETDIR/Voxel.geo.gs.spv
$GLSL $BASEDIR/Voxel.frag -DGEOMETRY -o $TARGETDIR/Voxel.geo.fs.spv
$GLSL $BASEDIR/Voxel.vert -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.geo.ins.vs.spv
$GLSL $BASEDIR/Voxel.geom -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.geo.ins.gs.spv
$GLSL $BASEDIR/Voxel.frag -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.geo.ins.fs.spv

BIN
resource/shaders-src/frag.spv (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/textures-src/1024-realistic/Debug.cube.back.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/textures-src/1024-realistic/Debug.cube.bottom.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/textures-src/1024-realistic/Debug.cube.front.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/textures-src/1024-realistic/Debug.cube.left.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/textures-src/1024-realistic/Debug.cube.right.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resource/textures-src/1024-realistic/Debug.cube.top.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -37,6 +37,12 @@ Stone_Wall_008_NORM.jpg terrain/Stone_wall.nrm.dds
Water_002_COLOR.jpg terrain/Water.dds
Water_002_HOS.jpg terrain/Water.hos.dds
Water_002_NORM.jpg terrain/Water.nrm.dds
Debug.cube.back.png sky/Debug.cube.back.dds
Debug.cube.bottom.png sky/Debug.cube.bottom.dds
Debug.cube.front.png sky/Debug.cube.front.dds
Debug.cube.left.png sky/Debug.cube.left.dds
Debug.cube.right.png sky/Debug.cube.right.dds
Debug.cube.top.png sky/Debug.cube.top.dds
Space_orange.cube.back.png sky/Space_orange.cube.back.dds
Space_orange.cube.bottom.png sky/Space_orange.cube.bottom.dds
Space_orange.cube.front.png sky/Space_orange.cube.front.dds

View File

@ -30,7 +30,6 @@ void Client::run(server_handle* const localHandle) {
auto world = world::client::Load(options.connection, localHandle, options.world, options.contouring);
state.contouring = world->getContouring();
//TODO: loop
do {
window.startFrame();
FrameMark;
@ -56,7 +55,7 @@ void Client::run(server_handle* const localHandle) {
}
camera.update();
pipeline->lookFrom(camera);
pipeline->LightInvDir = glm::vec3(glm::rotate(glm::mat4(1), deltaTime * .1f, glm::vec3(1, .5, .1)) * glm::vec4(pipeline->LightInvDir, 0));
pipeline->LightInvDir = glm::vec3(glm::rotate(glm::mat4(1), deltaTime * .5f, glm::vec3(1, .5, .1)) * glm::vec4(pipeline->LightInvDir, 0));
{
const auto ray_result = world->raycast(camera.getRay() * options.voxel_density);
@ -102,7 +101,7 @@ void Client::run(server_handle* const localHandle) {
pipeline->reloadShaders(options.renderer.voxel);
}
if(actions && render::UI::Actions::RendererTextures) {
pipeline->reloadTextures(options.renderer.textures, options.renderer.mipMapLOD, options.renderer.anisotropy);
pipeline->reloadTextures(options.renderer.textures, options.renderer.getMipmapLodBias(), options.renderer.getAnisotropy());
}
if(actions && render::UI::Actions::World) {
//FIXME: server options world->setOptions(options.world);
@ -131,9 +130,8 @@ void Client::run(server_handle* const localHandle) {
{ // Chunks
const auto pass = pipeline->beginWorldPass();
const auto draw = [&](glm::mat4 model, render::LodModel *const buffer, const contouring::Abstract::area_info &area, const voxel_pos &pos) {
pipeline->setCurvature(glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
reports.models_count++;
reports.tris_count += pass(buffer, model);
reports.tris_count += pass(buffer, model, glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
};
if (options.culling > 0) {
std::vector<glm::vec3> occlusion;
@ -161,14 +159,17 @@ void Client::run(server_handle* const localHandle) {
};*/
//world->getEntitiesModels(draw, frustum, offset, options.voxel_density);
}
if(state.look_at.has_value()) { // Indicator
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), 1.f / glm::vec3(options.voxel_density)), glm::vec3(state.look_at.value().pos.second + state.look_at.value().offset - offset * glm::llvec3(options.voxel_density)) - glm::vec3(.5 + options.editor.tool.radius)), glm::vec3(1 + options.editor.tool.radius * 2));
reports.models_count++;
reports.tris_count += pipeline->drawIndicatorCube(model);
{
const auto pass = pipeline->beginIndicatorPass();
if(state.look_at.has_value()) { // Indicator
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), 1.f / glm::vec3(options.voxel_density)), glm::vec3(state.look_at.value().pos.second + state.look_at.value().offset - offset * glm::llvec3(options.voxel_density)) - glm::vec3(.5 + options.editor.tool.radius)), glm::vec3(1 + options.editor.tool.radius * 2));
reports.models_count++;
reports.tris_count += pass(model);
}
}
pipeline->endPass();
pipeline->postProcess();
render::UI::Get()->render();
pipeline->endFrame();
}
{ // Swap buffers
@ -180,9 +181,10 @@ void Client::run(server_handle* const localHandle) {
window.waitTargetFPS();
} while (!(inputs.isDown(Input::Quit) || window.shouldClose()));
options.contouring = state.contouring->getOptions();
world.reset();
render::UI::Unload();
render::Renderer::Unload();
window.destroy();
options.contouring = state.contouring->getOptions();
}

View File

@ -35,8 +35,8 @@ public:
preferVulkan = config["render"]["prefer_vulkan"].value_or(preferVulkan);
renderer.textures = config["render"]["textures"].value_or(renderer.textures);
renderer.mipMapLOD = config["render"]["texture_quality"].value_or(renderer.mipMapLOD);
renderer.anisotropy = config["render"]["texture_angular_quality"].value_or(renderer.anisotropy);
renderer.textureQuality = config["render"]["texture_quality"].value_or(renderer.textureQuality);
renderer.textureSharpness = config["render"]["texture_angular_quality"].value_or(renderer.textureSharpness);
renderer.voxel.pbr = config["render"]["pbr"].value_or(renderer.voxel.pbr);
renderer.voxel.triplanar = config["render"]["triplanar"].value_or(renderer.voxel.triplanar);
renderer.voxel.stochastic = config["render"]["stochastic"].value_or(renderer.voxel.stochastic);
@ -103,8 +103,8 @@ public:
config.insert_or_assign("render", toml::table({
{"prefer_vulkan", preferVulkan},
{"textures", renderer.textures},
{"texture_quality", renderer.mipMapLOD},
{"texture_angular_quality", renderer.anisotropy},
{"texture_quality", renderer.textureQuality},
{"texture_angular_quality", renderer.textureSharpness},
{"pbr", renderer.voxel.pbr},
{"triplanar", renderer.voxel.triplanar},
{"stochastic", renderer.voxel.stochastic},

View File

@ -64,6 +64,13 @@ namespace contouring {
if (worker.joinable())
worker.join();
}
//TODO: prefer unique_ptr
for(auto& buffer: buffers) {
for(auto& val: buffer.second.second) {
delete val.second;
}
}
}
std::string FlatDualMC::getOptions() const {

View File

@ -14,6 +14,7 @@ void Camera::updateProjection() {
void Camera::update() {
const auto &offset = origin->position.offset;
// FIXME: up inverted after backflip
const auto axis = origin->getAxis();
// Camera matrix
ViewMatrix = glm::lookAt(

View File

@ -22,7 +22,7 @@ struct passOptions {
/// Transform texture UV
bool stochastic = false;
/// Active geometry pass
bool geometry = false;
bool geometry = true;
/// Blend voxel with mixed materials (requires geometry)
bool blend = true;
/// Depth fog
@ -44,14 +44,17 @@ struct renderOptions {
/// Texture pack name
std::string textures = "1024-realistic";
/// Textures quality
float mipMapLOD = -.5;
int textureQuality = 100;
/// Textures anisotropic mapping
int anisotropy = 0;
int textureSharpness = 0;
/// Depth color
glm::vec4 clear_color;
/// Parallel processing frames
/// Incease FPS but also a bit latency (Vulkan only)
int inFlightFrames = 2;
constexpr float getMipmapLodBias() const { return 1 - (textureQuality / 100.f); }
constexpr int getAnisotropy() const { return textureSharpness >= 1 ? (1 << (textureSharpness - 1)) : 0; }
};
/// Rendering plateform interface
@ -64,13 +67,16 @@ public:
/// Start new frame and setup
virtual void beginFrame() = 0;
/// Get started world program
virtual std::function<size_t(render::LodModel *const, glm::mat4)> beginWorldPass() = 0;
/// (vertex buffer, model matrix, sphereProj, curvature)
virtual std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() = 0;
/// Get started entity program
virtual std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> beginEntityPass() = 0;
/// Draw cube indicator
virtual size_t drawIndicatorCube(glm::mat4 model) = 0;
virtual std::function<size_t(glm::mat4)> beginIndicatorPass() = 0;
/// Apply postprocessing
virtual void endPass() = 0;
virtual void postProcess() = 0;
/// Finalise frame
virtual void endFrame() = 0;
/// Swap displayed image
virtual void swapBuffer(Window &) = 0;
@ -78,7 +84,6 @@ public:
virtual void lookFrom(const Camera &) = 0;
virtual void setClearColor(glm::vec4) = 0;
virtual void setCurvature(glm::vec4, float) = 0;
virtual void reloadShaders(const passOptions &) = 0;
virtual void reloadTextures(const std::string &, float mipMapLOD, float anisotropy) = 0;

View File

@ -106,10 +106,12 @@ UI::Actions UI::draw(config::client::options &options, state::state &state, cons
actions |= Actions::FillMode;
}
ImGui::Text("Textures '%s'", options.renderer.textures.c_str()); // MAYBE: select
if (ImGui::SliderFloat("LOD", &options.renderer.mipMapLOD, -1, 1) |
ImGui::SliderInt("Anisotropy", &options.renderer.anisotropy, 0, 8)) {
if (ImGui::SliderInt("Quality", &options.renderer.textureQuality, 0, 200, "%d%%") |
ImGui::SliderInt("Sharpness", &options.renderer.textureSharpness, 0, 8)) {
actions |= Actions::RendererTextures;
}
if(ImGui::IsItemHovered())
ImGui::SetTooltip("Better texture quality especially at low angles");
ImGui::End();
}

View File

@ -3,6 +3,8 @@
using namespace render;
std::unique_ptr<Texture> (*Texture::loadFunc)(const std::string&, const sampling&) = nullptr;
std::unique_ptr<TextureCube> (*TextureCube::loadFunc)(const std::array<std::string, 6>&, const Texture::sampling &) = nullptr;
std::unique_ptr<TextureArray> (*TextureArray::loadFunc)(const std::vector<std::string>&, const Texture::sampling &) = nullptr;
#include <stdio.h>
#include <string.h>
@ -12,7 +14,7 @@ std::unique_ptr<Texture> (*Texture::loadFunc)(const std::string&, const sampling
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
std::optional<Image::properties> Image::Read(const std::string& imagepath, std::vector<unsigned char>& data) {
std::optional<Image::properties> Image::Read(const std::string& imagepath, std::vector<unsigned char>& data, bool srgb) {
unsigned char header[124];
properties info;
@ -54,15 +56,18 @@ std::optional<Image::properties> Image::Read(const std::string& imagepath, std::
switch(fourCC)
{
case FOURCC_DXT3:
info.format = Format::BC2;
info.format = srgb ? Format::BC2 : Format::BC2_UNORM;
break;
case FOURCC_DXT5:
info.format = Format::BC3;
info.format = srgb ? Format::BC3 : Format::BC3_UNORM;
break;
//MAYBE: VK_FORMAT_BC6H_SFLOAT_BLOCK
default:
return {};
}
//FIXME: miplevels with size < block size (2 last) are corrupted
const uint maxMipmapLevels = 1 + std::floor(std::log2(std::max(info.size.height, info.size.width))) - 2;
info.mipmapLevels = std::min(maxMipmapLevels, info.mipmapLevels);
return info;
}

View File

@ -20,8 +20,10 @@ public:
enum class Format {
/// DXT3 RGBA SRGB
BC2 = 136,
BC2_UNORM = 135,
/// DXT5 RGBA SRGB
BC3 = 138,
BC3_UNORM = 137,
// MAYBE: R8G8B8A8
// MAYBE: For HDR BC6H_SFLOAT = 144,
};
@ -73,23 +75,27 @@ public:
};
struct requirement: properties {
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
int samples = 1, bool optimal = true): properties(props), layout(layout),
usage(usage), aspect(aspect), samples(samples), optimal(optimal)
int samples = 1, uint32_t layers = 1, bool cube = false, bool optimal = true):
properties(props), layout(layout), usage(usage), aspect(aspect), samples(samples),
layers(layers), cube(cube), optimal(optimal)
{
assert(samples > 0 && (std::ceil(std::log2(samples)) == std::floor(std::log2(samples))) && "Samples must be pow2");
assert(!cube || layers == 6);
}
Layout layout;
Usage usage;
Aspect aspect;
//NOTE: matches VkSampleCountFlagBits
int samples;
uint32_t layers;
bool cube;
bool optimal;
static requirement Texture(const properties &props) {
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR); }
static requirement Texture(const properties &props, uint32_t arraySize = 1, bool cube = false) {
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR, 1, arraySize, cube); }
};
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data, bool srgb = true);
};
/// Const image (single texture2D) with sampler
@ -108,6 +114,7 @@ public:
Wrap wrap = Wrap::MIRRORED_REPEAT;
int anisotropy = 0;
bool mipmap = true;
float mipmapLod = 0;
};
/// Only supports dds files
@ -120,4 +127,36 @@ public:
protected:
static std::unique_ptr<Texture> (*loadFunc)(const std::string&, const sampling&);
};
/// Const 6 dept image (single textureCube) with sampler
class TextureCube: public Image {
public:
/// Only supports dds files
/// DXT3(BC2) DXT5(BC3)
static _FORCE_INLINE_ std::unique_ptr<TextureCube> LoadFromFiles(const std::array<std::string, 6> &paths, const Texture::sampling &props) {
assert(loadFunc != nullptr && "Uninitialized renderer");
return loadFunc(paths, props);
}
protected:
static std::unique_ptr<TextureCube> (*loadFunc)(const std::array<std::string, 6>&, const Texture::sampling&);
};
/// Const image array (textureArray) with sampler
class TextureArray: public Image {
public:
/// Only supports dds files
/// DXT3(BC2) DXT5(BC3)
static _FORCE_INLINE_ std::unique_ptr<TextureArray> LoadFromFiles(const std::vector<std::string> &paths, const Texture::sampling &props) {
assert(loadFunc != nullptr && "Uninitialized renderer");
return loadFunc(paths, props);
}
constexpr uint32_t getSize() const { return size; }
protected:
TextureArray(uint32_t size): size(size) { }
uint32_t size;
static std::unique_ptr<TextureArray> (*loadFunc)(const std::vector<std::string>&, const Texture::sampling&);
};
}

View File

@ -7,6 +7,22 @@ using namespace render;
std::unique_ptr<Model> (*Model::createFunc)(const Data&) = nullptr;
std::unique_ptr<LodModel> (*LodModel::createFunc)(const LodData&) = nullptr;
const std::vector<glm::vec3> Shape::SKY_CUBE = {
{-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f},
{-1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
{ 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f},
{-1.0f, -1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, -1.0f},
{-1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}
};
const std::pair<std::vector<glm::vec3>, std::vector<glm::vec4>> Indicator::CUBE = {{
{0, 0, 0}, {0, 0, 1}, {0, 0, 1}, {0, 1, 1}, {0, 1, 1}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {1, 0, 1}, {1, 1, 1},
{1, 1, 1}, {1, 1, 0}, {1, 1, 0}, {1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}, {0, 1, 0}, {1, 1, 0}
}, {
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
}};
void indexVBO(const std::vector<PackedVertexData> &in_vertices, std::vector<glm::u16> &out_indices, std::vector<PackedVertexData> &out_vertices);
Model::Data::Data(const std::vector<PackedVertexData> &vs, const std::vector<glm::u16> &indices): indices(indices), vertices(vs) { }

View File

@ -39,10 +39,20 @@ struct PackedVertexData {
};
};
/// Position only buffer
class Shape {
public:
virtual ~Shape() { }
static const std::vector<glm::vec3> SKY_CUBE;
};
/// Color lines model
class Indicator {
public:
virtual ~Indicator() { }
static const std::pair<std::vector<glm::vec3>, std::vector<glm::vec4>> CUBE;
};
/// VertexData model with index

View File

@ -14,34 +14,11 @@ using namespace render::gl;
constexpr auto GL_MAJOR = 4;
constexpr auto GL_MINOR = 6;
#define CONTENT_DIR "content/"
#define TEXTURES_DIR CONTENT_DIR "textures/"
Renderer::Renderer(const renderOptions& options):
IndicatorCubeBuffer({
glm::vec3(0, 0, 0), glm::vec3(0, 0, 1),
glm::vec3(0, 0, 1), glm::vec3(0, 1, 1),
glm::vec3(0, 1, 1), glm::vec3(0, 1, 0),
glm::vec3(0, 1, 0), glm::vec3(0, 0, 0),
glm::vec3(1, 0, 0), glm::vec3(1, 0, 1),
glm::vec3(1, 0, 1), glm::vec3(1, 1, 1),
glm::vec3(1, 1, 1), glm::vec3(1, 1, 0),
glm::vec3(1, 1, 0), glm::vec3(1, 0, 0),
glm::vec3(0, 0, 0), glm::vec3(1, 0, 0),
glm::vec3(0, 0, 1), glm::vec3(1, 0, 1),
glm::vec3(0, 1, 1), glm::vec3(1, 1, 1),
glm::vec3(0, 1, 0), glm::vec3(1, 1, 0),
}, {
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
}) {
IndicatorCubeBuffer(Indicator::CUBE.first, Indicator::CUBE.second) {
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
@ -51,7 +28,7 @@ Renderer::Renderer(const renderOptions& options):
IndicatorPass = std::make_unique<pass::ColorProgram>();
FogColor = glm::vec3(options.clear_color.x, options.clear_color.y, options.clear_color.z);
loadTextures(options.textures, options.mipMapLOD, options.anisotropy);
loadTextures(options.textures, options.getMipmapLodBias(), options.getAnisotropy());
}
Renderer::~Renderer() {
@ -115,11 +92,11 @@ void Renderer::beginFrame() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
std::function<size_t(render::LodModel *const, glm::mat4)> Renderer::beginWorldPass() {
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() {
WorldPass->useIt();
WorldPass->start(this);
return [&](render::LodModel *const buf, glm::mat4 model) {
WorldPass->setup(this, model);
return [&](render::LodModel *const buf, glm::mat4 model, glm::vec4 sph, float curv) {
WorldPass->setup(model, sph, curv);
return dynamic_cast<LodModel *const>(buf)->draw();
};
}
@ -128,22 +105,25 @@ std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> Rend
EntityPass->useIt();
EntityPass->start(this);
return [&](render::Model *const buf, const std::vector<glm::mat4> &models) {
EntityPass->setup(this, models);
EntityPass->setup(models);
return dynamic_cast<Model *const>(buf)->drawInstanced(models.size());
};
}
size_t Renderer::drawIndicatorCube(glm::mat4 model) {
std::function<size_t(glm::mat4)> Renderer::beginIndicatorPass() {
IndicatorPass->useIt();
IndicatorPass->setup(this, model);
return IndicatorCubeBuffer.draw();
return [&](glm::mat4 model) {
IndicatorPass->setup(this, model);
return IndicatorCubeBuffer.draw();
};
}
void Renderer::endPass() {
void Renderer::postProcess() {
if(SkyEnable) {
SkyPass->draw(this);
}
}
void Renderer::endFrame() { }
void Renderer::swapBuffer(Window& w) {
TracyGpuZone("Swap");
@ -161,21 +141,25 @@ void Renderer::reloadTextures(const std::string& texturePath, float mipMapLOD, f
}
void Renderer::unloadTextures() {
glDeleteTextures(1, &HOSAtlas);
glDeleteTextures(1, &NormalAtlas);
glDeleteTextures(1, &TextureAtlas);
HOSAtlas.reset();
NormalAtlas.reset();
TextureAtlas.reset();
}
void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) {
std::vector<std::string> terrainTextures;
for(const auto& texture: world::materials::textures) {
terrainTextures.emplace_back(texturePath + "/terrain/" + texture);
}
const auto ani = anisotropy >= 1 ? (1 << (static_cast<int>(anisotropy)-1)) : 0;
TextureAtlas = pass::Program::loadTextureArray(terrainTextures, "", mipMapLOD, ani);
NormalAtlas = pass::Program::loadTextureArray(terrainTextures, ".nrm", mipMapLOD, ani);
HOSAtlas = pass::Program::loadTextureArray(terrainTextures, ".hos", mipMapLOD, ani);
auto makePaths = [&](const std::string& suffix) {
terrainTextures.clear();
for(const auto& texture: world::materials::textures) {
terrainTextures.emplace_back(TEXTURES_DIR + texturePath + "/terrain/" + texture + suffix + ".dds");
}
return terrainTextures;
};
auto sampling = Texture::sampling{true, true, Texture::Wrap::REPEAT, anisotropy, true, mipMapLOD};
TextureAtlas = TextureArray::LoadFromFiles(makePaths(""), sampling);
NormalAtlas = TextureArray::LoadFromFiles(makePaths(".nrm"), sampling);
HOSAtlas = TextureArray::LoadFromFiles(makePaths(".hos"), sampling);
Skybox = pass::Program::loadTextureCube(texturePath + "/sky/Space_tray");
Skybox = TextureCube::LoadFromFiles(TEXTURES_DIR + texturePath + "/sky/Space_tray.cube", {});
}
void Renderer::lookFrom(const Camera& camera) {
@ -188,7 +172,3 @@ void Renderer::setClearColor(glm::vec4 c) {
FogColor = c;
glClearColor(c.r, c.g, c.b, c.a);
}
void Renderer::setCurvature(glm::vec4 sp, float c) {
SphereProj = sp;
Curvature = c;
}

View File

@ -7,6 +7,7 @@
#include "pass/SkyProgram.hpp"
#include "pass/ColorProgram.hpp"
#include "api/Models.hpp"
#include "api/Images.hpp"
namespace render::gl {
@ -28,33 +29,27 @@ public:
}
GLuint getTextureAtlas() const {
return TextureAtlas;
return TextureAtlas->getId();
}
GLuint getNormalAtlas() const {
return NormalAtlas;
return NormalAtlas->getId();
}
GLuint getHOSAtlas() const {
return HOSAtlas;
return HOSAtlas->getId();
}
GLuint getSkyTexture() const {
return Skybox;
return Skybox->getId();
}
void beginFrame() override;
std::function<size_t(render::LodModel *const, glm::mat4)> beginWorldPass() override;
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() override;
std::function<size_t(render::Model *const, const std::vector<glm::mat4>&)> beginEntityPass() override;
size_t drawIndicatorCube(glm::mat4 model) override;
void endPass() override;
std::function<size_t(glm::mat4)> beginIndicatorPass() override;
void postProcess() override;
void endFrame() override;
void swapBuffer(Window&) override;
void setClearColor(glm::vec4) override;
void setCurvature(glm::vec4, float) override;
glm::vec4 getSphereProj() const {
return SphereProj;
}
float getCurvature() const {
return Curvature;
}
/// Apply camera matrices
void lookFrom(const Camera&) override;
@ -79,16 +74,10 @@ private:
glm::mat4 ProjectionMatrix;
glm::mat4 ViewMatrix;
GLuint TextureAtlas;
GLuint NormalAtlas;
GLuint HOSAtlas;
GLuint Skybox;
/// Sphere bending
/// offset.xyz radius.w
glm::vec4 SphereProj;
/// Ratio between spherical and cartesian
float Curvature;
std::unique_ptr<TextureArray> TextureAtlas;
std::unique_ptr<TextureArray> NormalAtlas;
std::unique_ptr<TextureArray> HOSAtlas;
std::unique_ptr<TextureCube> Skybox;
/// Draw skybox
bool SkyEnable;

Some files were not shown because too many files have changed in this diff Show More