Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
/run/
/out/
/logs/
/bin/
/.vscode/
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ nvidium_version=0.4.3-beta13-26.1


# Mod Properties
mod_version = 0.2.20-beta
mod_version = 0.2.20-beta-26.3
maven_group = me.cortex
archives_base_name = voxy
14 changes: 13 additions & 1 deletion src/main/java/me/cortex/voxy/client/core/model/MipGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ private static void solidify(long baseAddr, byte msk, short[] SCRATCH, ByteArray
}

public static void putTextures(boolean darkened, ColourDepthTextureData[] textures, MemoryBuffer into) {
putTextures(darkened, 0, textures, into);
}

public static void putTextures(boolean darkened, int partialTintMask, ColourDepthTextureData[] textures, MemoryBuffer into) {
//if (MODEL_TEXTURE_SIZE != 16) {throw new IllegalStateException("THIS METHOD MUST BE REDONE IF THIS CONST CHANGES");}

//TODO: need to use a write mask to see what pixels must be used to contribute to mipping
Expand All @@ -87,13 +91,21 @@ public static void putTextures(boolean darkened, ColourDepthTextureData[] textur
int y = (i&1)*MODEL_TEXTURE_SIZE;
int j = 0;
boolean anyTransparent = false;
boolean isPartialTint = ((partialTintMask >> i) & 1) != 0;
int[] depth = textures[i].depth();
for (int t : textures[i].colour()) {
if (isPartialTint) {
boolean isTinted = (depth[j] & (1 << 7)) != 0;
t = (t & 0x00FFFFFF) | (isTinted ? 0xFF000000 : 0);
}
int o = ((y+(j>>LAYERS))*LENGTH_B + ((j&(MODEL_TEXTURE_SIZE-1))+x))*4; j++;//LAYERS here is just cause faster
//t = ((t&0xFF000000)==0)?0x00_FF_00_FF:t;//great for testing
MemoryUtil.memPutInt(addr+o, t);
anyTransparent |= ((t&0xFF000000)==0);
}
solidMsk |= (anyTransparent?1:0)<<i;
if (!isPartialTint) {
solidMsk |= (anyTransparent?1:0)<<i;
}
}

if (!darkened) {
Expand Down
28 changes: 17 additions & 11 deletions src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b

//TODO: FIXME faces that have the same "alignment depth" e.g. (sizes[0]+sizes[1])~=1 can be merged into a double faced single quad

int partialTintMask = 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
long faceUploadPtr = uploadPtr + 4L * face;//Each face gets 4 bytes worth of data
Expand Down Expand Up @@ -600,26 +601,31 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b
faceModelData |= Math.min(enc,62)<<16;
//Still have 11 bits free

int tintState = 0;
//Bits 24,25 are tint metadata
if (tintSources!=null) {//We have a tint
tintState = TextureUtils.computeFaceTint(textureData[face], checkMode);
if (tintState == 2) {//Partial tint
faceModelData |= 1<<24;
partialTintMask |= 1<<face;
} else if (tintState == 3) {//Full tint
faceModelData |= 2<<24;
}
}

//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 |= layer != ChunkSectionLayer.SOLID;
needsAlphaDiscard &= layer != ChunkSectionLayer.TRANSLUCENT;//Translucent doesnt have alpha discard
if (tintState == 2) {
needsAlphaDiscard = false;//Partial tint faces use alpha as a tint mask and must not discard
}
faceModelData |= needsAlphaDiscard?1<<22:0;

faceModelData |= ((!faceCoversFullBlock)&&layer != ChunkSectionLayer.TRANSLUCENT)?1<<23:0;//Alpha discard override, translucency doesnt have alpha discard

//Bits 24,25 are tint metadata
if (tintSources!=null) {//We have a tint
int tintState = TextureUtils.computeFaceTint(textureData[face], checkMode);
if (tintState == 2) {//Partial tint
faceModelData |= 1<<24;
} else if (tintState == 3) {//Full tint
faceModelData |= 2<<24;
}
}

MemoryUtil.memPutInt(faceUploadPtr, faceModelData);
}

Expand Down Expand Up @@ -685,7 +691,7 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b
//TODO callback to inject extra data into the model data

if (uploadResult.hasMips)
MipGen.putTextures(darkenedTinting, textureData, uploadResult.texture);
MipGen.putTextures(darkenedTinting, partialTintMask, textureData, uploadResult.texture);

//glGenerateTextureMipmap(this.textures.id);

Expand Down
38 changes: 14 additions & 24 deletions src/main/resources/assets/voxy/shaders/lod/gl46/quads.frag
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,14 @@ struct VoxyFragmentParameters {
void voxy_emitFragment(VoxyFragmentParameters parameters);
#else

vec4 computeColour(vec2 texturePos, vec4 colour) {
//Conditional tinting, TODO: FIXME: this is better but still not great, try encode data into the top bit of alpha so its per pixel

vec4 computeColour(vec2 texturePos, vec4 colour, float tintMask) {
uint tintingFunction = tintingState();
bool doTint = tintingFunction==2;//Always tint if function == 2
if (tintingFunction == 1) {//partial tint
vec4 tintTest = textureLod(blockModelAtlas, texturePos, 0);
if (abs(tintTest.r-tintTest.g) < 0.02f && abs(tintTest.g-tintTest.b) < 0.02f) {
doTint = true;
}
}
if (doTint) {
colour *= uint2vec4RGBA(interData.z).yzwx;
if (tintingFunction == 2u) {
colour.rgb *= uint2vec4RGBA(interData.z).yzw;
} else if (tintingFunction == 1u) {
colour.rgb *= mix(vec3(1.0), uint2vec4RGBA(interData.z).yzw, tintMask);
}
return (colour * uint2vec4RGBA(interData.y)) + vec4(0,0,0,float(interData.w&0xFFu)/255);
return (colour * uint2vec4RGBA(interData.y)) + vec4(0,0,0,float(interData.w&0xFFu)/255.0);
}

#endif
Expand Down Expand Up @@ -140,6 +133,8 @@ void main() {
// colour = textureLod(blockModelAtlas, texPos, 0);
//}

float tintMask = colour.a;

//If we are in shaders and are a helper invocation, just exit, as it enables extra performance gains for small sized
// fragments, we do this here after derivative computation
//Trying it with all shaders
Expand All @@ -166,7 +161,7 @@ void main() {
//Also, small quad is really fking over the mipping level somehow
#ifndef TRANSLUCENT
colour.a = 1.0f;
if (useDiscard() && (textureLod(blockModelAtlas, texPos, 0).a <= 0.1f)) {
if (useDiscard() && tintingState() != 1u && (textureLod(blockModelAtlas, texPos, 0).a <= 0.1f)) {
//if (useDiscard() && (colour.a <= 0.1f)) {
#else
if (textureLod(blockModelAtlas, texPos, 0).a == 0.0f) {
Expand All @@ -186,7 +181,7 @@ void main() {
#endif

#ifndef PATCHED_SHADER
colour = computeColour(texPos, colour);
colour = computeColour(texPos, colour, tintMask);
outColour = colour;

#ifdef DEBUG_RENDER
Expand All @@ -202,16 +197,11 @@ void main() {
uint modelId = getModelId();
BlockModel model = modelData[modelId];
uint tintingFunction = tintingState();
bool doTint = tintingFunction==2;//Always tint if function == 2
if (tintingFunction==1) {//Partial tint
vec4 tintTest = texture(blockModelAtlas, texPos, -2);
if (abs(tintTest.r-tintTest.g) < 0.02f && abs(tintTest.g-tintTest.b) < 0.02f) {
doTint = true;
}
}
vec4 tint = vec4(1);
if (doTint) {
vec4 tint = vec4(1.0);
if (tintingFunction == 2u) {
tint = uint2vec4RGBA(interData.z).yzwx;
} else if (tintingFunction == 1u) {
tint = vec4(mix(vec3(1.0), uint2vec4RGBA(interData.z).yzw, tintMask), 1.0);
}

uint face = getFace();
Expand Down