Two pass transparency
This commit is contained in:
parent
9a095a09ac
commit
7920e8b473
5
TODO.md
5
TODO.md
|
@ -29,7 +29,7 @@
|
||||||
- [~] Occlusion Culling
|
- [~] Occlusion Culling
|
||||||
- [ ] Iterator ray
|
- [ ] Iterator ray
|
||||||
- [ ] Cast from chunk center
|
- [ ] Cast from chunk center
|
||||||
- [ ] Transparency
|
- [x] Transparency
|
||||||
- [ ] Entities
|
- [ ] Entities
|
||||||
|
|
||||||
## Hello universe
|
## Hello universe
|
||||||
|
@ -64,6 +64,7 @@
|
||||||
## Hello darkness
|
## Hello darkness
|
||||||
|
|
||||||
- [ ] Slash screen
|
- [ ] Slash screen
|
||||||
|
- [ ] Start/Pause menu
|
||||||
- [ ] QUIC protocal
|
- [ ] QUIC protocal
|
||||||
- [ ] Use in memory protocol (to replace server_handle)
|
- [ ] Use in memory protocol (to replace server_handle)
|
||||||
- [ ] Octree
|
- [ ] Octree
|
||||||
|
@ -88,3 +89,5 @@
|
||||||
- [ ] Deferred
|
- [ ] Deferred
|
||||||
- [ ] Cascaded shadow maps
|
- [ ] Cascaded shadow maps
|
||||||
- [ ] Ray Tracing
|
- [ ] Ray Tracing
|
||||||
|
- [ ] Translucency
|
||||||
|
- Back face Depth based
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#define UNIT_SIZE 8
|
#define UNIT_SIZE 8
|
||||||
|
|
||||||
// Ouput data
|
// Ouput data
|
||||||
layout(location = 0) out vec3 color;
|
layout(location = 0) out vec4 color;
|
||||||
|
|
||||||
uniform sampler2DArray TextureAtlas;
|
uniform sampler2DArray TextureAtlas;
|
||||||
uniform sampler2DArray NormalAtlas;
|
uniform sampler2DArray NormalAtlas;
|
||||||
|
@ -107,10 +107,10 @@ vec4 getTexture(sampler2DArray sample, vec2 UV) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 getTriTexture(sampler2DArray sample, vec2 crdx, vec2 crdy, vec2 crdz, vec3 weights) {
|
vec4 getTriTexture(sampler2DArray sample, vec2 crdx, vec2 crdy, vec2 crdz, vec3 weights) {
|
||||||
return getTexture(sample, crdx).rgb * weights.x +
|
return getTexture(sample, crdx) * weights.x +
|
||||||
getTexture(sample, crdy).rgb * weights.y +
|
getTexture(sample, crdy) * weights.y +
|
||||||
getTexture(sample, crdz).rgb * weights.z;
|
getTexture(sample, crdz) * weights.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -127,7 +127,7 @@ void main() {
|
||||||
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);
|
vec4 tex = getTriTexture(TextureAtlas, UVx, UVy, UVz, blendWeights);
|
||||||
|
|
||||||
#ifdef PBR
|
#ifdef PBR
|
||||||
// Whiteout normal blend
|
// Whiteout normal blend
|
||||||
|
@ -141,7 +141,7 @@ void main() {
|
||||||
// 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);
|
vec3 worldNormal = normalize(texNx.zyx * blendWeights.x + texNy.xzy * blendWeights.y +texNz.xyz * blendWeights.z);
|
||||||
|
|
||||||
vec3 texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights);
|
vec3 texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights).rgb;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
// Cheap planar
|
// Cheap planar
|
||||||
|
@ -149,7 +149,7 @@ void main() {
|
||||||
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;
|
vec4 tex = getTexture(TextureAtlas, UV);
|
||||||
#ifdef PBR
|
#ifdef 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
|
||||||
|
@ -165,7 +165,7 @@ void main() {
|
||||||
// Colors
|
// Colors
|
||||||
#ifdef PBR
|
#ifdef PBR
|
||||||
// Texture properties
|
// Texture properties
|
||||||
vec3 TextureDiffuseColor = tex;
|
vec3 TextureDiffuseColor = vec3(tex);
|
||||||
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;
|
||||||
|
|
||||||
|
@ -202,22 +202,21 @@ void main() {
|
||||||
|
|
||||||
// MAYBE: shadow
|
// MAYBE: shadow
|
||||||
|
|
||||||
color =
|
color = vec4(
|
||||||
// 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),
|
||||||
|
// Restore alpha
|
||||||
|
tex.a);
|
||||||
#else
|
#else
|
||||||
color = tex;
|
color = tex;
|
||||||
#endif
|
#endif
|
||||||
#if FOG
|
#if FOG
|
||||||
float ratio = exp(vs.Depth * 0.69)-1;
|
float ratio = exp(vs.Depth * 0.69)-1;
|
||||||
color = mix(color, pow(FogColor, vec3(2.2)), clamp(ratio, 0, 1));
|
color = mix(color, vec4(pow(FogColor, vec3(2.2)), 1), clamp(ratio, 0, 1));
|
||||||
#endif
|
#endif
|
||||||
color = pow(color, vec3(1.0 / 2.2));
|
color = pow(color, vec4(vec3(1.0 / 2.2), 1));
|
||||||
if(color.r > 1 || color.g > 1 || color.b > 1) {
|
|
||||||
color = vec3(1, 0, 0); //TODO: bloom
|
|
||||||
}
|
|
||||||
}
|
}
|
BIN
resource/content/shaders/Voxel.fs.spv (Stored with Git LFS)
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)
BIN
resource/content/shaders/Voxel.geo.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.ins.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.ins.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.ins.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.ins.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Water.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Water.dds (Stored with Git LFS)
Binary file not shown.
|
@ -116,15 +116,16 @@ if(BLEND) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 getTriTexture(sampler2DArray smpl, vec2 crdx, vec2 crdy, vec2 crdz, vec3 weights) {
|
vec4 getTriTexture(sampler2DArray smpl, vec2 crdx, vec2 crdy, vec2 crdz, vec3 weights) {
|
||||||
return getTexture(smpl, crdx).rgb * weights.x +
|
return getTexture(smpl, crdx) * weights.x +
|
||||||
getTexture(smpl, crdy).rgb * weights.y +
|
getTexture(smpl, crdy) * weights.y +
|
||||||
getTexture(smpl, crdz).rgb * weights.z;
|
getTexture(smpl, crdz) * weights.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float texScale = 1. / UNIT_SIZE;
|
float texScale = 1. / UNIT_SIZE;
|
||||||
vec3 tex, worldNormal, texHOS;
|
vec4 tex;
|
||||||
|
vec3 worldNormal, texHOS;
|
||||||
|
|
||||||
if(TRIPLANAR) {
|
if(TRIPLANAR) {
|
||||||
// Triplanar
|
// Triplanar
|
||||||
|
@ -152,7 +153,7 @@ if(PBR) {
|
||||||
// Swizzle tangent normals to match world orientation and triblend
|
// Swizzle tangent normals to match world orientation and triblend
|
||||||
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);
|
||||||
|
|
||||||
texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights);
|
texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights).rgb;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cheap planar
|
// Cheap planar
|
||||||
|
@ -160,7 +161,7 @@ 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;
|
||||||
|
|
||||||
tex = getTexture(TextureAtlas, UV).rgb;
|
tex = getTexture(TextureAtlas, UV);
|
||||||
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
|
||||||
|
@ -176,7 +177,7 @@ if(PBR) {
|
||||||
// Colors
|
// Colors
|
||||||
if(PBR) {
|
if(PBR) {
|
||||||
// Texture properties
|
// Texture properties
|
||||||
vec3 TextureDiffuseColor = tex;
|
vec3 TextureDiffuseColor = tex.rgb;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -213,21 +214,20 @@ if(PBR) {
|
||||||
|
|
||||||
// MAYBE: shadow
|
// MAYBE: shadow
|
||||||
|
|
||||||
tex =
|
color = vec4(
|
||||||
// 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),
|
||||||
|
// Restore alpha
|
||||||
|
tex.a);
|
||||||
|
} else {
|
||||||
|
color = tex;
|
||||||
}
|
}
|
||||||
if(FOG) {
|
if(FOG) {
|
||||||
float ratio = exp(vs.Depth * 0.69)-1;
|
float ratio = exp(vs.Depth * 0.69)-1;
|
||||||
tex = mix(tex, UBO.fog.rgb, clamp(ratio, 0, 1));
|
color = mix(color, vec4(UBO.fog.rgb, 1), clamp(ratio, 0, 1));
|
||||||
}
|
}
|
||||||
//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
|
|
||||||
}*/
|
|
||||||
}
|
}
|
BIN
resource/textures-src/1024-realistic/Water_002_COLOR.jpg (Stored with Git LFS)
BIN
resource/textures-src/1024-realistic/Water_002_COLOR.jpg (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
|
@ -34,7 +34,7 @@ Stone_Path_004_normal.jpg terrain/Stone_path.nrm.dds
|
||||||
Stone_Wall_008_COLOR.jpg terrain/Stone_wall.dds
|
Stone_Wall_008_COLOR.jpg terrain/Stone_wall.dds
|
||||||
Stone_Wall_008_HOS.jpg terrain/Stone_wall.hos.dds
|
Stone_Wall_008_HOS.jpg terrain/Stone_wall.hos.dds
|
||||||
Stone_Wall_008_NORM.jpg terrain/Stone_wall.nrm.dds
|
Stone_Wall_008_NORM.jpg terrain/Stone_wall.nrm.dds
|
||||||
Water_002_COLOR.jpg terrain/Water.dds
|
Water_002_COLOR.png 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.back.png sky/Debug.cube.back.dds
|
||||||
|
|
|
@ -137,18 +137,13 @@ void Client::run(server_handle* const localHandle) {
|
||||||
reports.models_count = 0;
|
reports.models_count = 0;
|
||||||
reports.tris_count = 0;
|
reports.tris_count = 0;
|
||||||
std::optional<geometry::Frustum> frustum;
|
std::optional<geometry::Frustum> frustum;
|
||||||
if(options.culling >= 0) {
|
if(options.culling <= 0) {
|
||||||
frustum = {camera.getFrustum()};
|
frustum = {camera.getFrustum()};
|
||||||
}
|
}
|
||||||
const auto offset = state.position.raw_as_long();
|
const auto offset = state.position.raw_as_long();
|
||||||
{ // Chunks
|
{ // Chunks
|
||||||
const auto pass = pipeline->beginWorldPass();
|
std::vector<glm::vec3> occlusion;
|
||||||
const auto draw = [&](glm::mat4 model, render::LodModel *const buffer, const contouring::Abstract::area_info &area, const voxel_pos &pos) {
|
|
||||||
reports.models_count++;
|
|
||||||
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;
|
|
||||||
const auto ratio = options.culling * 2;
|
const auto ratio = options.culling * 2;
|
||||||
occlusion.reserve(glm::pow2(ratio * 2 - 1));
|
occlusion.reserve(glm::pow2(ratio * 2 - 1));
|
||||||
const auto [ch, cv] = player.getAngles();
|
const auto [ch, cv] = player.getAngles();
|
||||||
|
@ -160,9 +155,30 @@ void Client::run(server_handle* const localHandle) {
|
||||||
occlusion.emplace_back(cos(v) * sin(h), sin(v), cos(v) * cos(h));
|
occlusion.emplace_back(cos(v) * sin(h), sin(v), cos(v) * cos(h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.contouring->getModels(draw, player.position, options.camera.far, occlusion, offset, options.voxel_density);
|
}
|
||||||
} else {
|
{ // Solid
|
||||||
state.contouring->getModels(draw, frustum, offset, options.voxel_density);
|
const auto pass = pipeline->beginWorldPass(true);
|
||||||
|
const auto draw = [&](glm::mat4 model, render::LodModel *const buffer, const contouring::Abstract::area_info &area, const voxel_pos &pos) {
|
||||||
|
reports.models_count++;
|
||||||
|
reports.tris_count += pass(buffer, model, glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
|
||||||
|
};
|
||||||
|
if (options.culling > 0) {
|
||||||
|
state.contouring->getModels(draw, player.position, options.camera.far, occlusion, offset, options.voxel_density, true);
|
||||||
|
} else {
|
||||||
|
state.contouring->getModels(draw, frustum, offset, options.voxel_density, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.renderer.voxel.transparency) {
|
||||||
|
const auto pass = pipeline->beginWorldPass(false);
|
||||||
|
const auto draw = [&](glm::mat4 model, render::LodModel *const buffer, const contouring::Abstract::area_info &area, const voxel_pos &pos) {
|
||||||
|
reports.models_count++;
|
||||||
|
reports.tris_count += pass(buffer, model, glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
|
||||||
|
};
|
||||||
|
if (options.culling > 0) {
|
||||||
|
state.contouring->getModels(draw, player.position, options.camera.far, occlusion, offset, options.voxel_density, false);
|
||||||
|
} else {
|
||||||
|
state.contouring->getModels(draw, frustum, offset, options.voxel_density, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // Entities
|
{ // Entities
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
renderer.skybox = config["render"]["skybox"].value_or(renderer.skybox);
|
renderer.skybox = config["render"]["skybox"].value_or(renderer.skybox);
|
||||||
renderer.voxel.curvature = config["render"]["curvature"].value_or(renderer.voxel.curvature);
|
renderer.voxel.curvature = config["render"]["curvature"].value_or(renderer.voxel.curvature);
|
||||||
renderer.voxel.curv_depth = config["render"]["curvature_depth"].value_or(renderer.voxel.curv_depth);
|
renderer.voxel.curv_depth = config["render"]["curvature_depth"].value_or(renderer.voxel.curv_depth);
|
||||||
|
renderer.voxel.transparency = config["render"]["transparency"].value_or(renderer.voxel.transparency);
|
||||||
culling = config["render"]["culling"].value_or(culling);
|
culling = config["render"]["culling"].value_or(culling);
|
||||||
|
|
||||||
contouring = config["contouring"].value_or(std::string(""));
|
contouring = config["contouring"].value_or(std::string(""));
|
||||||
|
@ -120,6 +121,7 @@ public:
|
||||||
{"skybox", renderer.skybox},
|
{"skybox", renderer.skybox},
|
||||||
{"curvature", renderer.voxel.curvature},
|
{"curvature", renderer.voxel.curvature},
|
||||||
{"curvature_depth", renderer.voxel.curv_depth},
|
{"curvature_depth", renderer.voxel.curv_depth},
|
||||||
|
{"transparency", renderer.voxel.transparency},
|
||||||
{"culling", culling}
|
{"culling", culling}
|
||||||
}));
|
}));
|
||||||
config.insert_or_assign("contouring", contouring);
|
config.insert_or_assign("contouring", contouring);
|
||||||
|
@ -191,7 +193,7 @@ public:
|
||||||
|
|
||||||
windowOptions window;
|
windowOptions window;
|
||||||
|
|
||||||
bool preferVulkan = true;
|
bool preferVulkan = false;
|
||||||
render::renderOptions renderer;
|
render::renderOptions renderer;
|
||||||
int culling = 0;
|
int culling = 0;
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,9 @@ namespace contouring {
|
||||||
|
|
||||||
/// Get buffers in frustum with model matrices
|
/// Get buffers in frustum with model matrices
|
||||||
/// @note buffers invalidated after update
|
/// @note buffers invalidated after update
|
||||||
virtual void getModels(draw_call draw, const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density) = 0;
|
virtual void getModels(draw_call draw, const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density, bool solid) = 0;
|
||||||
/// Get buffers hitting occlusion rays with model matrices
|
/// Get buffers hitting occlusion rays with model matrices
|
||||||
/// @note buffers invalidated after update
|
/// @note buffers invalidated after update
|
||||||
virtual void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) = 0;
|
virtual void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -47,8 +47,13 @@ namespace contouring {
|
||||||
loadQueue.wait();
|
loadQueue.wait();
|
||||||
if (loadQueue.pop(ctx)) {
|
if (loadQueue.pop(ctx)) {
|
||||||
ZoneScopedN("ProcessContouring");
|
ZoneScopedN("ProcessContouring");
|
||||||
render::LodModel::LodData data;
|
std::pair<render::LodModel::LodData, render::LodModel::LodData> data;
|
||||||
render(ctx.second, data, tmp);
|
if (transparency) {
|
||||||
|
render(ctx.second, data.first, tmp, Layer::Solid);
|
||||||
|
render(ctx.second, data.second, tmp, Layer::Transparent);
|
||||||
|
} else {
|
||||||
|
render(ctx.second, data.first, tmp, Layer::Both);
|
||||||
|
}
|
||||||
//TODO: direct upload with vulkan
|
//TODO: direct upload with vulkan
|
||||||
loadedQueue.emplace(ctx.first, data);
|
loadedQueue.emplace(ctx.first, data);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +73,8 @@ namespace contouring {
|
||||||
//TODO: prefer unique_ptr
|
//TODO: prefer unique_ptr
|
||||||
for(auto& buffer: buffers) {
|
for(auto& buffer: buffers) {
|
||||||
for(auto& val: buffer.second.second) {
|
for(auto& val: buffer.second.second) {
|
||||||
delete val.second;
|
delete val.second.first;
|
||||||
|
delete val.second.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,20 +135,24 @@ namespace contouring {
|
||||||
|
|
||||||
void FlatDualMC::update(const voxel_pos& pos, const world::client::area_map& areas) {
|
void FlatDualMC::update(const voxel_pos& pos, const world::client::area_map& areas) {
|
||||||
ZoneScopedN("Ct");
|
ZoneScopedN("Ct");
|
||||||
std::pair<area_<chunk_pos>, render::LodModel::LodData> out;
|
std::pair<area_<chunk_pos>, std::pair<render::LodModel::LodData, render::LodModel::LodData>> out;
|
||||||
TracyPlot("CtLoad", static_cast<int64_t>(loadQueue.size()));
|
TracyPlot("CtLoad", static_cast<int64_t>(loadQueue.size()));
|
||||||
//MAYBE: clear out of range loadQueue.trim(keepDistance * keepDistance)
|
//MAYBE: clear out of range loadQueue.trim(keepDistance * keepDistance)
|
||||||
TracyPlot("CtLoaded", static_cast<int64_t>(loadedQueue.size()));
|
TracyPlot("CtLoaded", static_cast<int64_t>(loadedQueue.size()));
|
||||||
for(auto handle = loadedQueue.extractor(); handle.first(out);) {
|
for(auto handle = loadedQueue.extractor(); handle.first(out);) {
|
||||||
const auto buffer = out.second.first.empty() ? NULL : render::LodModel::Create(out.second).release();
|
const auto bufferSolid = out.second.first.first.empty() ? NULL : render::LodModel::Create(out.second.first).release();
|
||||||
|
const auto bufferTrans = out.second.second.first.empty() ? NULL : render::LodModel::Create(out.second.second).release();
|
||||||
auto &bfs = buffers[out.first.first].second; //NOTE: buffer.first uninitialized (will be set in clear())
|
auto &bfs = buffers[out.first.first].second; //NOTE: buffer.first uninitialized (will be set in clear())
|
||||||
if (const auto it = bfs.find(out.first.second); it != bfs.end()) {
|
if (const auto it = bfs.find(out.first.second); it != bfs.end()) {
|
||||||
if(it->second != NULL)
|
if (it->second.first != NULL)
|
||||||
delete it->second;
|
delete it->second.first;
|
||||||
|
if (it->second.second != NULL)
|
||||||
|
delete it->second.second;
|
||||||
|
|
||||||
it->second = buffer;
|
it->second.first = bufferSolid;
|
||||||
|
it->second.second = bufferTrans;
|
||||||
} else {
|
} else {
|
||||||
bfs.emplace(out.first.second, buffer);
|
bfs.emplace(out.first.second, std::make_pair(bufferSolid, bufferTrans));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t buffer_count = 0;
|
size_t buffer_count = 0;
|
||||||
|
@ -165,13 +175,20 @@ namespace contouring {
|
||||||
auto it = bfs.begin();
|
auto it = bfs.begin();
|
||||||
while(it != bfs.end()) {
|
while(it != bfs.end()) {
|
||||||
if (const auto distRatio = glm::length(glm::dvec3(center - it->first)) / keepDistance; distRatio > 1) {
|
if (const auto distRatio = glm::length(glm::dvec3(center - it->first)) / keepDistance; distRatio > 1) {
|
||||||
if(it->second != NULL)
|
if(it->second.first != NULL)
|
||||||
delete it->second;
|
delete it->second.first;
|
||||||
|
if (it->second.second != NULL)
|
||||||
|
delete it->second.second;
|
||||||
|
|
||||||
it = bfs.erase(it);
|
it = bfs.erase(it);
|
||||||
} else {
|
} else {
|
||||||
if(it->second != NULL) {
|
const auto level = std::clamp<size_t>((1 + lod_quality - distRatio) * levelMax * (1 + lod_strength), 0, levelMax);
|
||||||
it->second->setLevel(std::clamp<size_t>((1+lod_quality-distRatio)*levelMax*(1+lod_strength), 0, levelMax));
|
if (it->second.first != NULL) {
|
||||||
|
it->second.first->setLevel(level);
|
||||||
|
buffer_count++;
|
||||||
|
}
|
||||||
|
if (it->second.second != NULL) {
|
||||||
|
it->second.second->setLevel(level);
|
||||||
buffer_count++;
|
buffer_count++;
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
|
@ -180,8 +197,10 @@ namespace contouring {
|
||||||
++it_a;
|
++it_a;
|
||||||
} else {
|
} else {
|
||||||
for(auto& buffer: it_a->second.second) {
|
for(auto& buffer: it_a->second.second) {
|
||||||
if(buffer.second != NULL)
|
if (buffer.second.first != NULL)
|
||||||
delete buffer.second;
|
delete buffer.second.first;
|
||||||
|
if(buffer.second.second != NULL)
|
||||||
|
delete buffer.second.second;
|
||||||
}
|
}
|
||||||
it_a = buffers.erase(it_a);
|
it_a = buffers.erase(it_a);
|
||||||
}
|
}
|
||||||
|
@ -220,7 +239,7 @@ namespace contouring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatDualMC::render(const surrounding::corners &surrounding, render::LodModel::LodData &out, std::vector<render::VertexData> &tmp) const {
|
void FlatDualMC::render(const surrounding::corners &surrounding, render::LodModel::LodData &out, std::vector<render::VertexData> &tmp, Layer layer) const {
|
||||||
const int SIZE = CHUNK_LENGTH + 3;
|
const int SIZE = CHUNK_LENGTH + 3;
|
||||||
std::array<dualmc::DualMC<float>::Point, SIZE * SIZE * SIZE> grid;
|
std::array<dualmc::DualMC<float>::Point, SIZE * SIZE * SIZE> grid;
|
||||||
{
|
{
|
||||||
|
@ -228,7 +247,9 @@ namespace contouring {
|
||||||
const auto setCell = [&](int x, int y, int z, const world::Voxel &voxel) {
|
const auto setCell = [&](int x, int y, int z, const world::Voxel &voxel) {
|
||||||
auto &cell = grid[((z * SIZE) + y) * SIZE + x];
|
auto &cell = grid[((z * SIZE) + y) * SIZE + x];
|
||||||
cell.w = voxel.material();
|
cell.w = voxel.material();
|
||||||
cell.x = voxel.density_ratio() * (!world::materials::invisibility[cell.w] && (transparency || !world::materials::transparency[cell.w]));
|
cell.x = voxel.density_ratio() * (!world::materials::invisibility[cell.w] &&
|
||||||
|
((world::materials::transparency[cell.w] && (layer && Layer::Transparent)) ||
|
||||||
|
(!world::materials::transparency[cell.w] && (layer && Layer::Solid))));
|
||||||
};
|
};
|
||||||
for (int z = 0; z < SIZE; z++) {
|
for (int z = 0; z < SIZE; z++) {
|
||||||
for (int y = 0; y < SIZE; y++) {
|
for (int y = 0; y < SIZE; y++) {
|
||||||
|
@ -303,18 +324,19 @@ namespace contouring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatDualMC::getModels(draw_call out, const std::optional<geometry::Frustum> &frustum, const glm::llvec3& offset, int density) {
|
void FlatDualMC::getModels(draw_call out, const std::optional<geometry::Frustum> &frustum, const glm::llvec3& offset, int density, bool solid) {
|
||||||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
||||||
for (const auto [_, area] : buffers) {
|
for (const auto [_, area] : buffers) {
|
||||||
for (const auto [pos, buffer] : area.second) {
|
for (const auto [pos, buf] : area.second) {
|
||||||
const auto vPos = glm::multiply(pos);
|
const auto vPos = glm::multiply(pos);
|
||||||
const glm::vec3 fPos = (glm::vec3(std::get<0>(area.first).raw_as_long() + vPos - offset * glm::llvec3(density)) + std::get<0>(area.first).offset) / glm::vec3(density);
|
const glm::vec3 fPos = (glm::vec3(std::get<0>(area.first).raw_as_long() + vPos - offset * glm::llvec3(density)) + std::get<0>(area.first).offset) / glm::vec3(density);
|
||||||
|
const auto buffer = solid ? buf.first : buf.second;
|
||||||
if (buffer != NULL && (!frustum.has_value() || frustum.value().contains(geometry::Box::fromMin(fPos, glm::vec3(CHUNK_LENGTH / (float)density)))))
|
if (buffer != NULL && (!frustum.has_value() || frustum.value().contains(geometry::Box::fromMin(fPos, glm::vec3(CHUNK_LENGTH / (float)density)))))
|
||||||
out(glm::translate(scaling, fPos * (float)density), buffer, area.first, vPos);
|
out(glm::translate(scaling, fPos * (float)density), buffer, area.first, vPos);
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatDualMC::getModels(draw_call out, const glm::ifvec3& from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) {
|
void FlatDualMC::getModels(draw_call out, const glm::ifvec3& from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) {
|
||||||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
||||||
const auto start = glm::ifvec3(glm::divide(from.as_voxel(density)));
|
const auto start = glm::ifvec3(glm::divide(from.as_voxel(density)));
|
||||||
const auto dist = far * density / CHUNK_LENGTH;
|
const auto dist = far * density / CHUNK_LENGTH;
|
||||||
|
@ -327,10 +349,11 @@ namespace contouring {
|
||||||
ray.grid(points);
|
ray.grid(points);
|
||||||
for(auto& point: points) {
|
for(auto& point: points) {
|
||||||
auto it = area.second.find(glm::lvec3(point) - area_offset);
|
auto it = area.second.find(glm::lvec3(point) - area_offset);
|
||||||
if(it != area.second.end() && it->second != NULL && done.insert(it->first).second) {
|
const auto buffer = solid ? it->second.first : it->second.second;
|
||||||
|
if(it != area.second.end() && buffer != NULL && done.insert(it->first).second) {
|
||||||
const auto vPos = glm::multiply(it->first);
|
const auto vPos = glm::multiply(it->first);
|
||||||
const glm::vec3 fPos = glm::vec3(std::get<0>(area.first).raw_as_long() + vPos - offset * glm::llvec3(density)) + std::get<0>(area.first).offset;
|
const glm::vec3 fPos = glm::vec3(std::get<0>(area.first).raw_as_long() + vPos - offset * glm::llvec3(density)) + std::get<0>(area.first).offset;
|
||||||
out(glm::translate(scaling, fPos), it->second, area.first, vPos);
|
out(glm::translate(scaling, fPos), buffer, area.first, vPos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,17 +33,17 @@ namespace contouring {
|
||||||
|
|
||||||
/// Get buffers in frustum with model matrices
|
/// Get buffers in frustum with model matrices
|
||||||
/// @note buffers invalidated after update
|
/// @note buffers invalidated after update
|
||||||
void getModels(draw_call draw, const std::optional<geometry::Frustum> &frustum, const glm::llvec3 &offset, int density) override;
|
void getModels(draw_call draw, const std::optional<geometry::Frustum> &frustum, const glm::llvec3 &offset, int density, bool solid) override;
|
||||||
/// Get buffers hitting occlusion rays with model matrices
|
/// Get buffers hitting occlusion rays with model matrices
|
||||||
/// @note buffers invalidated after update
|
/// @note buffers invalidated after update
|
||||||
void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) override;
|
void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//FIXME: use unique_ptr
|
//FIXME: use unique_ptr
|
||||||
robin_hood::unordered_map<area_id, robin_hood::pair<area_info, robin_hood::unordered_map<chunk_pos, render::LodModel*>>> buffers;
|
robin_hood::unordered_map<area_id, robin_hood::pair<area_info, robin_hood::unordered_map<chunk_pos, std::pair<render::LodModel *, render::LodModel *>>>> buffers;
|
||||||
|
|
||||||
safe_priority_queue_map<area_<chunk_pos>, surrounding::corners, int, area_hash> loadQueue;
|
safe_priority_queue_map<area_<chunk_pos>, surrounding::corners, int, area_hash> loadQueue;
|
||||||
safe_queue<std::pair<area_<chunk_pos>, render::LodModel::LodData>> loadedQueue;
|
safe_queue<std::pair<area_<chunk_pos>, std::pair<render::LodModel::LodData, render::LodModel::LodData>>> loadedQueue;
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
std::vector<std::thread> workers;
|
std::vector<std::thread> workers;
|
||||||
|
@ -62,6 +62,15 @@ namespace contouring {
|
||||||
|
|
||||||
std::vector<std::pair<float, float>> loadedLevels;
|
std::vector<std::pair<float, float>> loadedLevels;
|
||||||
|
|
||||||
void render(const surrounding::corners &surrounding, render::LodModel::LodData& out, std::vector<render::VertexData>& tmp) const;
|
enum class Layer {
|
||||||
|
Solid = 1,
|
||||||
|
Transparent = 2,
|
||||||
|
Both = Solid | Transparent,
|
||||||
|
};
|
||||||
|
friend inline bool operator&&(Layer a, Layer b) {
|
||||||
|
return static_cast<int>(a) & static_cast<int>(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(const surrounding::corners &surrounding, render::LodModel::LodData& out, std::vector<render::VertexData>& tmp, Layer layer) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ struct passOptions {
|
||||||
bool curvature = true;
|
bool curvature = true;
|
||||||
/// Keep depth in sphere
|
/// Keep depth in sphere
|
||||||
bool curv_depth = true;
|
bool curv_depth = true;
|
||||||
|
/// Alpha blend
|
||||||
|
bool transparency = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Rendering options
|
/// Rendering options
|
||||||
|
@ -68,7 +70,7 @@ public:
|
||||||
virtual void beginFrame() = 0;
|
virtual void beginFrame() = 0;
|
||||||
/// Get started world program
|
/// Get started world program
|
||||||
/// (vertex buffer, model matrix, sphereProj, curvature)
|
/// (vertex buffer, model matrix, sphereProj, curvature)
|
||||||
virtual std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() = 0;
|
virtual std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass(bool solid) = 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
|
||||||
|
|
|
@ -109,6 +109,8 @@ UI::Actions UI::draw(config::client::options &options, state::state &state, cons
|
||||||
ImGui::TextDisabled("Depth");
|
ImGui::TextDisabled("Depth");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeRenderer |= ImGui::Checkbox("Transparency", &options.renderer.voxel.transparency);
|
||||||
|
|
||||||
changeRenderer |= ImGui::Checkbox("Fog", &options.renderer.voxel.fog);
|
changeRenderer |= ImGui::Checkbox("Fog", &options.renderer.voxel.fog);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Checkbox("Skybox", &options.renderer.skybox);
|
ImGui::Checkbox("Skybox", &options.renderer.skybox);
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
Control = 1 << 7,
|
Control = 1 << 7,
|
||||||
FillMode = 1 << 8,
|
FillMode = 1 << 8,
|
||||||
Message = 1 << 9,
|
Message = 1 << 9,
|
||||||
|
Transparency = 1 << 10,
|
||||||
};
|
};
|
||||||
friend inline void operator|=(Actions& a, Actions b) {
|
friend inline void operator|=(Actions& a, Actions b) {
|
||||||
a = static_cast<Actions>(static_cast<int>(a) | static_cast<int>(b));
|
a = static_cast<Actions>(static_cast<int>(a) | static_cast<int>(b));
|
||||||
|
|
|
@ -72,6 +72,9 @@ bool Renderer::Load(Window& window, const renderOptions& opt, const windowOption
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
GLint smp;
|
GLint smp;
|
||||||
glGetIntegerv(GL_SAMPLES, &smp);
|
glGetIntegerv(GL_SAMPLES, &smp);
|
||||||
if (smp > 0) {
|
if (smp > 0) {
|
||||||
|
@ -98,9 +101,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, glm::vec4, float)> Renderer::beginWorldPass() {
|
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass(bool solid) {
|
||||||
WorldPass->useIt();
|
if (solid) {
|
||||||
WorldPass->start(this);
|
WorldPass->useIt();
|
||||||
|
WorldPass->start(this);
|
||||||
|
}
|
||||||
return [&](render::LodModel *const buf, glm::mat4 model, glm::vec4 sph, float curv) {
|
return [&](render::LodModel *const buf, glm::mat4 model, glm::vec4 sph, float curv) {
|
||||||
WorldPass->setup(model, sph, curv);
|
WorldPass->setup(model, sph, curv);
|
||||||
return dynamic_cast<LodModel *const>(buf)->draw();
|
return dynamic_cast<LodModel *const>(buf)->draw();
|
||||||
|
@ -138,6 +143,11 @@ void Renderer::swapBuffer(Window& w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::reloadShaders(const pass::VoxelProgram::options& options) {
|
void Renderer::reloadShaders(const pass::VoxelProgram::options& options) {
|
||||||
|
if (options.transparency) {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
WorldPass = std::make_unique<pass::WorldProgram>(options);
|
WorldPass = std::make_unique<pass::WorldProgram>(options);
|
||||||
EntityPass = std::make_unique<pass::EntityProgram>(options);
|
EntityPass = std::make_unique<pass::EntityProgram>(options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void beginFrame() override;
|
void beginFrame() override;
|
||||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() override;
|
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass(bool solid) 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;
|
||||||
std::function<size_t(glm::mat4)> beginIndicatorPass() override;
|
std::function<size_t(glm::mat4)> beginIndicatorPass() override;
|
||||||
void postProcess() override;
|
void postProcess() override;
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
#define CONTENT_DIR "content/"
|
#define CONTENT_DIR "content/"
|
||||||
#define SHADER_DIR CONTENT_DIR "shaders/"
|
#define SHADER_DIR CONTENT_DIR "shaders/"
|
||||||
|
|
||||||
constexpr auto BLENDING = false;
|
|
||||||
|
|
||||||
using namespace render::vk;
|
using namespace render::vk;
|
||||||
|
|
||||||
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
|
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
|
||||||
|
@ -297,24 +295,24 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
||||||
depthStencil.stencilTestEnable = VK_FALSE;
|
depthStencil.stencilTestEnable = VK_FALSE;
|
||||||
// Stencil options front/back
|
// Stencil options front/back
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
|
VkPipelineColorBlendAttachmentState solidColorBlendAttachment{};
|
||||||
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
solidColorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
if constexpr (BLENDING) {
|
solidColorBlendAttachment.blendEnable = VK_FALSE;
|
||||||
colorBlendAttachment.blendEnable = VK_TRUE;
|
|
||||||
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
VkPipelineColorBlendAttachmentState blendColorBlendAttachment{};
|
||||||
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
blendColorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
blendColorBlendAttachment.blendEnable = VK_TRUE;
|
||||||
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
blendColorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
blendColorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
blendColorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||||
} else {
|
blendColorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||||
colorBlendAttachment.blendEnable = VK_FALSE;
|
blendColorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||||
}
|
blendColorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
|
||||||
VkPipelineColorBlendStateCreateInfo colorBlending{};
|
VkPipelineColorBlendStateCreateInfo colorBlending{};
|
||||||
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
colorBlending.attachmentCount = 1; //NOTE: For multitarget
|
colorBlending.attachmentCount = 1; //NOTE: For multitarget
|
||||||
colorBlending.pAttachments = &colorBlendAttachment;
|
colorBlending.pAttachments = options.voxel.transparency ? &blendColorBlendAttachment : &solidColorBlendAttachment;
|
||||||
colorBlending.logicOpEnable = VK_FALSE;
|
colorBlending.logicOpEnable = VK_FALSE;
|
||||||
colorBlending.logicOp = VK_LOGIC_OP_COPY;
|
colorBlending.logicOp = VK_LOGIC_OP_COPY;
|
||||||
colorBlending.blendConstants[0] = 0.0f;
|
colorBlending.blendConstants[0] = 0.0f;
|
||||||
|
|
|
@ -450,11 +450,13 @@ void Renderer::beginFrame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() {
|
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass(bool solid) {
|
||||||
assert(currentImage < swapChain->getImageViews().size());
|
assert(currentImage < swapChain->getImageViews().size());
|
||||||
|
|
||||||
auto& pass = pipeline->getWorldPass();
|
auto& pass = pipeline->getWorldPass();
|
||||||
commandCenter->startWorldPass(currentImage, pass);
|
if (solid) {
|
||||||
|
commandCenter->startWorldPass(currentImage, pass);
|
||||||
|
}
|
||||||
return [&](render::LodModel *const rBuffer, glm::mat4 model, glm::vec4 sphere, float curv) {
|
return [&](render::LodModel *const rBuffer, glm::mat4 model, glm::vec4 sphere, float curv) {
|
||||||
auto buffer = dynamic_cast<render::vk::LodModel *const>(rBuffer);
|
auto buffer = dynamic_cast<render::vk::LodModel *const>(rBuffer);
|
||||||
buffer->setLastUse(currentImage);
|
buffer->setLastUse(currentImage);
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
static _FORCE_INLINE_ Renderer *Get() { return static_cast<Renderer*>(render::Renderer::Get()); }
|
static _FORCE_INLINE_ Renderer *Get() { return static_cast<Renderer*>(render::Renderer::Get()); }
|
||||||
|
|
||||||
void beginFrame() override;
|
void beginFrame() override;
|
||||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() override;
|
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass(bool solid) 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;
|
||||||
std::function<size_t(glm::mat4)> beginIndicatorPass() override;
|
std::function<size_t(glm::mat4)> beginIndicatorPass() override;
|
||||||
void postProcess() override;
|
void postProcess() override;
|
||||||
|
|
Loading…
Reference in New Issue