первый коммит, мусор в 3д текстуре
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
#version 150
|
||||
|
||||
uniform sampler2D DiffuseSampler;
|
||||
uniform sampler2D DepthSampler;
|
||||
uniform sampler3D FogVolume;
|
||||
|
||||
uniform mat4 InverseProjection;
|
||||
uniform mat4 InverseView;
|
||||
|
||||
uniform vec3 CameraPosition;
|
||||
|
||||
uniform ivec2 FogOrigin;
|
||||
uniform ivec2 RingBlockOffset;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Настройки
|
||||
//------------------------------------------------------------
|
||||
|
||||
const float STEP_SIZE = 0.5;
|
||||
const float MAX_DISTANCE = 256.0;
|
||||
const int MAX_STEPS = int(MAX_DISTANCE / STEP_SIZE);
|
||||
|
||||
// Размер туманного объёма
|
||||
const float FOG_SIZE_X = 256.0;
|
||||
const float FOG_SIZE_Z = 256.0;
|
||||
|
||||
// Высота мира
|
||||
const float WORLD_BOTTOM = -64.0;
|
||||
const float WORLD_HEIGHT = 384.0;
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
vec3 reconstructViewPosition(vec2 uv)
|
||||
{
|
||||
float depth = texture(DepthSampler, uv).r;
|
||||
|
||||
vec4 clip = vec4(
|
||||
uv * 2.0 - 1.0,
|
||||
depth * 2.0 - 1.0,
|
||||
1.0
|
||||
);
|
||||
|
||||
vec4 view = InverseProjection * clip;
|
||||
|
||||
return view.xyz / view.w;
|
||||
}
|
||||
|
||||
vec3 reconstructWorldPosition(vec2 uv)
|
||||
{
|
||||
vec3 viewPos = reconstructViewPosition(uv);
|
||||
|
||||
vec4 world = InverseView * vec4(viewPos, 1.0);
|
||||
|
||||
return world.xyz + CameraPosition;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
float density(vec3 worldPos)
|
||||
{
|
||||
vec3 uv;
|
||||
|
||||
float localX = worldPos.x - float(FogOrigin.x);
|
||||
float localZ = worldPos.z - float(FogOrigin.y);
|
||||
|
||||
if (
|
||||
localX < 0.0 || localX >= FOG_SIZE_X ||
|
||||
localZ < 0.0 || localZ >= FOG_SIZE_Z ||
|
||||
worldPos.y < WORLD_BOTTOM ||
|
||||
worldPos.y >= WORLD_BOTTOM + WORLD_HEIGHT
|
||||
){
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float physicalX = mod(
|
||||
localX + float(RingBlockOffset.x),
|
||||
FOG_SIZE_X
|
||||
);
|
||||
|
||||
float physicalZ = mod(
|
||||
localZ + float(RingBlockOffset.y),
|
||||
FOG_SIZE_Z
|
||||
);
|
||||
|
||||
uv.x = physicalX / FOG_SIZE_X;
|
||||
uv.z = physicalZ / FOG_SIZE_Z;
|
||||
uv.y = (worldPos.y - WORLD_BOTTOM) / WORLD_HEIGHT;
|
||||
|
||||
return texture(FogVolume, uv).r;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sceneColor = texture(DiffuseSampler, texCoord);
|
||||
|
||||
vec3 worldPos = reconstructWorldPosition(texCoord);
|
||||
|
||||
vec3 rayDir = normalize(worldPos - CameraPosition);
|
||||
|
||||
float rayLength = distance(worldPos, CameraPosition);
|
||||
rayLength = min(rayLength, MAX_DISTANCE);
|
||||
|
||||
vec3 samplePos = CameraPosition;
|
||||
|
||||
float fog = 0.0;
|
||||
|
||||
for (int i = 0; i < MAX_STEPS; i++)
|
||||
{
|
||||
float traveled = float(i) * STEP_SIZE;
|
||||
|
||||
if (traveled >= rayLength)
|
||||
break;
|
||||
|
||||
samplePos += rayDir * STEP_SIZE;
|
||||
|
||||
fog += density(samplePos) * STEP_SIZE;
|
||||
}
|
||||
|
||||
fog = clamp(fog, 0.0, 1.0);
|
||||
|
||||
vec3 fogColor = vec3(
|
||||
0.75,
|
||||
0.80,
|
||||
0.90
|
||||
);
|
||||
|
||||
FragColor = vec4(
|
||||
mix(sceneColor.rgb, fogColor, fog),
|
||||
1.0
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user