Added alpha discard flag to faces
This commit is contained in:
@@ -160,25 +160,29 @@ public class ModelManager {
|
||||
long uploadPtr = UploadStream.INSTANCE.upload(this.modelBuffer, (long) modelId * MODEL_SIZE, MODEL_SIZE);
|
||||
|
||||
|
||||
//TODO: implement
|
||||
//TODO: implement;
|
||||
// TODO: if it has a constant colour instead... idk why (apparently for things like spruce leaves)?? but premultiply the texture data by the constant colour
|
||||
boolean hasBiomeColourResolver = false;
|
||||
|
||||
|
||||
|
||||
//TODO: special case stuff like vines and glow lichen, where it can be represented by a single double sided quad
|
||||
// since that would help alot with perf of lots of vines, can be done by having one of the faces just not exist and the other be in no occlusion mode
|
||||
|
||||
var sizes = this.computeModelDepth(textureData, checkMode);
|
||||
|
||||
//TODO: THIS, note this can be tested for in 2 ways, re render the model with quad culling disabled and see if the result
|
||||
// is the same, (if yes then needs double sided quads)
|
||||
// another way to test it is if e.g. up and down havent got anything rendered but the sides do (e.g. all plants etc)
|
||||
boolean needsDoubleSidedQuads = false;
|
||||
|
||||
//TODO: special case stuff like vines and glow lichen, where it can be represented by a single double sided quad
|
||||
// since that would help alot with perf of lots of vines
|
||||
boolean needsDoubleSidedQuads = (sizes[0] < -0.1 && sizes[1] < -0.1) || (sizes[2] < -0.1 && sizes[3] < -0.1) || (sizes[4] < -0.1 && sizes[5] < -0.1);
|
||||
|
||||
|
||||
//This also checks if there is a block colour resolver for the given blockstate and marks that the block has a resolver
|
||||
var sizes = this.computeModelDepth(textureData, checkMode);
|
||||
|
||||
//Each face gets 1 byte, with the top 2 bytes being for whatever
|
||||
long metadata = hasBiomeColourResolver?1:0;
|
||||
long metadata = 0;
|
||||
metadata |= hasBiomeColourResolver?1:0;
|
||||
metadata |= blockRenderLayer == RenderLayer.getTranslucent()?2:0;
|
||||
metadata |= needsDoubleSidedQuads?4:0;
|
||||
|
||||
//TODO: add a bunch of control config options for overriding/setting options of metadata for each face of each type
|
||||
for (int face = 5; face != -1; face--) {//In reverse order to make indexing into the metadata long easier
|
||||
@@ -192,6 +196,7 @@ public class ModelManager {
|
||||
continue;
|
||||
}
|
||||
var faceSize = TextureUtils.computeBounds(textureData[face], checkMode);
|
||||
int writeCount = TextureUtils.getWrittenPixelCount(textureData[face], checkMode);
|
||||
|
||||
boolean faceCoversFullBlock = faceSize[0] == 0 && faceSize[2] == 0 &&
|
||||
faceSize[1] == (this.modelTextureSize-1) && faceSize[3] == (this.modelTextureSize-1);
|
||||
@@ -206,7 +211,6 @@ public class ModelManager {
|
||||
occludesFace &= offset < 0.1;//If the face is rendered far away from the other face, then it doesnt occlude
|
||||
|
||||
if (occludesFace) {
|
||||
int writeCount = TextureUtils.getWrittenPixelCount(textureData[face], checkMode);
|
||||
occludesFace &= ((float)writeCount)/(this.modelTextureSize * this.modelTextureSize) > 0.9;// only occlude if the face covers more than 90% of the face
|
||||
}
|
||||
metadata |= occludesFace?1:0;
|
||||
@@ -231,6 +235,14 @@ public class ModelManager {
|
||||
faceModelData |= Math.round(offset*63)<<16;//Change the scale from 0->1 (ends inclusive) float to 0->63 (6 bits) NOTE! that 63 == 1.0f meaning its shifted all the way to the other side of the model
|
||||
//Still have 11 bits free
|
||||
|
||||
//Stuff like fences are solid, however they have extra side piece that mean it needs to have discard on
|
||||
int area = (faceSize[1]-faceSize[0]+1) * (faceSize[3]-faceSize[2]+1);
|
||||
boolean needsAlphaDiscard = ((float)writeCount)/area<0.9;//If the amount of area covered by written pixels is less than a threashold, disable discard as its not needed
|
||||
|
||||
needsAlphaDiscard |= blockRenderLayer != RenderLayer.getSolid();
|
||||
|
||||
faceModelData |= needsAlphaDiscard?1<<22:0;
|
||||
|
||||
MemoryUtil.memPutInt(faceUploadPtr, faceModelData);
|
||||
}
|
||||
this.metadataCache[modelId] = metadata;
|
||||
@@ -238,6 +250,9 @@ public class ModelManager {
|
||||
uploadPtr += 4*6;
|
||||
//Have 40 bytes free for remaining model data
|
||||
// todo: put in like the render layer type ig? along with colour resolver info
|
||||
int modelFlags = 0;
|
||||
//modelFlags |= blockRenderLayer == RenderLayer.getSolid()?0:1;// should discard alpha
|
||||
MemoryUtil.memPutInt(uploadPtr, modelFlags);
|
||||
|
||||
|
||||
|
||||
@@ -344,4 +359,8 @@ public class ModelManager {
|
||||
this.textures.free();
|
||||
glDeleteSamplers(this.blockSampler);
|
||||
}
|
||||
|
||||
public void addDebugInfo(List<String> info) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public abstract class AbstractFarWorldRenderer {
|
||||
}
|
||||
|
||||
public void addDebugData(List<String> debug) {
|
||||
|
||||
this.models.addDebugInfo(debug);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
|
||||
@@ -177,6 +177,7 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
|
||||
|
||||
@Override
|
||||
public void addDebugData(List<String> debug) {
|
||||
super.addDebugData(debug);
|
||||
debug.add("Geometry buffer usage: " + ((float)Math.round((this.geometry.getGeometryBufferUsage()*100000))/1000) + "%");
|
||||
debug.add("Render Sections: " + this.geometry.getSectionCount());
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ layout(binding = 0, std140) uniform SceneUniform {
|
||||
|
||||
struct BlockModel {
|
||||
uint faceData[6];
|
||||
uint _pad[10];
|
||||
uint flagsA;
|
||||
uint _pad[9];
|
||||
};
|
||||
|
||||
struct SectionMeta {
|
||||
|
||||
@@ -7,3 +7,7 @@ float extractFaceIndentation(uint faceData) {
|
||||
vec4 extractFaceSizes(uint faceData) {
|
||||
return (vec4(faceData&0xF, (faceData>>4)&0xF, (faceData>>8)&0xF, (faceData>>12)&0xF)/16)+vec4(0,1f/16,0,1f/16);
|
||||
}
|
||||
|
||||
uint faceHasAlphaCuttout(uint faceData) {
|
||||
return (faceData>>22)&1;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ layout(binding = 0) uniform sampler2D blockModelAtlas;
|
||||
layout(location = 0) in vec2 uv;
|
||||
layout(location = 1) in flat vec2 baseUV;
|
||||
layout(location = 2) in flat vec4 colourTinting;
|
||||
layout(location = 3) in flat int discardAlpha;
|
||||
layout(location = 3) in flat uint discardAlpha;
|
||||
|
||||
layout(location = 0) out vec4 outColour;
|
||||
void main() {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
layout(location = 0) out vec2 uv;
|
||||
layout(location = 1) out flat vec2 baseUV;
|
||||
layout(location = 2) out flat vec4 colourTinting;
|
||||
layout(location = 3) out flat int discardAlpha;
|
||||
layout(location = 3) out flat uint discardAlpha;
|
||||
|
||||
uint extractLodLevel() {
|
||||
return uint(gl_BaseInstance)>>29;
|
||||
@@ -26,13 +26,13 @@ vec4 uint2vec4RGBA(uint colour) {
|
||||
}
|
||||
|
||||
//Gets the face offset with respect to the face direction (e.g. some will be + some will be -)
|
||||
float getDepthOffset(BlockModel model, uint face) {
|
||||
float offset = extractFaceIndentation(model.faceData[face]);
|
||||
float getDepthOffset(uint faceData, uint face) {
|
||||
float offset = extractFaceIndentation(faceData);
|
||||
return offset * (1-((int(face)&1)*2));
|
||||
}
|
||||
|
||||
vec2 getFaceSizeOffset(BlockModel model, uint face, uint corner) {
|
||||
vec4 faceOffsetsSizes = extractFaceSizes(model.faceData[face]);
|
||||
vec2 getFaceSizeOffset(uint faceData, uint corner) {
|
||||
vec4 faceOffsetsSizes = extractFaceSizes(faceData);
|
||||
return mix(faceOffsetsSizes.xz, -(1-faceOffsetsSizes.yw), bvec2(((corner>>1)&1)==1, (corner&1)==1));
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ void main() {
|
||||
uint face = extractFace(quad);
|
||||
uint modelId = extractStateId(quad);
|
||||
BlockModel model = modelData[modelId];
|
||||
uint faceData = model.faceData[face];
|
||||
|
||||
//Change the ordering due to backface culling
|
||||
//NOTE: when rendering, backface culling is disabled as we simply dispatch calls for each face
|
||||
@@ -58,11 +59,11 @@ void main() {
|
||||
ivec3 lodCorner = ((extractRelativeLodPos()<<lodLevel) - (baseSectionPos&(ivec3((1<<lodLevel)-1))))<<5;
|
||||
vec3 corner = innerPos * (1<<lodLevel) + lodCorner;
|
||||
|
||||
vec2 faceOffset = getFaceSizeOffset(model, face, cornerIdx);
|
||||
vec2 faceOffset = getFaceSizeOffset(faceData, cornerIdx);
|
||||
vec2 quadSize = vec2(extractSize(quad) * ivec2((cornerIdx>>1)&1, cornerIdx&1));
|
||||
vec2 size = (quadSize + faceOffset) * (1<<lodLevel);
|
||||
|
||||
vec3 offset = vec3(size, (float(face&1) + getDepthOffset(model, face)) * (1<<lodLevel));
|
||||
vec3 offset = vec3(size, (float(face&1) + getDepthOffset(faceData, face)) * (1<<lodLevel));
|
||||
|
||||
if ((face>>1) == 0) {//Up/down
|
||||
offset = offset.xzy;
|
||||
@@ -85,7 +86,7 @@ void main() {
|
||||
baseUV = modelUV + (vec2(face%3, face/3) * (1f/(vec2(3,2)*256f)));
|
||||
uv = quadSize + faceOffset;//Add in the face offset for 0,0 uv
|
||||
|
||||
discardAlpha = 0;
|
||||
discardAlpha = faceHasAlphaCuttout(faceData);
|
||||
|
||||
//Compute lighting
|
||||
colourTinting = getLighting(extractLightId(quad));
|
||||
|
||||
Reference in New Issue
Block a user