abstract and pull out vertex shader internals
This commit is contained in:
@@ -95,7 +95,7 @@ public class MDICSectionRenderer extends AbstractSectionRenderer<MDICViewport, B
|
||||
this.pipeline = pipeline;
|
||||
//The pipeline can be used to transform the renderer in abstract ways
|
||||
|
||||
String vertex = ShaderLoader.parse("voxy:lod/gl46/quads2.vert");
|
||||
String vertex = ShaderLoader.parse("voxy:lod/gl46/quads3.vert");
|
||||
String taa = pipeline.taaFunction("taaShift");
|
||||
if (taa != null) {
|
||||
vertex += "\n"+taa;//inject it at the end
|
||||
|
||||
@@ -11,8 +11,8 @@ layout(binding = 2) uniform sampler2D depthTex;
|
||||
//TODO: need to fix when merged quads have discardAlpha set to false but they span multiple tiles
|
||||
// however they are not a full block
|
||||
|
||||
layout(location = 0) in vec2 uv;
|
||||
layout(location = 1) in flat uvec4 interData;
|
||||
layout(location = 0) in flat uvec4 interData;
|
||||
layout(location = 1) in vec2 uv;
|
||||
|
||||
#ifdef DEBUG_RENDER
|
||||
layout(location = 7) in flat uint quadDebug;
|
||||
@@ -48,11 +48,7 @@ bool useCutout() {
|
||||
}
|
||||
|
||||
uint getFace() {
|
||||
#ifndef PATCHED_SHADER
|
||||
return (interData.w>>8)&7u;
|
||||
#else
|
||||
return (interData.y>>8)&7u;
|
||||
#endif
|
||||
return (interData.x>>4)&7u;
|
||||
}
|
||||
|
||||
#ifdef PATCHED_SHADER
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
//#define DEBUG_RENDER
|
||||
|
||||
layout(location = 0) out vec2 uv;
|
||||
layout(location = 1) out flat uvec4 interData;
|
||||
layout(location = 0) out flat uvec4 interData;
|
||||
layout(location = 1) out vec2 uv;
|
||||
|
||||
uint packVec4(vec4 vec) {
|
||||
uvec4 vec_=uvec4(vec*255)<<uvec4(24,16,8,0);
|
||||
|
||||
55
src/main/resources/assets/voxy/shaders/lod/gl46/quads3.vert
Normal file
55
src/main/resources/assets/voxy/shaders/lod/gl46/quads3.vert
Normal file
@@ -0,0 +1,55 @@
|
||||
#version 460 core
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
|
||||
#define QUAD_BUFFER_BINDING 1
|
||||
#define MODEL_BUFFER_BINDING 3
|
||||
#define MODEL_COLOUR_BUFFER_BINDING 4
|
||||
#define POSITION_SCRATCH_BINDING 5
|
||||
#define LIGHTING_SAMPLER_BINDING 1
|
||||
|
||||
#define USE_INTERPOLATED_UV
|
||||
|
||||
#import <voxy:lod/quad_format.glsl>
|
||||
#import <voxy:lod/block_model.glsl>
|
||||
#import <voxy:lod/gl46/bindings.glsl>
|
||||
#import <voxy:lod/quad_util.glsl>
|
||||
|
||||
layout(location = 0) out flat uvec4 interData;
|
||||
#ifdef USE_INTERPOLATED_UV
|
||||
layout(location = 1) out vec2 uv;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_RENDER
|
||||
layout(location = 7) out flat uint quadDebug;
|
||||
#endif
|
||||
|
||||
vec2 taaShift();
|
||||
|
||||
//TODO: add a mechanism so that some quads can ignore backface culling
|
||||
// this would help alot with stuff like crops as they would look kinda weird i think,
|
||||
// same with flowers etc
|
||||
void main() {
|
||||
taaOffset = taaShift();
|
||||
|
||||
QuadData quad;
|
||||
setupQuad(quad, quadData[uint(gl_VertexID)>>2], positionBuffer[gl_BaseInstance], (gl_VertexID&3) == 1);
|
||||
|
||||
uint cornerId = gl_VertexID&3;
|
||||
gl_Position = getQuadCornerPos(quad, cornerId);
|
||||
|
||||
#ifdef USE_INTERPOLATED_UV
|
||||
uv = getCornerUV(quad, cornerId);
|
||||
#endif
|
||||
|
||||
//Note: other data is automatically discarded as it is undefiend and has not been generated
|
||||
interData = quad.attributeData;
|
||||
|
||||
|
||||
#ifdef DEBUG_RENDER
|
||||
quadDebug = extractDetail(positionBuffer[gl_BaseInstance]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef TAA_PATCH
|
||||
vec2 taaShift() {return vec2(0.0);}
|
||||
#endif
|
||||
189
src/main/resources/assets/voxy/shaders/lod/quad_util.glsl
Normal file
189
src/main/resources/assets/voxy/shaders/lod/quad_util.glsl
Normal file
@@ -0,0 +1,189 @@
|
||||
//Common utility functions for decoding and operating on quads
|
||||
|
||||
vec3 swizzelDataAxis(uint axis, vec3 data) {
|
||||
return mix(mix(data.zxy,data.xzy,bvec3(axis==0)),data,bvec3(axis==1));
|
||||
}
|
||||
|
||||
uint extractDetail(uvec2 encPos) {
|
||||
return encPos.x>>28;
|
||||
}
|
||||
|
||||
ivec3 extractLoDPosition(uvec2 encPos) {
|
||||
int y = ((int(encPos.x)<<4)>>24);
|
||||
int x = (int(encPos.y)<<4)>>8;
|
||||
int z = int((encPos.x&((1u<<20)-1))<<4);
|
||||
z |= int(encPos.y>>28);
|
||||
z <<= 8;
|
||||
z >>= 8;
|
||||
return ivec3(x,y,z);
|
||||
}
|
||||
|
||||
vec4 getFaceSize(uint faceData) {
|
||||
float EPSILON = 0.00005f;
|
||||
|
||||
vec4 faceOffsetsSizes = extractFaceSizes(faceData);
|
||||
|
||||
//Expand the quads by a very small amount (because of the subtraction after this also becomes an implicit add)
|
||||
faceOffsetsSizes.xz -= vec2(EPSILON);
|
||||
|
||||
//Make the end relative to the start
|
||||
faceOffsetsSizes.yw -= faceOffsetsSizes.xz;
|
||||
|
||||
return faceOffsetsSizes;
|
||||
}
|
||||
|
||||
|
||||
vec2 taaOffset = vec2(0);//TODO: compute this
|
||||
|
||||
struct QuadData {
|
||||
uvec4 attributeData;
|
||||
|
||||
float lodScale;
|
||||
uint axis;
|
||||
//Used for computing the 4 corners of the quad
|
||||
vec3 basePoint;
|
||||
vec2 quadSizeAddin;
|
||||
vec2 uvCorner;
|
||||
};
|
||||
|
||||
uint makeQuadFlags(uint faceData, uint modelId, ivec2 quadSize, const in BlockModel model, uint face) {
|
||||
//bit: 0-use cuttout, 1-dont use mipmaps, 2|3-tint state, 4|6-face, 8|11-width, 12|15-height, 16|31-model id
|
||||
uint flags = 0;
|
||||
|
||||
flags |= modelId<<16;//Model id
|
||||
flags |= (uint(quadSize.x-1)<<8)|(uint(quadSize.y-1)<<12);//quad size
|
||||
|
||||
{//Cuttout
|
||||
flags |= faceHasAlphaCuttout(faceData);
|
||||
flags |= uint(any(greaterThan(quadSize, ivec2(1)))) & faceHasAlphaCuttoutOverride(faceData);
|
||||
}
|
||||
|
||||
flags |= uint(!modelHasMipmaps(model))<<1;//Not mipmaps
|
||||
|
||||
flags |= faceTintState(faceData)<<2;
|
||||
flags |= face<<4;//Face
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint packVec4(vec4 vec) {
|
||||
uvec4 vec_=uvec4(vec*255)<<uvec4(24,16,8,0);
|
||||
return vec_.x|vec_.y|vec_.z|vec_.w;
|
||||
}
|
||||
|
||||
uvec3 makeRemainingAttributes(const in BlockModel model, const in Quad quad, uint lodLevel, uint face) {
|
||||
uvec3 attributes = uvec3(0);
|
||||
|
||||
uint lighting = extractLightId(quad);
|
||||
|
||||
//Apply model colour tinting
|
||||
uint tintColour = model.colourTint;
|
||||
|
||||
if (modelHasBiomeLUT(model)) {
|
||||
tintColour = colourData[tintColour + extractBiomeId(quad)];
|
||||
}
|
||||
|
||||
#ifdef PATCHED_SHADER
|
||||
attributes.x = lighting;
|
||||
attributes.y = tintColour;
|
||||
#else
|
||||
bool isTranslucent = modelIsTranslucent(model);
|
||||
bool hasAO = modelHasMipmaps(model);//TODO: replace with per face AO flag
|
||||
bool isShaded = hasAO;//TODO: make this a per face flag
|
||||
|
||||
vec4 tinting = getLighting(lighting);
|
||||
|
||||
uint conditionalTinting = 0;
|
||||
if (tintColour != uint(-1)) {
|
||||
conditionalTinting = tintColour;
|
||||
}
|
||||
|
||||
uint addin = 0;
|
||||
if (!isTranslucent) {
|
||||
tinting.w = 0.0;
|
||||
//Encode the face, the lod level and
|
||||
uint encodedData = 0;
|
||||
encodedData |= face;
|
||||
encodedData |= (lodLevel<<3);
|
||||
encodedData |= uint(hasAO)<<6;
|
||||
addin = encodedData;
|
||||
}
|
||||
|
||||
//Apply face tint
|
||||
#ifdef DARKENED_TINTING
|
||||
if (isShaded) {
|
||||
//TODO: make branchless, infact apply ahead of time to the texture itself in ModelManager since that is
|
||||
// per face
|
||||
if ((face>>1) == 1) {//NORTH, SOUTH
|
||||
tinting.xyz *= 0.8f;
|
||||
} else if ((face>>1) == 2) {//EAST, WEST
|
||||
tinting.xyz *= 0.6f;
|
||||
} else {//UP DOWN
|
||||
tinting.xyz *= 0.9f;
|
||||
}
|
||||
} else {
|
||||
tinting.xyz *= 0.9f;
|
||||
}
|
||||
#else
|
||||
if (isShaded) {
|
||||
//TODO: make branchless, infact apply ahead of time to the texture itself in ModelManager since that is
|
||||
// per face
|
||||
if ((face>>1) == 1) {//NORTH, SOUTH
|
||||
tinting.xyz *= 0.8f;
|
||||
} else if ((face>>1) == 2) {//EAST, WEST
|
||||
tinting.xyz *= 0.6f;
|
||||
} else if (face == 0) {//DOWN
|
||||
tinting.xyz *= 0.5f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
attributes.x = packVec4(tinting);
|
||||
attributes.y = conditionalTinting;
|
||||
attributes.z = addin|(face<<8);
|
||||
#endif
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void setupQuad(out QuadData quad, const in Quad rawQuad, uvec2 sPos, bool generateAttributes) {
|
||||
uint lodLevel = extractDetail(sPos);
|
||||
float lodScale = 1<<lodLevel;
|
||||
ivec3 baseSection = (extractLoDPosition(sPos)<<lodLevel) - baseSectionPos;
|
||||
|
||||
uint face = extractFace(rawQuad);
|
||||
uint modelId = extractStateId(rawQuad);
|
||||
BlockModel model = modelData[modelId];
|
||||
uint faceData = model.faceData[face];
|
||||
ivec2 quadSize = extractSize(rawQuad);
|
||||
|
||||
if (generateAttributes) {
|
||||
quad.attributeData.x = makeQuadFlags(faceData, modelId, quadSize, model, face);
|
||||
quad.attributeData.yzw = makeRemainingAttributes(model, rawQuad, lodLevel, face);
|
||||
}
|
||||
|
||||
vec4 faceSize = getFaceSize(faceData);
|
||||
|
||||
vec3 quadStart = extractPos(rawQuad);
|
||||
float depthOffset = extractFaceIndentation(faceData);
|
||||
quadStart += swizzelDataAxis(face>>1, vec3(faceSize.xz, mix(depthOffset, 1-depthOffset, float(face&1u))));
|
||||
|
||||
quad.lodScale = lodScale;
|
||||
quad.axis = face>>1;
|
||||
quad.basePoint = (quadStart*lodScale)+vec3(baseSection<<5);
|
||||
quad.quadSizeAddin = (faceSize.yw + quadSize - 1);
|
||||
quad.uvCorner = faceSize.xz;
|
||||
}
|
||||
|
||||
vec4 getQuadCornerPos(in QuadData quad, uint cornerId) {
|
||||
vec2 cornerMask = vec2((cornerId>>1)&1u, cornerId&1u)*quad.lodScale;
|
||||
vec3 point = quad.basePoint + swizzelDataAxis(quad.axis,vec3(quad.quadSizeAddin*cornerMask,0));
|
||||
vec4 pos = MVP * vec4(point, 1.0f);
|
||||
pos.xy += taaOffset*pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
#ifdef USE_INTERPOLATED_UV
|
||||
vec2 getCornerUV(const in QuadData quad, uint cornerId) {
|
||||
return quad.uvCorner + quad.quadSizeAddin*vec2((cornerId>>1)&1u, cornerId&1u);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user