screenspace tweeks

This commit is contained in:
mcrcortex
2025-04-20 12:44:42 +10:00
parent 7d0cbefe17
commit 5d01bc8f03
2 changed files with 75 additions and 63 deletions

View File

@@ -274,7 +274,7 @@ public class ModelFactory {
var colourProvider = getColourProvider(blockState.getBlock()); var colourProvider = getColourProvider(blockState.getBlock());
long uploadPtr = UploadStream.INSTANCE.upload(this.storage.modelBuffer, (long) modelId * MODEL_SIZE, MODEL_SIZE);; long uploadPtr = UploadStream.INSTANCE.upload(this.storage.modelBuffer, (long) modelId * MODEL_SIZE, MODEL_SIZE);
//TODO: implement; //TODO: implement;

View File

@@ -17,14 +17,6 @@ layout(binding = HIZ_BINDING) uniform sampler2DShadow hizDepthSampler;
//TODO: maybe do spher bounds aswell? cause they have different accuracies but are both over estimates (liberals (non conservative xD)) //TODO: maybe do spher bounds aswell? cause they have different accuracies but are both over estimates (liberals (non conservative xD))
// so can do && // so can do &&
vec3 minBB;
vec3 maxBB;
vec2 size;
bool insideFrustum;
uint BASE_IDX = gl_LocalInvocationID.x*8;
shared vec2[LOCAL_SIZE*8] screenPoints;
bool within(vec2 a, vec2 b, vec2 c) { bool within(vec2 a, vec2 b, vec2 c) {
return all(lessThan(a,b)) && all(lessThan(b, c)); return all(lessThan(a,b)) && all(lessThan(b, c));
} }
@@ -37,6 +29,21 @@ bool within(float a, float b, float c) {
return a<b && b<c; return a<b && b<c;
} }
float crossMag(vec2 a, vec2 b) {
return abs(a.x*b.y-b.x*a.y);
}
bool checkPointInView(vec4 point) {
return within(vec3(-point.w,-point.w,0.0f), point.xyz, vec3(point.w));
}
vec3 minBB;
vec3 maxBB;
vec2 size;
bool insideFrustum;
float screenSize;
UnpackedNode node22; UnpackedNode node22;
//Sets up screenspace with the given node id, returns true on success false on failure/should not continue //Sets up screenspace with the given node id, returns true on success false on failure/should not continue
//Accesses data that is setup in the main traversal and is just shared to here //Accesses data that is setup in the main traversal and is just shared to here
@@ -56,39 +63,65 @@ void setupScreenspace(in UnpackedNode node) {
//vec3 minPos = minSize + basePos; //vec3 minPos = minSize + basePos;
//vec3 maxPos = maxSize + basePos; //vec3 maxPos = maxSize + basePos;
minBB = vec3(9999.0f); vec3 basePos = vec3(((node.pos<<node.lodLevel)-camSecPos)<<5)-camSubSecPos;
maxBB = vec3(-9999.0f);
insideFrustum = false;
for (int i = 0; i < 8; i++) { vec4 P000 = VP * vec4(basePos, 1);
vec3 ppoint = vec3((i&1)!=0,(i&2)!=0,(i&4)!=0)*(32<<node.lodLevel); mat3x4 Axis = mat3x4(VP) * float(32<<node.lodLevel);
ppoint += vec3(((node.pos<<node.lodLevel)-camSecPos)<<5)-camSubSecPos; vec4 P100 = Axis[0] + P000;
vec4 P001 = Axis[2] + P000;
vec4 P101 = Axis[2] + P100;
vec4 P010 = Axis[1] + P000;
vec4 P110 = Axis[1] + P100;
vec4 P011 = Axis[1] + P001;
vec4 P111 = Axis[1] + P101;
insideFrustum = checkPointInView(P000) || checkPointInView(P100) || checkPointInView(P001) || checkPointInView(P101) ||
checkPointInView(P010) || checkPointInView(P110) || checkPointInView(P011) || checkPointInView(P111);
//Fast exit
//NOTE!: cant this be precomputed and put in an array?? in the scene uniform?? if (!insideFrustum) {
vec4 pPoint = VP*vec4(ppoint, 1);//Size of section is 32x32x32 (need to change it to a bounding box in the future) return;
bool pointInside = within(vec3(-pPoint.w,-pPoint.w,0.0f), pPoint.xyz, vec3(pPoint.w));
insideFrustum = insideFrustum || pointInside;
vec3 point = pPoint.xyz/pPoint.w;
//TODO: CLIP TO VIEWPORT
minBB = min(minBB, point);
maxBB = max(maxBB, point);
screenPoints[BASE_IDX+i] = point.xy*0.5f+0.5f;
} }
//printf("Screenspace MIN: %f, %f, %f MAX: %f, %f, %f", minBB.x,minBB.y,minBB.z, maxBB.x,maxBB.y,maxBB.z); //Perspective divide + convert to screenspace (i.e. range 0->1 if within viewport)
vec3 p000 = (P000.xyz/P000.w) * 0.5f + 0.5f;
vec3 p100 = (P100.xyz/P100.w) * 0.5f + 0.5f;
vec3 p001 = (P001.xyz/P001.w) * 0.5f + 0.5f;
vec3 p101 = (P101.xyz/P101.w) * 0.5f + 0.5f;
vec3 p010 = (P010.xyz/P010.w) * 0.5f + 0.5f;
vec3 p110 = (P110.xyz/P110.w) * 0.5f + 0.5f;
vec3 p011 = (P011.xyz/P011.w) * 0.5f + 0.5f;
vec3 p111 = (P111.xyz/P111.w) * 0.5f + 0.5f;
//Convert to screenspace
maxBB = maxBB*0.5f+0.5f; {//Compute exact screenspace size
minBB = minBB*0.5f+0.5f; float ssize = 0;
{//Faces from 0,0,0
vec2 A = p100.xy-p000.xy;
vec2 B = p010.xy-p000.xy;
vec2 C = p001.xy-p000.xy;
ssize += crossMag(A,B);
ssize += crossMag(A,C);
ssize += crossMag(C,B);
}
{//Faces from 1,1,1
vec2 A = p011.xy-p111.xy;
vec2 B = p101.xy-p111.xy;
vec2 C = p110.xy-p111.xy;
ssize += crossMag(A,B);
ssize += crossMag(A,C);
ssize += crossMag(C,B);
}
ssize *= 0.5f;//Half the size since we did both back and front area
screenSize = ssize;
}
minBB = min(min(min(p000, p100), min(p001, p101)), min(min(p010, p110), min(p011, p111)));
maxBB = max(max(max(p000, p100), max(p001, p101)), max(max(p010, p110), max(p011, p111)));
size = clamp(maxBB.xy - minBB.xy, vec2(0), vec2(1)); size = clamp(maxBB.xy - minBB.xy, vec2(0), vec2(1));
} }
//Checks if the node is implicitly culled (outside frustum) //Checks if the node is implicitly culled (outside frustum)
@@ -104,47 +137,26 @@ bool isCulledByHiz() {
//} //}
vec2 ssize = size * vec2(screenW, screenH); vec2 ssize = size * vec2(screenW, screenH);
float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1))); float miplevel = log2(max(max(ssize.x, ssize.y),1));
miplevel = ceil(miplevel);
//miplevel = clamp(miplevel, 0, 20); //miplevel = clamp(miplevel, 0, 20);
vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f; vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f;
//TODO: maybe get rid of clamp //TODO: maybe get rid of clamp
//Todo: replace with some rasterization, e.g. especially for request back to cpu //Todo: replace with some rasterization, e.g. especially for request back to cpu
vec2 midpoint2 = clamp(midpoint, vec2(0), vec2(1)); //vec2 midpoint2 = clamp(midpoint, vec2(0), vec2(1));
bool culled = textureLod(hizDepthSampler, vec3(midpoint2, minBB.z), miplevel) < 0.0001f; vec2 midpoint2 = midpoint;
bool culled = textureLod(hizDepthSampler, vec3(midpoint2, minBB.z*2.0f-1.0f), miplevel) < 0.0001f;//*0.5f+0.5f
//printf("HiZ sample point: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z); //printf("HiZ sample point: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z);
//if (culled && node22.lodLevel != 4) { //if ((culled) && node22.lodLevel == 0) {
// printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.0f,0.0f, 0.000001f), 20)); // printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.5f,0.5f, 0.000000001f), 9.0f));
//} //}
return culled; return culled;
} }
float crossMag(vec2 a, vec2 b) {
return abs(a.x*b.y-b.x*a.y);
}
//Returns if we should decend into its children or not //Returns if we should decend into its children or not
bool shouldDecend() { bool shouldDecend() {
float size = 0; return screenSize > minSSS;
{//Faces from 0,0,0
vec2 base = screenPoints[BASE_IDX+0];
vec2 A = screenPoints[BASE_IDX+1]-base;
vec2 B = screenPoints[BASE_IDX+2]-base;
vec2 C = screenPoints[BASE_IDX+4]-base;
size += crossMag(A,B);
size += crossMag(A,C);
size += crossMag(C,B);
}
{//Faces from 1,1,1
vec2 base = screenPoints[BASE_IDX+7];
vec2 A = screenPoints[BASE_IDX+3]-base;
vec2 B = screenPoints[BASE_IDX+5]-base;
vec2 C = screenPoints[BASE_IDX+6]-base;
size += crossMag(A,B);
size += crossMag(A,C);
size += crossMag(C,B);
}
size *= 0.5f;//Half the size since we did both back and front area
return size > minSSS;
} }