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

View File

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

View File

@ -1,9 +1,9 @@
#version 450 core #version 450 core
layout(push_constant) uniform PushConstants { layout(binding = 0) uniform UniformBufferObject {
mat4 View; mat4 view;
mat4 Projection; mat4 proj;
} Push; } UBO;
layout (location = 0) in vec3 Position_modelspace; layout (location = 0) in vec3 Position_modelspace;
@ -11,5 +11,7 @@ layout (location = 0) out vec3 UV;
void main(){ void main(){
UV = Position_modelspace; 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 #extension GL_ARB_separate_shader_objects : enable
layout(binding = 0) uniform UniformBufferObject { layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view; mat4 view;
mat4 proj; mat4 proj;
} ubo; } UBO;
layout(push_constant) uniform PushConst {
mat4 model;
} Push;
layout(location = 0) in vec3 inPosition; layout(location = 0) in vec3 Position_modelspace;
layout(location = 1) in vec3 inColor; layout(location = 1) in vec3 Color_model;
layout(location = 2) in vec2 inTexCoord; layout(location = 2) in vec2 TexCoord_model;
layout(location = 0) out vec3 fragColor; layout(location = 0) out vec3 Color;
layout(location = 1) out vec2 fragTexCoord; layout(location = 1) out vec2 TexCoord;
void main() { void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0); gl_Position = UBO.proj * UBO.view * Push.model * vec4(Position_modelspace, 1.0);
fragColor = inColor; Color = Color_model;
fragTexCoord = inTexCoord; 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 (constant_id = 16) const int UNIT_SIZE = 8;
layout (binding = 0) uniform UniformBufferObject { layout (binding = 0) uniform UniformBufferObject {
vec3 FogColor; mat4 view;
float FogDepth; mat4 proj;
vec3 LightInvDirection_worldspace; vec3 lightInvDirection_worldspace;
vec4 fog; //color.rgb depth.a
} UBO; } UBO;
layout (binding = 1) uniform sampler2DArray TextureAtlas; layout (binding = 1) uniform sampler2DArray TextureAtlas;
layout (binding = 2) uniform sampler2DArray NormalAtlas; layout (binding = 2) uniform sampler2DArray NormalAtlas;
layout (binding = 3) uniform sampler2DArray HOSAtlas; 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 #ifdef GEOMETRY
layout (location = 0) in GeometryData layout (location = 0) in GeometryData
#else #else
@ -52,7 +43,7 @@ layout (location = 0) in VertexData
float Depth; float Depth;
} vs; } vs;
layout(location = 0) out vec3 color; layout(location = 0) out vec4 color;
vec3 expand(vec3 v) { vec3 expand(vec3 v) {
return (v - 0.5) * 2; return (v - 0.5) * 2;
@ -133,7 +124,7 @@ vec3 getTriTexture(sampler2DArray smpl, vec2 crdx, vec2 crdy, vec2 crdz, vec3 we
void main() { void main() {
float texScale = 1. / UNIT_SIZE; float texScale = 1. / UNIT_SIZE;
vec3 tex, texN, worldNormal, texHOS; vec3 tex, worldNormal, texHOS;
if(TRIPLANAR) { if(TRIPLANAR) {
// Triplanar // Triplanar
@ -147,7 +138,7 @@ if(TRIPLANAR) {
vec2 UVy = vs.Position_modelspace.zx * texScale; vec2 UVy = vs.Position_modelspace.zx * texScale;
vec2 UVz = vs.Position_modelspace.xy * 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) { if(PBR) {
// Whiteout normal blend // Whiteout normal blend
@ -159,9 +150,9 @@ if(PBR) {
texNy = vec3(texNy.xy + vs.FaceNormal_worldspace.xz, abs(texNy.z) * vs.FaceNormal_worldspace.y); 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); texNz = vec3(texNz.xy + vs.FaceNormal_worldspace.xy, abs(texNz.z) * vs.FaceNormal_worldspace.z);
// Swizzle tangent normals to match world orientation and triblend // 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 { } else {
// Cheap planar // Cheap planar
@ -169,16 +160,16 @@ if(PBR) {
vec3 nrm = normalize(pow(blendWeights, vec3(80 / sqrt(UNIT_SIZE)))); 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; 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) { if(PBR) {
vec3 texN = expand(getTexture(NormalAtlas, UV).rgb); vec3 texN = expand(getTexture(NormalAtlas, UV).rgb);
// Swizzle world normals into tangent space and apply Whiteout blend // Swizzle world normals into tangent space and apply Whiteout blend
// Swizzle tangent normals to match world orientation and triblend // 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.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(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 TextureAmbientColor = vec3(.1) * TextureDiffuseColor * texHOS.y;
vec3 TextureSpecularColor = vec3(.8) * texHOS.z; 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 // Light emission properties
// You probably want to put them as uniforms // You probably want to put them as uniforms
@ -222,22 +213,21 @@ if(PBR) {
// MAYBE: shadow // MAYBE: shadow
color = tex =
// Ambient : simulates indirect lighting // Ambient : simulates indirect lighting
TextureAmbientColor + TextureAmbientColor +
// Diffuse : "color" of the object // Diffuse : "color" of the object
visibility * TextureDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) + visibility * TextureDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) +
// Specular : reflective highlight, like a mirror // Specular : reflective highlight, like a mirror
visibility * TextureSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance * distance); visibility * TextureSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance * distance);
} else {
color = tex;
} }
if(FOG) { if(FOG) {
float ratio = exp(vs.Depth * 0.69)-1; 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)); //TODO: check gamma color = pow(color, vec3(1.0 / 2.2));
if(color.r > 1 || color.g > 1 || color.b > 1) { color = vec4(tex, 1);
color = vec3(1, 0, 0); //TODO: bloom /*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; } gs;
void main() { 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++) { for(int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position; gl_Position = gl_in[i].gl_Position;
gs.Position_modelspace = vs_in[i].Position_modelspace; gs.Position_modelspace = vs_in[i].Position_modelspace;
gs.FaceNormal_modelspace = vs_in[i].FaceNormal_modelspace; gs.FaceNormal_modelspace = vs_in[i].FaceNormal_modelspace;
gs.Textures[i] = vs_in[i].Texture;
switch(int(mod(i,3))) { switch(int(mod(i,3))) {
case 0: case 0:
gs.TextureRatio = vec3(1,0,0); gs.TextureRatio = vec3(1,0,0);
@ -60,9 +62,6 @@ if(PBR) {
gs.EyeDirection_cameraspace = vs_in[i].EyeDirection_cameraspace; gs.EyeDirection_cameraspace = vs_in[i].EyeDirection_cameraspace;
gs.LightDirection_cameraspace = vs_in[i].LightDirection_cameraspace; gs.LightDirection_cameraspace = vs_in[i].LightDirection_cameraspace;
} }
#ifdef SHADOW
gs.ShadowCoord = vs_in[i].ShadowCoord;
#endif
if(FOG) { if(FOG) {
gs.Depth = vs_in[i].Depth; 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 (constant_id = 6) const bool CURV_DEPTH = true;
layout (binding = 0) uniform UniformBufferObject { layout (binding = 0) uniform UniformBufferObject {
vec3 FogColor; mat4 view;
float FogDepth; mat4 proj;
vec3 LightInvDirection_worldspace; vec3 lightInvDirection_worldspace;
vec4 fog; //color.rgb depth.a
} UBO; } UBO;
layout(push_constant) uniform PushConstants { layout(push_constant) uniform PushConst {
mat4 Proj; //MAYBE: move Proj View to UBO
mat4 View;
#ifndef INSTANCED #ifndef INSTANCED
mat4 Model; mat4 model;
#endif #endif
vec4 SphereProj; vec4 sphereProj;
float Curvature; float curvature;
} Push; } Push;
layout (location = 0) in vec3 Position_modelspace; layout (location = 0) in vec3 Position_modelspace;
@ -47,27 +47,27 @@ layout (location = 0) out VertexData {
void main(){ void main(){
#ifndef INSTANCED #ifndef INSTANCED
mat4 Model = Push.Model; mat4 Model = Push.model;
#endif #endif
vs.Position_modelspace = Position_modelspace; vs.Position_modelspace = Position_modelspace;
if(DO_CURVATURE) { if(DO_CURVATURE) {
if(Push.Curvature > 0) { if(Push.curvature > 0) {
vec3 Position_areaspace = Position_modelspace + Push.SphereProj.xyz; 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)); vec2 sph = vec2(acos(Position_areaspace.z / length(Position_areaspace.xyz)), atan(Position_areaspace.y, Position_areaspace.x));
float radius = CURV_DEPTH ? float radius = CURV_DEPTH ?
max(max(abs(Position_areaspace.x), abs(Position_areaspace.y)), abs(Position_areaspace.z)) : max(max(abs(Position_areaspace.x), abs(Position_areaspace.y)), abs(Position_areaspace.z)) :
Push.SphereProj.w; 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); 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); vec4 Position_cameraspace = UBO.view * Model * vec4(vs.Position_modelspace, 1);
gl_Position = Push.Proj * Position_cameraspace; gl_Position = UBO.proj * Position_cameraspace;
if(FOG) { if(FOG) {
vs.Depth = length(Position_cameraspace.xyz) / UBO.FogDepth; vs.Depth = length(Position_cameraspace.xyz) / UBO.fog.a;
} }
vs.Texture = Texture_model; vs.Texture = Texture_model;
@ -82,6 +82,6 @@ if(PBR) {
vs.EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace.xyz; vs.EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace.xyz;
// Vector that goes from the vertex to the light, in camera space // 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 # Voxel
$GLSL $BASEDIR/Voxel.vert -o $TARGETDIR/Voxel.vs.spv $GLSL $BASEDIR/Voxel.vert -o $TARGETDIR/Voxel.vs.spv
$GLSL $BASEDIR/Voxel.frag -o $TARGETDIR/Voxel.fs.spv $GLSL $BASEDIR/Voxel.frag -o $TARGETDIR/Voxel.fs.spv
$GLSL $BASEDIR/Voxel.vert -DINSTANCED -o $TARGETDIR/Voxel.vs.ins.spv $GLSL $BASEDIR/Voxel.vert -DINSTANCED -o $TARGETDIR/Voxel.ins.vs.spv
$GLSL $BASEDIR/Voxel.frag -DINSTANCED -o $TARGETDIR/Voxel.fs.ins.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.vert -DGEOMETRY -o $TARGETDIR/Voxel.geo.vs.spv
$GLSL $BASEDIR/Voxel.geom -DGEOMETRY -o $TARGETDIR/Voxel.gs.geo.spv $GLSL $BASEDIR/Voxel.geom -DGEOMETRY -o $TARGETDIR/Voxel.geo.gs.spv
$GLSL $BASEDIR/Voxel.frag -DGEOMETRY -o $TARGETDIR/Voxel.fs.geo.spv $GLSL $BASEDIR/Voxel.frag -DGEOMETRY -o $TARGETDIR/Voxel.geo.fs.spv
$GLSL $BASEDIR/Voxel.vert -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.vs.geo.ins.spv $GLSL $BASEDIR/Voxel.vert -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.geo.ins.vs.spv
$GLSL $BASEDIR/Voxel.geom -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.gs.geo.ins.spv $GLSL $BASEDIR/Voxel.geom -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.geo.ins.gs.spv
$GLSL $BASEDIR/Voxel.frag -DGEOMETRY -DINSTANCED -o $TARGETDIR/Voxel.fs.geo.ins.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_COLOR.jpg terrain/Water.dds
Water_002_HOS.jpg terrain/Water.hos.dds Water_002_HOS.jpg terrain/Water.hos.dds
Water_002_NORM.jpg terrain/Water.nrm.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.back.png sky/Space_orange.cube.back.dds
Space_orange.cube.bottom.png sky/Space_orange.cube.bottom.dds Space_orange.cube.bottom.png sky/Space_orange.cube.bottom.dds
Space_orange.cube.front.png sky/Space_orange.cube.front.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); auto world = world::client::Load(options.connection, localHandle, options.world, options.contouring);
state.contouring = world->getContouring(); state.contouring = world->getContouring();
//TODO: loop
do { do {
window.startFrame(); window.startFrame();
FrameMark; FrameMark;
@ -56,7 +55,7 @@ void Client::run(server_handle* const localHandle) {
} }
camera.update(); camera.update();
pipeline->lookFrom(camera); 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); 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); pipeline->reloadShaders(options.renderer.voxel);
} }
if(actions && render::UI::Actions::RendererTextures) { 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) { if(actions && render::UI::Actions::World) {
//FIXME: server options world->setOptions(options.world); //FIXME: server options world->setOptions(options.world);
@ -131,9 +130,8 @@ void Client::run(server_handle* const localHandle) {
{ // Chunks { // Chunks
const auto pass = pipeline->beginWorldPass(); 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) { 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.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) { if (options.culling > 0) {
std::vector<glm::vec3> occlusion; std::vector<glm::vec3> occlusion;
@ -161,14 +159,17 @@ void Client::run(server_handle* const localHandle) {
};*/ };*/
//world->getEntitiesModels(draw, frustum, offset, options.voxel_density); //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)); const auto pass = pipeline->beginIndicatorPass();
reports.models_count++; if(state.look_at.has_value()) { // Indicator
reports.tris_count += pipeline->drawIndicatorCube(model); 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(); render::UI::Get()->render();
pipeline->endFrame();
} }
{ // Swap buffers { // Swap buffers
@ -180,9 +181,10 @@ void Client::run(server_handle* const localHandle) {
window.waitTargetFPS(); window.waitTargetFPS();
} while (!(inputs.isDown(Input::Quit) || window.shouldClose())); } while (!(inputs.isDown(Input::Quit) || window.shouldClose()));
options.contouring = state.contouring->getOptions();
world.reset();
render::UI::Unload(); render::UI::Unload();
render::Renderer::Unload(); render::Renderer::Unload();
window.destroy(); window.destroy();
options.contouring = state.contouring->getOptions();
} }

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ struct passOptions {
/// Transform texture UV /// Transform texture UV
bool stochastic = false; bool stochastic = false;
/// Active geometry pass /// Active geometry pass
bool geometry = false; bool geometry = true;
/// Blend voxel with mixed materials (requires geometry) /// Blend voxel with mixed materials (requires geometry)
bool blend = true; bool blend = true;
/// Depth fog /// Depth fog
@ -44,14 +44,17 @@ struct renderOptions {
/// Texture pack name /// Texture pack name
std::string textures = "1024-realistic"; std::string textures = "1024-realistic";
/// Textures quality /// Textures quality
float mipMapLOD = -.5; int textureQuality = 100;
/// Textures anisotropic mapping /// Textures anisotropic mapping
int anisotropy = 0; int textureSharpness = 0;
/// Depth color /// Depth color
glm::vec4 clear_color; glm::vec4 clear_color;
/// Parallel processing frames /// Parallel processing frames
/// Incease FPS but also a bit latency (Vulkan only) /// Incease FPS but also a bit latency (Vulkan only)
int inFlightFrames = 2; 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 /// Rendering plateform interface
@ -64,13 +67,16 @@ public:
/// Start new frame and setup /// Start new frame and setup
virtual void beginFrame() = 0; virtual void beginFrame() = 0;
/// Get started world program /// 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 /// Get started entity program
virtual std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> beginEntityPass() = 0; virtual std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> beginEntityPass() = 0;
/// Draw cube indicator /// Draw cube indicator
virtual size_t drawIndicatorCube(glm::mat4 model) = 0; virtual std::function<size_t(glm::mat4)> beginIndicatorPass() = 0;
/// Apply postprocessing /// Apply postprocessing
virtual void endPass() = 0; virtual void postProcess() = 0;
/// Finalise frame
virtual void endFrame() = 0;
/// Swap displayed image /// Swap displayed image
virtual void swapBuffer(Window &) = 0; virtual void swapBuffer(Window &) = 0;
@ -78,7 +84,6 @@ public:
virtual void lookFrom(const Camera &) = 0; virtual void lookFrom(const Camera &) = 0;
virtual void setClearColor(glm::vec4) = 0; virtual void setClearColor(glm::vec4) = 0;
virtual void setCurvature(glm::vec4, float) = 0;
virtual void reloadShaders(const passOptions &) = 0; virtual void reloadShaders(const passOptions &) = 0;
virtual void reloadTextures(const std::string &, float mipMapLOD, float anisotropy) = 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; actions |= Actions::FillMode;
} }
ImGui::Text("Textures '%s'", options.renderer.textures.c_str()); // MAYBE: select ImGui::Text("Textures '%s'", options.renderer.textures.c_str()); // MAYBE: select
if (ImGui::SliderFloat("LOD", &options.renderer.mipMapLOD, -1, 1) | if (ImGui::SliderInt("Quality", &options.renderer.textureQuality, 0, 200, "%d%%") |
ImGui::SliderInt("Anisotropy", &options.renderer.anisotropy, 0, 8)) { ImGui::SliderInt("Sharpness", &options.renderer.textureSharpness, 0, 8)) {
actions |= Actions::RendererTextures; actions |= Actions::RendererTextures;
} }
if(ImGui::IsItemHovered())
ImGui::SetTooltip("Better texture quality especially at low angles");
ImGui::End(); ImGui::End();
} }

View File

@ -3,6 +3,8 @@
using namespace render; using namespace render;
std::unique_ptr<Texture> (*Texture::loadFunc)(const std::string&, const sampling&) = nullptr; 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 <stdio.h>
#include <string.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_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" 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]; unsigned char header[124];
properties info; properties info;
@ -54,15 +56,18 @@ std::optional<Image::properties> Image::Read(const std::string& imagepath, std::
switch(fourCC) switch(fourCC)
{ {
case FOURCC_DXT3: case FOURCC_DXT3:
info.format = Format::BC2; info.format = srgb ? Format::BC2 : Format::BC2_UNORM;
break; break;
case FOURCC_DXT5: case FOURCC_DXT5:
info.format = Format::BC3; info.format = srgb ? Format::BC3 : Format::BC3_UNORM;
break; break;
//MAYBE: VK_FORMAT_BC6H_SFLOAT_BLOCK //MAYBE: VK_FORMAT_BC6H_SFLOAT_BLOCK
default: default:
return {}; 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; return info;
} }

View File

@ -20,8 +20,10 @@ public:
enum class Format { enum class Format {
/// DXT3 RGBA SRGB /// DXT3 RGBA SRGB
BC2 = 136, BC2 = 136,
BC2_UNORM = 135,
/// DXT5 RGBA SRGB /// DXT5 RGBA SRGB
BC3 = 138, BC3 = 138,
BC3_UNORM = 137,
// MAYBE: R8G8B8A8 // MAYBE: R8G8B8A8
// MAYBE: For HDR BC6H_SFLOAT = 144, // MAYBE: For HDR BC6H_SFLOAT = 144,
}; };
@ -73,23 +75,27 @@ public:
}; };
struct requirement: properties { struct requirement: properties {
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect, requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
int samples = 1, bool optimal = true): properties(props), layout(layout), int samples = 1, uint32_t layers = 1, bool cube = false, bool optimal = true):
usage(usage), aspect(aspect), samples(samples), optimal(optimal) 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(samples > 0 && (std::ceil(std::log2(samples)) == std::floor(std::log2(samples))) && "Samples must be pow2");
assert(!cube || layers == 6);
} }
Layout layout; Layout layout;
Usage usage; Usage usage;
Aspect aspect; Aspect aspect;
//NOTE: matches VkSampleCountFlagBits //NOTE: matches VkSampleCountFlagBits
int samples; int samples;
uint32_t layers;
bool cube;
bool optimal; bool optimal;
static requirement Texture(const properties &props) { static requirement Texture(const properties &props, uint32_t arraySize = 1, bool cube = false) {
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR); } 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 /// Const image (single texture2D) with sampler
@ -108,6 +114,7 @@ public:
Wrap wrap = Wrap::MIRRORED_REPEAT; Wrap wrap = Wrap::MIRRORED_REPEAT;
int anisotropy = 0; int anisotropy = 0;
bool mipmap = true; bool mipmap = true;
float mipmapLod = 0;
}; };
/// Only supports dds files /// Only supports dds files
@ -120,4 +127,36 @@ public:
protected: protected:
static std::unique_ptr<Texture> (*loadFunc)(const std::string&, const sampling&); 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<Model> (*Model::createFunc)(const Data&) = nullptr;
std::unique_ptr<LodModel> (*LodModel::createFunc)(const LodData&) = 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); 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) { } 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 /// Color lines model
class Indicator { class Indicator {
public: public:
virtual ~Indicator() { } virtual ~Indicator() { }
static const std::pair<std::vector<glm::vec3>, std::vector<glm::vec4>> CUBE;
}; };
/// VertexData model with index /// VertexData model with index

View File

@ -14,34 +14,11 @@ using namespace render::gl;
constexpr auto GL_MAJOR = 4; constexpr auto GL_MAJOR = 4;
constexpr auto GL_MINOR = 6; constexpr auto GL_MINOR = 6;
#define CONTENT_DIR "content/"
#define TEXTURES_DIR CONTENT_DIR "textures/"
Renderer::Renderer(const renderOptions& options): Renderer::Renderer(const renderOptions& options):
IndicatorCubeBuffer({ IndicatorCubeBuffer(Indicator::CUBE.first, Indicator::CUBE.second) {
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),
}) {
glGenVertexArrays(1, &VertexArrayID); glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID); glBindVertexArray(VertexArrayID);
@ -51,7 +28,7 @@ Renderer::Renderer(const renderOptions& options):
IndicatorPass = std::make_unique<pass::ColorProgram>(); IndicatorPass = std::make_unique<pass::ColorProgram>();
FogColor = glm::vec3(options.clear_color.x, options.clear_color.y, options.clear_color.z); 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() { Renderer::~Renderer() {
@ -115,11 +92,11 @@ void Renderer::beginFrame() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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->useIt();
WorldPass->start(this); WorldPass->start(this);
return [&](render::LodModel *const buf, glm::mat4 model) { return [&](render::LodModel *const buf, glm::mat4 model, glm::vec4 sph, float curv) {
WorldPass->setup(this, model); WorldPass->setup(model, sph, curv);
return dynamic_cast<LodModel *const>(buf)->draw(); 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->useIt();
EntityPass->start(this); EntityPass->start(this);
return [&](render::Model *const buf, const std::vector<glm::mat4> &models) { 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()); 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->useIt();
IndicatorPass->setup(this, model); return [&](glm::mat4 model) {
return IndicatorCubeBuffer.draw(); IndicatorPass->setup(this, model);
return IndicatorCubeBuffer.draw();
};
} }
void Renderer::endPass() { void Renderer::postProcess() {
if(SkyEnable) { if(SkyEnable) {
SkyPass->draw(this); SkyPass->draw(this);
} }
} }
void Renderer::endFrame() { }
void Renderer::swapBuffer(Window& w) { void Renderer::swapBuffer(Window& w) {
TracyGpuZone("Swap"); TracyGpuZone("Swap");
@ -161,21 +141,25 @@ void Renderer::reloadTextures(const std::string& texturePath, float mipMapLOD, f
} }
void Renderer::unloadTextures() { void Renderer::unloadTextures() {
glDeleteTextures(1, &HOSAtlas); HOSAtlas.reset();
glDeleteTextures(1, &NormalAtlas); NormalAtlas.reset();
glDeleteTextures(1, &TextureAtlas); TextureAtlas.reset();
} }
void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) { void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) {
std::vector<std::string> terrainTextures; std::vector<std::string> terrainTextures;
for(const auto& texture: world::materials::textures) { auto makePaths = [&](const std::string& suffix) {
terrainTextures.emplace_back(texturePath + "/terrain/" + texture); terrainTextures.clear();
} for(const auto& texture: world::materials::textures) {
const auto ani = anisotropy >= 1 ? (1 << (static_cast<int>(anisotropy)-1)) : 0; terrainTextures.emplace_back(TEXTURES_DIR + texturePath + "/terrain/" + texture + suffix + ".dds");
TextureAtlas = pass::Program::loadTextureArray(terrainTextures, "", mipMapLOD, ani); }
NormalAtlas = pass::Program::loadTextureArray(terrainTextures, ".nrm", mipMapLOD, ani); return terrainTextures;
HOSAtlas = pass::Program::loadTextureArray(terrainTextures, ".hos", mipMapLOD, ani); };
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) { void Renderer::lookFrom(const Camera& camera) {
@ -188,7 +172,3 @@ void Renderer::setClearColor(glm::vec4 c) {
FogColor = c; FogColor = c;
glClearColor(c.r, c.g, c.b, c.a); 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/SkyProgram.hpp"
#include "pass/ColorProgram.hpp" #include "pass/ColorProgram.hpp"
#include "api/Models.hpp" #include "api/Models.hpp"
#include "api/Images.hpp"
namespace render::gl { namespace render::gl {
@ -28,33 +29,27 @@ public:
} }
GLuint getTextureAtlas() const { GLuint getTextureAtlas() const {
return TextureAtlas; return TextureAtlas->getId();
} }
GLuint getNormalAtlas() const { GLuint getNormalAtlas() const {
return NormalAtlas; return NormalAtlas->getId();
} }
GLuint getHOSAtlas() const { GLuint getHOSAtlas() const {
return HOSAtlas; return HOSAtlas->getId();
} }
GLuint getSkyTexture() const { GLuint getSkyTexture() const {
return Skybox; return Skybox->getId();
} }
void beginFrame() override; 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; std::function<size_t(render::Model *const, const std::vector<glm::mat4>&)> beginEntityPass() override;
size_t drawIndicatorCube(glm::mat4 model) override; std::function<size_t(glm::mat4)> beginIndicatorPass() override;
void endPass() override; void postProcess() override;
void endFrame() override;
void swapBuffer(Window&) override; void swapBuffer(Window&) override;
void setClearColor(glm::vec4) 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 /// Apply camera matrices
void lookFrom(const Camera&) override; void lookFrom(const Camera&) override;
@ -79,16 +74,10 @@ private:
glm::mat4 ProjectionMatrix; glm::mat4 ProjectionMatrix;
glm::mat4 ViewMatrix; glm::mat4 ViewMatrix;
GLuint TextureAtlas; std::unique_ptr<TextureArray> TextureAtlas;
GLuint NormalAtlas; std::unique_ptr<TextureArray> NormalAtlas;
GLuint HOSAtlas; std::unique_ptr<TextureArray> HOSAtlas;
GLuint Skybox; std::unique_ptr<TextureCube> Skybox;
/// Sphere bending
/// offset.xyz radius.w
glm::vec4 SphereProj;
/// Ratio between spherical and cartesian
float Curvature;
/// Draw skybox /// Draw skybox
bool SkyEnable; bool SkyEnable;

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