mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 15:36:14 +03:00
192 lines
6.9 KiB
GLSL
192 lines
6.9 KiB
GLSL
|
|
#version 460
|
|
|
|
/*
|
|
** Physical based render code, develop by engineer: qiutanguu.
|
|
*/
|
|
|
|
#extension GL_GOOGLE_include_directive : enable
|
|
#extension GL_EXT_samplerless_texture_functions : enable
|
|
#include "Cloud_Common.glsl"
|
|
#include "KuwaharaFilter.glsl"
|
|
|
|
vec3 drawSun(vec3 rayDir, vec3 sunDir)
|
|
{
|
|
const float dT = dot(rayDir, sunDir);
|
|
|
|
const float theta = 0.1 * kPI / 180.0;
|
|
const vec3 sunCenterColor = vec3(1.0f, 0.92549, 0.87843) * 39.0f * 100;
|
|
|
|
const float cT = cos(theta);
|
|
if (dT >= cT)
|
|
{
|
|
return sunCenterColor;
|
|
}
|
|
|
|
return vec3(0.0);
|
|
}
|
|
|
|
float getDensity(vec3 worldPosition, float distToEye)
|
|
{
|
|
const float fogStartHeight = 0.0;
|
|
const float heightFallOff = 0.1;
|
|
|
|
float heightFog = exp(-(worldPosition.y - fogStartHeight) * heightFallOff);
|
|
|
|
// Height fog.
|
|
return 0.0001 + heightFog; // 1.0;
|
|
}
|
|
|
|
layout (local_size_x = 8, local_size_y = 8) in;
|
|
void main()
|
|
{
|
|
ivec2 texSize = imageSize(imageHdrSceneColor);
|
|
ivec2 depthTextureSize = textureSize(inDepth, 0);
|
|
ivec2 workPos = ivec2(gl_GlobalInvocationID.xy);
|
|
|
|
if(workPos.x >= texSize.x || workPos.y >= texSize.y)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const vec2 uv = (vec2(workPos) + vec2(0.5f)) / vec2(texSize);
|
|
|
|
vec4 clipSpace = vec4(uv.x * 2.0f - 1.0f, 1.0f - uv.y * 2.0f, 0.0, 1.0);
|
|
vec4 viewPosH = viewData.camInvertProj * clipSpace;
|
|
vec3 viewDir = viewPosH.xyz / viewPosH.w;
|
|
vec3 worldDir = normalize((viewData.camInvertView * vec4(viewDir, 0.0)).xyz);
|
|
|
|
vec4 srcColor = imageLoad(imageHdrSceneColor, workPos);
|
|
float sceneZ = texture(sampler2D(inDepth, pointClampEdgeSampler), uv).r;
|
|
// vec4 cloudColor = kuwaharaFilter(inCloudReconstructionTexture, linearClampEdgeSampler,uv);
|
|
|
|
vec4 cloudColor = texture(sampler2D(inCloudReconstructionTexture, linearClampEdgeSampler), uv);
|
|
|
|
float cloudDepth = texture(sampler2D(inCloudDepthReconstructionTexture, linearClampEdgeSampler), uv).r;
|
|
cloudDepth = max(1e-5f, cloudDepth); // very far cloud may be negative, use small value is enough.
|
|
|
|
vec3 result = srcColor.rgb;
|
|
if(sceneZ <= cloudDepth) // reverse z.
|
|
{
|
|
result = mix(srcColor.rgb, cloudColor.rgb, 1.0 - cloudColor.a);
|
|
}
|
|
|
|
// God ray for light.
|
|
#if 0
|
|
{
|
|
AtmosphereParameters atmosphere = getAtmosphereParameters(frameData);
|
|
|
|
const uint kGodRaySteps = 64;
|
|
const float kMaxMarchingDistance = 400.0f;
|
|
|
|
const DirectionalLightInfo light = frameData.directionalLight;
|
|
|
|
vec3 worldPosWP = getWorldPos(uv, sceneZ, viewData);
|
|
vec3 pixelToCameraWP = viewData.camWorldPos.xyz - worldPosWP;
|
|
|
|
float pixelToCameraDistanceWP = max(1e-5f, length(pixelToCameraWP));
|
|
vec3 rayDirWP = pixelToCameraWP / pixelToCameraDistanceWP;
|
|
|
|
float marchingDistance = min(kMaxMarchingDistance, pixelToCameraDistanceWP);
|
|
if(pixelToCameraDistanceWP > kMaxMarchingDistance)
|
|
{
|
|
worldPosWP = viewData.camWorldPos.xyz - rayDirWP * marchingDistance;
|
|
}
|
|
|
|
float stepLength = marchingDistance / float(kGodRaySteps);
|
|
vec3 stepRay = rayDirWP * stepLength;
|
|
|
|
// Interval noise is better than blue noise here.
|
|
float taaOffset = interleavedGradientNoise(workPos, frameData.frameIndex.x % frameData.jitterPeriod);
|
|
|
|
vec3 rayPosWP = worldPosWP + stepRay * (taaOffset + 0.05);
|
|
|
|
float transmittance = 1.0;
|
|
vec3 scatteredLight = vec3(0.0, 0.0, 0.0);
|
|
|
|
vec3 sunColor = frameData.directionalLight.color * frameData.directionalLight.intensity;
|
|
|
|
vec3 sunDirection = -normalize(frameData.directionalLight.direction);
|
|
float VoL = dot(-rayDirWP, sunDirection);
|
|
const float cosTheta = -VoL;
|
|
float phase = hgPhase(0.3, cosTheta);
|
|
|
|
for(uint i = 0; i < kGodRaySteps; i ++)
|
|
{
|
|
float visibilityTerm = 1.0;
|
|
{
|
|
// First find active cascade.
|
|
uint activeCascadeId = 0;
|
|
vec3 shadowCoord;
|
|
|
|
// Loop to find suitable cascade.
|
|
for(uint cascadeId = 0; cascadeId < light.cascadeCount; cascadeId ++)
|
|
{
|
|
shadowCoord = projectPos(rayPosWP, cascadeInfos[cascadeId].viewProj);
|
|
if(onRange(shadowCoord.xyz, vec3(light.cascadeBorderAdopt), vec3(1.0f - light.cascadeBorderAdopt)))
|
|
{
|
|
break;
|
|
}
|
|
activeCascadeId ++;
|
|
}
|
|
|
|
if(activeCascadeId < light.cascadeCount)
|
|
{
|
|
const float perCascadeOffsetUV = 1.0f / light.cascadeCount;
|
|
const float shadowTexelSize = 1.0f / float(light.perCascadeXYDim);
|
|
|
|
// Main cascsade shadow compute.
|
|
{
|
|
vec3 shadowPosOnAltas = shadowCoord;
|
|
|
|
// Also add altas bias and z bias.
|
|
shadowPosOnAltas.x = (shadowPosOnAltas.x + float(activeCascadeId)) * perCascadeOffsetUV;
|
|
shadowPosOnAltas.z += 0.001 * (activeCascadeId + 1.0);
|
|
|
|
float depthShadow = texture(sampler2D(inSDSMShadowDepth, pointClampEdgeSampler), shadowPosOnAltas.xy).r;
|
|
visibilityTerm = shadowPosOnAltas.z > depthShadow ? 1.0 : 0.0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Second evaluate transmittance due to participating media
|
|
vec3 atmosphereTransmittance;
|
|
{
|
|
vec3 P0 = rayPosWP * 0.001 + vec3(0.0, atmosphere.bottomRadius, 0.0); // meter -> kilometers.
|
|
float viewHeight = length(P0);
|
|
const vec3 upVector = P0 / viewHeight;
|
|
|
|
float viewZenithCosAngle = dot(-normalize(frameData.directionalLight.direction), upVector);
|
|
vec2 sampleUv;
|
|
lutTransmittanceParamsToUv(atmosphere, viewHeight, viewZenithCosAngle, sampleUv);
|
|
atmosphereTransmittance = texture(sampler2D(inTransmittanceLut, linearClampEdgeSampler), sampleUv).rgb;
|
|
}
|
|
|
|
float density = getDensity(rayPosWP, pixelToCameraDistanceWP);
|
|
|
|
float sigmaS = density * 0.01;
|
|
float sigmaE = 0.001 * density + 1e-4f;
|
|
|
|
vec3 sunSkyLuminance = vec3(0.1) + visibilityTerm * sunColor * phase; // TODO: Sample SH as ambient light.
|
|
|
|
vec3 sactterLitStep = sunSkyLuminance * sigmaS;
|
|
|
|
float stepTransmittance = exp(-sigmaE * stepLength);
|
|
scatteredLight += atmosphereTransmittance * transmittance * (sactterLitStep - sactterLitStep * stepTransmittance) / max(1e-4f, sigmaE); // TODO: Add ambient light and atmosphere transmittance.
|
|
|
|
transmittance *= stepTransmittance;
|
|
|
|
// Step.
|
|
rayPosWP += stepRay;
|
|
}
|
|
|
|
result = result.rgb * transmittance + scatteredLight;
|
|
|
|
// result = scatteredLight;
|
|
}
|
|
#endif
|
|
|
|
|
|
imageStore(imageHdrSceneColor, workPos, vec4(result.rgb, 1.0));
|
|
} |