mirror of
https://github.com/lubosz/overte.git
synced 2025-04-25 00:03:16 +02:00
refining the voxelizatoion, tracking one bug where light flickers
This commit is contained in:
parent
bd4268ee18
commit
9a492b3a88
5 changed files with 58 additions and 32 deletions
|
@ -513,7 +513,7 @@ void GL45Texture::stripToMip(uint16_t newMinMip) {
|
|||
syncSampler();
|
||||
size_t oldSize = _size;
|
||||
updateSize();
|
||||
Q_ASSERT(_size > oldSize);
|
||||
// Q_ASSERT(_size > oldSize);
|
||||
|
||||
|
||||
// Re-insert into the texture-by-mips map if appropriate
|
||||
|
|
|
@ -6,16 +6,12 @@
|
|||
#endif
|
||||
|
||||
float frustumGrid_depthRampGridToVolume(float ngrid) {
|
||||
//if (ngrid < 0.0f)
|
||||
// return ngrid;
|
||||
// return ngrid;
|
||||
// return ngrid;
|
||||
// return sqrt(ngrid);
|
||||
return float_exp2(ngrid) - 1.0f;
|
||||
}
|
||||
float frustumGrid_depthRampInverseVolumeToGrid(float nvolume) {
|
||||
//if (nvolume < 0.0f)
|
||||
// return nvolume;
|
||||
// return nvolume;
|
||||
// return nvolume;
|
||||
// return nvolume * nvolume;
|
||||
return log2(nvolume + 1.0f);
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ uint32_t scanLightVolumeBox(FrustumGrid& grid, const FrustumGrid::Planes planes[
|
|||
for (auto z = zMin; (z <= zMax); z++) {
|
||||
for (auto y = yMin; (y <= yMax); y++) {
|
||||
for (auto x = xMin; (x <= xMax); x++) {
|
||||
auto index = 1 + x + gridPosToOffset.y * y + gridPosToOffset.z * z;
|
||||
auto index = x + gridPosToOffset.y * y + gridPosToOffset.z * z;
|
||||
clusterGrid[index].emplace_back(lightId);
|
||||
numClustersTouched++;
|
||||
}
|
||||
|
@ -220,12 +220,15 @@ uint32_t scanLightVolumeSphere(FrustumGrid& grid, const FrustumGrid::Planes plan
|
|||
const auto& yPlanes = planes[1];
|
||||
const auto& zPlanes = planes[2];
|
||||
|
||||
int center_z = grid.frustumGrid_eyeDepthToClusterLayer(eyePosRadius.z);
|
||||
int center_y = (yMax + yMin) >> 1;
|
||||
// FInd the light origin cluster
|
||||
auto centerCluster = grid.frustumGrid_eyeToClusterPos(glm::vec3(eyePosRadius));
|
||||
int center_z = centerCluster.z;
|
||||
int center_y = centerCluster.y;
|
||||
|
||||
for (auto z = zMin; (z <= zMax); z++) {
|
||||
auto zSphere = eyePosRadius;
|
||||
if (z != center_z) {
|
||||
auto& plane = (z < center_z) ? zPlanes[z + 1] : -zPlanes[z];
|
||||
auto plane = (z < center_z) ? zPlanes[z + 1] : -zPlanes[z];
|
||||
if (!reduceSphereToPlane(zSphere, plane, zSphere)) {
|
||||
// pass this slice!
|
||||
continue;
|
||||
|
@ -234,7 +237,7 @@ uint32_t scanLightVolumeSphere(FrustumGrid& grid, const FrustumGrid::Planes plan
|
|||
for (auto y = yMin; (y <= yMax); y++) {
|
||||
auto ySphere = zSphere;
|
||||
if (y != center_y) {
|
||||
auto& plane = (y < center_y) ? yPlanes[y + 1] : -yPlanes[y];
|
||||
auto plane = (y < center_y) ? yPlanes[y + 1] : -yPlanes[y];
|
||||
if (!reduceSphereToPlane(ySphere, plane, ySphere)) {
|
||||
// pass this slice!
|
||||
continue;
|
||||
|
@ -262,8 +265,12 @@ uint32_t scanLightVolumeSphere(FrustumGrid& grid, const FrustumGrid::Planes plan
|
|||
|
||||
for (; (x <= xs); x++) {
|
||||
auto index = grid.frustumGrid_clusterToIndex(ivec3(x, y, z));
|
||||
clusterGrid[index].emplace_back(lightId);
|
||||
numClustersTouched++;
|
||||
if (index < (int) clusterGrid.size()) {
|
||||
clusterGrid[index].emplace_back(lightId);
|
||||
numClustersTouched++;
|
||||
} else {
|
||||
qDebug() << "WARNING: LightClusters::scanLightVolumeSphere invalid index found ? numClusters = " << clusterGrid.size() << " index = " << index << " found from cluster xyz = " << x << " " << y << " " << z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +331,7 @@ void LightClusters::updateClusters() {
|
|||
|
||||
// CLamp the z range
|
||||
zMin = std::max(0, zMin);
|
||||
|
||||
// zMax = std::min(zMax, theFrustumGrid.dims.z);
|
||||
|
||||
// find 2D corners of the sphere in grid
|
||||
int xMin { 0 };
|
||||
|
@ -362,7 +369,7 @@ void LightClusters::updateClusters() {
|
|||
auto rc = theFrustumGrid.frustumGrid_eyeToClusterDirH(rightDir);
|
||||
|
||||
xMin = std::max(xMin, lc);
|
||||
xMax = std::max(0, std::min(rc, xMax));
|
||||
xMax = std::min(rc, xMax);
|
||||
}
|
||||
|
||||
if ((eyeOriLen2V > radius2)) {
|
||||
|
@ -385,12 +392,14 @@ void LightClusters::updateClusters() {
|
|||
auto tc = theFrustumGrid.frustumGrid_eyeToClusterDirV(topDir);
|
||||
|
||||
yMin = std::max(yMin, bc);
|
||||
yMax = std::max(yMin, std::min(tc, yMax));
|
||||
yMax =std::min(tc, yMax);
|
||||
}
|
||||
|
||||
// now voxelize
|
||||
auto& clusterGrid = (isSpot ? clusterGridSpot : clusterGridPoint);
|
||||
numClusterTouched += scanLightVolumeSphere(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
||||
// numClusterTouched += scanLightVolumeSphere(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
||||
numClusterTouched += scanLightVolumeBox(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
||||
|
||||
}
|
||||
|
||||
// Lights have been gathered now reexpress in terms of 2 sequential buffers
|
||||
|
|
|
@ -241,21 +241,37 @@ void evalFragShading(out vec3 diffuse, out vec3 specular,
|
|||
diffuse *= specularBrdf.y;
|
||||
specular = vec3(specularBrdf.x);
|
||||
} else {
|
||||
vec4 shading = evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness);
|
||||
vec4 shading = evalPBRShadingGloss(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness);
|
||||
diffuse = vec3(shading.w);
|
||||
specular = shading.xyz;
|
||||
}
|
||||
diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled());
|
||||
}
|
||||
|
||||
void evalFragShadingSimpler(out vec3 diffuse, out vec3 specular,
|
||||
|
||||
void evalFragShadingScattering(out vec3 diffuse, out vec3 specular,
|
||||
vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir,
|
||||
float metallic, vec3 fresnel, float roughness, vec3 albedo
|
||||
|
||||
,float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
||||
|
||||
) {
|
||||
vec4 shading = evalPBRShadingGloss(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness);
|
||||
vec3 brdf = evalSkinBRDF(fragLightDir, fragNormal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w);
|
||||
float NdotL = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0);
|
||||
diffuse = mix(vec3(NdotL), brdf, scattering);
|
||||
|
||||
// Specular Lighting
|
||||
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
|
||||
vec2 specularBrdf = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0);
|
||||
|
||||
diffuse *= specularBrdf.y;
|
||||
specular = vec3(specularBrdf.x);
|
||||
diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled());
|
||||
}
|
||||
|
||||
void evalFragShadingGloss(out vec3 diffuse, out vec3 specular,
|
||||
vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir,
|
||||
float metallic, vec3 fresnel, float gloss, vec3 albedo
|
||||
) {
|
||||
vec4 shading = evalPBRShadingGloss(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, gloss);
|
||||
diffuse = vec3(shading.w);
|
||||
diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled());
|
||||
specular = shading.xyz;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<@include LightClusterGrid.slh@>
|
||||
|
||||
|
||||
|
||||
in vec2 _texCoord0;
|
||||
out vec4 _fragColor;
|
||||
|
||||
|
@ -94,7 +95,7 @@ void main(void) {
|
|||
|
||||
// COmpute the rougness into gloss2 once:
|
||||
float fragGloss2 = pow(frag.roughness + 0.001, 2.0);
|
||||
frag.roughness = fragGloss2;
|
||||
bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0);
|
||||
|
||||
int numLightTouching = 0;
|
||||
for (int i = 0; i < cluster.x; i++) {
|
||||
|
@ -131,9 +132,12 @@ void main(void) {
|
|||
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
|
||||
|
||||
// Eval shading
|
||||
evalFragShading(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo
|
||||
,frag.scattering, midNormalCurvature, lowNormalCurvature
|
||||
);
|
||||
if (withScattering) {
|
||||
evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo
|
||||
,frag.scattering, midNormalCurvature, lowNormalCurvature );
|
||||
} else {
|
||||
evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo);
|
||||
}
|
||||
|
||||
diffuse *= lightEnergy * isDiffuseEnabled();
|
||||
specular *= lightEnergy * isSpecularEnabled();
|
||||
|
@ -183,17 +187,18 @@ void main(void) {
|
|||
vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light);
|
||||
|
||||
// Eval shading
|
||||
evalFragShading(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo
|
||||
,frag.scattering, midNormalCurvature, lowNormalCurvature
|
||||
);
|
||||
if (withScattering) {
|
||||
evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo
|
||||
,frag.scattering, midNormalCurvature, lowNormalCurvature );
|
||||
} else {
|
||||
evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo);
|
||||
}
|
||||
|
||||
diffuse *= lightEnergy * isDiffuseEnabled();
|
||||
specular *= lightEnergy * isSpecularEnabled();
|
||||
|
||||
_fragColor.rgb += diffuse;
|
||||
_fragColor.rgb += specular;
|
||||
|
||||
// _fragColor.rgb += vec3(1.0/16.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue