mirror of
https://github.com/X0nk/Bliss-Shader.git
synced 2024-12-23 01:59:39 +08:00
faster floodfill sampling in rgb not hsv
This commit is contained in:
parent
ccf5ebd5d4
commit
41b2f443d9
@ -31,10 +31,8 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
|||||||
|
|
||||||
int sumOf(ivec3 vec) {return vec.x + vec.y + vec.z;}
|
int sumOf(ivec3 vec) {return vec.x + vec.y + vec.z;}
|
||||||
|
|
||||||
vec3 Lpv_RgbToHsv(const in vec3 lightColor, const in float lightRange) {
|
int getSharedIndex(ivec3 pos) {
|
||||||
vec3 lightValue = RgbToHsv(lightColor);
|
return sumOf(pos * lpvFlatten);
|
||||||
lightValue.b = lightRange / LpvBlockSkyRange.x;
|
|
||||||
return lightValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 GetLpvValue(in ivec3 texCoord) {
|
vec4 GetLpvValue(in ivec3 texCoord) {
|
||||||
@ -44,14 +42,25 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
|||||||
? imageLoad(imgLpv2, texCoord)
|
? imageLoad(imgLpv2, texCoord)
|
||||||
: imageLoad(imgLpv1, texCoord);
|
: imageLoad(imgLpv1, texCoord);
|
||||||
|
|
||||||
lpvSample.ba = exp2(lpvSample.ba * LpvBlockSkyRange) - 1.0;
|
vec4 hsv_sky = vec4(RgbToHsv(lpvSample.rgb), lpvSample.a);
|
||||||
lpvSample.rgb = HsvToRgb(lpvSample.rgb);
|
hsv_sky.zw = exp2(hsv_sky.zw * LpvBlockSkyRange) - 1.0;
|
||||||
|
lpvSample = vec4(HsvToRgb(hsv_sky.xyz), hsv_sky.w);
|
||||||
|
|
||||||
return lpvSample;
|
return lpvSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getSharedIndex(ivec3 pos) {
|
uint GetVoxelBlock(const in ivec3 voxelPos) {
|
||||||
return sumOf(pos * lpvFlatten);
|
if (clamp(voxelPos, ivec3(0), ivec3(VoxelSize3-1u)) != voxelPos)
|
||||||
|
return BLOCK_EMPTY;
|
||||||
|
|
||||||
|
return imageLoad(imgVoxelMask, voxelPos).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulateSharedIndex(const in ivec3 imgCoordOffset, const in ivec3 workGroupOffset, const in uint i) {
|
||||||
|
ivec3 pos = workGroupOffset + ivec3(i / lpvFlatten) % 10;
|
||||||
|
|
||||||
|
lpvSharedData[i] = GetLpvValue(imgCoordOffset + pos);
|
||||||
|
voxelSharedData[i] = GetVoxelBlock(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleShared(ivec3 pos, int mask_index) {
|
vec4 sampleShared(ivec3 pos, int mask_index) {
|
||||||
@ -83,20 +92,6 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
|||||||
const vec4 avgFalloff = (1.0/6.0) * LpvBlockSkyFalloff.xxxy;
|
const vec4 avgFalloff = (1.0/6.0) * LpvBlockSkyFalloff.xxxy;
|
||||||
return (sX1 + sX2 + sY1 + sY2 + sZ1 + sZ2) * avgFalloff;
|
return (sX1 + sX2 + sY1 + sY2 + sZ1 + sZ2) * avgFalloff;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint GetVoxelBlock(const in ivec3 voxelPos) {
|
|
||||||
if (clamp(voxelPos, ivec3(0), ivec3(VoxelSize3-1u)) != voxelPos)
|
|
||||||
return BLOCK_EMPTY;
|
|
||||||
|
|
||||||
return imageLoad(imgVoxelMask, voxelPos).r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PopulateSharedIndex(const in ivec3 imgCoordOffset, const in ivec3 workGroupOffset, const in uint i) {
|
|
||||||
ivec3 pos = workGroupOffset + ivec3(i / lpvFlatten) % 10;
|
|
||||||
|
|
||||||
lpvSharedData[i] = GetLpvValue(imgCoordOffset + pos);
|
|
||||||
voxelSharedData[i] = GetVoxelBlock(pos);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -107,6 +102,7 @@ void main() {
|
|||||||
uvec3 chunkPos = gl_WorkGroupID * gl_WorkGroupSize;
|
uvec3 chunkPos = gl_WorkGroupID * gl_WorkGroupSize;
|
||||||
if (any(greaterThanEqual(chunkPos, LpvSize3))) return;
|
if (any(greaterThanEqual(chunkPos, LpvSize3))) return;
|
||||||
|
|
||||||
|
// Pre-populate shared-memory buffer for improved sampling performance
|
||||||
uint i = uint(gl_LocalInvocationIndex) * 2u;
|
uint i = uint(gl_LocalInvocationIndex) * 2u;
|
||||||
if (i < 1000u) {
|
if (i < 1000u) {
|
||||||
ivec3 imgCoordOffset = ivec3(floor(cameraPosition) - floor(previousCameraPosition));
|
ivec3 imgCoordOffset = ivec3(floor(cameraPosition) - floor(previousCameraPosition));
|
||||||
@ -118,42 +114,49 @@ void main() {
|
|||||||
|
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
|
// Exit early if outside LPV buffer size
|
||||||
ivec3 imgCoord = ivec3(gl_GlobalInvocationID);
|
ivec3 imgCoord = ivec3(gl_GlobalInvocationID);
|
||||||
if (any(greaterThanEqual(imgCoord, LpvSize3))) return;
|
if (any(greaterThanEqual(imgCoord, LpvSize3))) return;
|
||||||
|
|
||||||
uint blockId = voxelSharedData[getSharedIndex(ivec3(gl_LocalInvocationID) + 1)];
|
|
||||||
vec4 lightValue = vec4(0.0);
|
vec4 lightValue = vec4(0.0);
|
||||||
|
vec3 lightColor = vec3(0.0);
|
||||||
vec3 tintColor = vec3(1.0);
|
vec3 tintColor = vec3(1.0);
|
||||||
|
float lightRange = 0.0;
|
||||||
uint mixMask = 0xFFFF;
|
uint mixMask = 0xFFFF;
|
||||||
|
|
||||||
if (blockId > 0u) {
|
// Decode light data for current voxel
|
||||||
tintColor = vec3(0.0);
|
uint blockId = voxelSharedData[getSharedIndex(ivec3(gl_LocalInvocationID) + 1)];
|
||||||
|
|
||||||
|
if (blockId > 0u) {
|
||||||
uvec2 blockData = imageLoad(imgBlockData, int(blockId)).rg;
|
uvec2 blockData = imageLoad(imgBlockData, int(blockId)).rg;
|
||||||
vec4 lightColorRange = unpackUnorm4x8(blockData.r);
|
vec4 lightColorRange = unpackUnorm4x8(blockData.r);
|
||||||
|
lightColor = srgbToLinear(lightColorRange.rgb);
|
||||||
|
lightRange = lightColorRange.a * 255.0;
|
||||||
vec4 tintColorMask = unpackUnorm4x8(blockData.g);
|
vec4 tintColorMask = unpackUnorm4x8(blockData.g);
|
||||||
tintColor = srgbToLinear(tintColorMask.rgb);
|
tintColor = srgbToLinear(tintColorMask.rgb);
|
||||||
mixMask = (blockData.g >> 24) & 0xFFFF;
|
mixMask = (blockData.g >> 24) & 0xFFFF;
|
||||||
|
|
||||||
vec3 lightColor = srgbToLinear(lightColorRange.rgb);
|
|
||||||
float lightRange = lightColorRange.a * 255.0;
|
|
||||||
|
|
||||||
if (lightRange > 0.0) {
|
|
||||||
lightValue.rgb = Lpv_RgbToHsv(lightColor, lightRange);
|
|
||||||
lightValue.ba = exp2(lightValue.ba * LpvBlockSkyRange) - 1.0;
|
|
||||||
lightValue.rgb = HsvToRgb(lightValue.rgb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mix neighbor voxel light values
|
||||||
if (any(greaterThan(tintColor, vec3(0.0)))) {
|
if (any(greaterThan(tintColor, vec3(0.0)))) {
|
||||||
vec4 lightMixed = mixNeighbours(ivec3(gl_LocalInvocationID), mixMask);
|
vec4 lightMixed = mixNeighbours(ivec3(gl_LocalInvocationID), mixMask);
|
||||||
lightMixed.rgb *= tintColor;
|
lightMixed.rgb *= tintColor;
|
||||||
lightValue += lightMixed;
|
lightValue += lightMixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
lightValue.rgb = RgbToHsv(lightValue.rgb);
|
// Add light for current voxel
|
||||||
lightValue.ba = log2(lightValue.ba + 1.0) / LpvBlockSkyRange;
|
if (lightRange > 0.0) {
|
||||||
|
vec3 hsv = RgbToHsv(lightColor);
|
||||||
|
hsv.z = exp2(lightRange) - 1.0;
|
||||||
|
lightValue.rgb += HsvToRgb(hsv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert back to linear RGB space
|
||||||
|
vec4 hsv_sky = vec4(RgbToHsv(lightValue.rgb), lightValue.a);
|
||||||
|
hsv_sky.zw = log2(hsv_sky.zw + 1.0) / LpvBlockSkyRange;
|
||||||
|
lightValue = vec4(HsvToRgb(hsv_sky.xyz), hsv_sky.w);
|
||||||
|
|
||||||
|
// Store final value
|
||||||
if (frameCounter % 2 == 0)
|
if (frameCounter % 2 == 0)
|
||||||
imageStore(imgLpv1, imgCoord, lightValue);
|
imageStore(imgLpv1, imgCoord, lightValue);
|
||||||
else
|
else
|
||||||
|
@ -1,51 +1,23 @@
|
|||||||
// LPV falloff curve
|
|
||||||
const float LpvBlockPower = 4.0;
|
|
||||||
|
|
||||||
// LPV block brightness scale
|
// LPV block brightness scale
|
||||||
const float LpvBlockBrightness = 2.0;
|
const float LpvBlockBrightness = 2.0;
|
||||||
|
|
||||||
|
|
||||||
float lpvCurve(float values) {
|
float lpvCurve(float values) {
|
||||||
// return pow(values, LpvBlockPower) ;
|
|
||||||
return pow(1.0 - sqrt(1.0-values), 2.0);
|
return pow(1.0 - sqrt(1.0-values), 2.0);
|
||||||
// return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 SampleLpvNearest(const in ivec3 lpvPos) {
|
|
||||||
vec4 lpvSample = (frameCounter % 2) == 0
|
|
||||||
? texelFetch(texLpv1, lpvPos, 0)
|
|
||||||
: texelFetch(texLpv2, lpvPos, 0);
|
|
||||||
|
|
||||||
lpvSample.b = lpvCurve(lpvSample.b) * LpvBlockSkyRange.x;
|
|
||||||
lpvSample.rgb = HsvToRgb(lpvSample.rgb);
|
|
||||||
|
|
||||||
return lpvSample;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 SampleLpvLinear(const in vec3 lpvPos) {
|
vec4 SampleLpvLinear(const in vec3 lpvPos) {
|
||||||
vec3 pos = lpvPos - 0.5;
|
vec3 texcoord = lpvPos / LpvSize3;
|
||||||
ivec3 lpvCoord = ivec3(floor(pos));
|
|
||||||
vec3 lpvF = fract(pos);
|
|
||||||
|
|
||||||
vec4 sample_x1y1z1 = SampleLpvNearest(lpvCoord + ivec3(0, 0, 0));
|
vec4 lpvSample = (frameCounter % 2) == 0
|
||||||
vec4 sample_x2y1z1 = SampleLpvNearest(lpvCoord + ivec3(1, 0, 0));
|
? textureLod(texLpv1, texcoord, 0)
|
||||||
vec4 sample_x1y2z1 = SampleLpvNearest(lpvCoord + ivec3(0, 1, 0));
|
: textureLod(texLpv2, texcoord, 0);
|
||||||
vec4 sample_x2y2z1 = SampleLpvNearest(lpvCoord + ivec3(1, 1, 0));
|
|
||||||
|
|
||||||
vec4 sample_x1y1z2 = SampleLpvNearest(lpvCoord + ivec3(0, 0, 1));
|
vec3 hsv = RgbToHsv(lpvSample.rgb);
|
||||||
vec4 sample_x2y1z2 = SampleLpvNearest(lpvCoord + ivec3(1, 0, 1));
|
hsv.z = lpvCurve(hsv.b) * LpvBlockSkyRange.x;
|
||||||
vec4 sample_x1y2z2 = SampleLpvNearest(lpvCoord + ivec3(0, 1, 1));
|
lpvSample.rgb = HsvToRgb(hsv);
|
||||||
vec4 sample_x2y2z2 = SampleLpvNearest(lpvCoord + ivec3(1, 1, 1));
|
|
||||||
|
|
||||||
vec4 sample_y1z1 = mix(sample_x1y1z1, sample_x2y1z1, lpvF.x);
|
return lpvSample;
|
||||||
vec4 sample_y2z1 = mix(sample_x1y2z1, sample_x2y2z1, lpvF.x);
|
|
||||||
|
|
||||||
vec4 sample_y1z2 = mix(sample_x1y1z2, sample_x2y1z2, lpvF.x);
|
|
||||||
vec4 sample_y2z2 = mix(sample_x1y2z2, sample_x2y2z2, lpvF.x);
|
|
||||||
|
|
||||||
vec4 sample_z1 = mix(sample_y1z1, sample_y2z1, lpvF.y);
|
|
||||||
vec4 sample_z2 = mix(sample_y1z2, sample_y2z2, lpvF.y);
|
|
||||||
|
|
||||||
return mix(sample_z1, sample_z2, lpvF.z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 GetLpvBlockLight(const in vec4 lpvSample) {
|
vec3 GetLpvBlockLight(const in vec4 lpvSample) {
|
||||||
|
@ -33,8 +33,6 @@ void PopulateShadowVoxel(const in vec3 playerPos) {
|
|||||||
if (
|
if (
|
||||||
((renderStage == MC_RENDER_STAGE_ENTITIES && (currentRenderedItemId > 0 || entityId > 0)) || renderStage == MC_RENDER_STAGE_BLOCK_ENTITIES)
|
((renderStage == MC_RENDER_STAGE_ENTITIES && (currentRenderedItemId > 0 || entityId > 0)) || renderStage == MC_RENDER_STAGE_BLOCK_ENTITIES)
|
||||||
) {
|
) {
|
||||||
voxelId = uint(mc_Entity.x + 0.5);
|
|
||||||
|
|
||||||
if (renderStage == MC_RENDER_STAGE_BLOCK_ENTITIES) {
|
if (renderStage == MC_RENDER_STAGE_BLOCK_ENTITIES) {
|
||||||
if (blockEntityId > 0 && blockEntityId < 500)
|
if (blockEntityId > 0 && blockEntityId < 500)
|
||||||
voxelId = uint(blockEntityId);
|
voxelId = uint(blockEntityId);
|
||||||
|
Loading…
Reference in New Issue
Block a user