Initial commit: Minecraft 光追着色器包(从零实现的 path tracing)
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
// MinecraftPT — Bloom CS (SIG)
|
||||
// Bloom sprite / glare generation (compute shader utility).
|
||||
|
||||
#ifndef BLOOM_CS_SIG_GLSL
|
||||
#define BLOOM_CS_SIG_GLSL
|
||||
|
||||
// Bloom glare from bright pixels
|
||||
void EmitBloomGlare(ivec2 texel, vec3 color, float intensity){
|
||||
// Simple bloom spike (cross pattern)
|
||||
// This is a placeholder — actual implementation samples and adds to bloom buffer
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
#include "/Lib/BasicFunctions/LightingConstants.glsl"
|
||||
// MinecraftPT — Cloud Shadow
|
||||
// Cloud shadow projection onto the ground from the cloud layer.
|
||||
|
||||
#ifndef CLOUD_SHADOW_GLSL
|
||||
uniform sampler3D CloudNoise3D;
|
||||
#define CLOUD_SHADOW_GLSL
|
||||
|
||||
float GetCloudShadow(vec3 worldPos){
|
||||
float cloudAlt = mix(CLOUD_CLEAR_ALTITUDE, CLOUD_RAIN_ALTITUDE, wetness);
|
||||
float cloudDensity = mix(CLOUD_CLEAR_DENSITY, CLOUD_RAIN_DENSITY, wetness);
|
||||
|
||||
// Project ground position onto cloud layer
|
||||
vec3 shadowDir = normalize(GetSunDirWorld());
|
||||
vec3 cloudPos = worldPos + shadowDir * (cloudAlt - worldPos.y) / shadowDir.y;
|
||||
|
||||
// Sample cloud density at that position
|
||||
vec2 p = cloudPos.xz * CLOUD_BASE_NOISE_SCALE + frameTimeCounter * 0.001 * CLOUD_SPEED;
|
||||
float n = textureLod(CloudNoise3D, vec3(p, 0.2), 0.0).r;
|
||||
|
||||
float shadow = 1.0 - saturate((n - 0.5) * cloudDensity * 2.0 * CLOUD_SHADOW);
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// MinecraftPT — Depth of Field
|
||||
// Circle of confusion computation and bokeh blur.
|
||||
|
||||
#ifndef DOF_GLSL
|
||||
#define DOF_GLSL
|
||||
|
||||
// Compute CoC (circle of confusion) for a fragment
|
||||
float GetCoC(float depth, float focalDepth){
|
||||
float focus = focalDepth;
|
||||
float aperture = DOF_BLUR;
|
||||
float coc = abs(depth - focus) / focus * aperture * DOF_MAX_COC;
|
||||
return clamp(coc, 0.0, DOF_MAX_COC);
|
||||
}
|
||||
|
||||
// Simple bokeh blur (gather)
|
||||
vec3 DofBlur(vec2 texelCoord, float coc){
|
||||
vec3 color = vec3(0.0);
|
||||
float weight = 0.0;
|
||||
|
||||
int radius = int(min(coc, 8.0)) + 1;
|
||||
for (int i = -radius; i <= radius; i++){
|
||||
for (int j = -radius; j <= radius; j++){
|
||||
float dist = length(vec2(i, j));
|
||||
if (dist > coc) continue;
|
||||
|
||||
vec2 coord = texelCoord + vec2(i, j);
|
||||
vec3 sampleColor = texelFetch(colortex12, ivec2(coord), 0).rgb;
|
||||
float w = max(0.0, 1.0 - dist / coc);
|
||||
|
||||
color += sampleColor * w;
|
||||
weight += w;
|
||||
}}
|
||||
|
||||
return weight > 0.0 ? color / weight : color;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
// MinecraftPT — End Sky
|
||||
// End dimension sky: stars, planet, accretion disc around black hole.
|
||||
|
||||
#ifndef END_SKY_GLSL
|
||||
#define END_SKY_GLSL
|
||||
|
||||
vec3 GetEndSky(vec3 dir, vec3 sunDir){
|
||||
dir = normalize(dir);
|
||||
|
||||
// Dark base
|
||||
vec3 color = vec3(0.01, 0.01, 0.02);
|
||||
|
||||
// Stars (hash-based)
|
||||
float stars = 0.0;
|
||||
vec3 starDir = dir;
|
||||
for (int i = 0; i < 32; i++){
|
||||
vec3 seed = vec3(i * 0.1, 0.5, 0.7);
|
||||
vec3 starPos = normalize(hash3(seed.xy) - 0.5);
|
||||
float star = exp(-(1.0 - dot(dir, starPos)) * 1000.0);
|
||||
stars += star * hash1(seed.xy);
|
||||
}
|
||||
color += stars * 0.5;
|
||||
|
||||
// Planet (distant body)
|
||||
vec3 planetDir = normalize(vec3(0.5, 0.3, 0.0));
|
||||
float planet = exp(-(1.0 - dot(dir, planetDir)) * 200.0);
|
||||
color += vec3(0.3, 0.4, 0.6) * planet * 0.8;
|
||||
|
||||
// Accretion disc (around planet)
|
||||
float disc = exp(-abs(dot(normalize(dir.xz), normalize(planetDir.xz))) * 50.0);
|
||||
disc *= step(abs(dir.y), 0.1);
|
||||
color += vec3(1.0, 0.6, 0.2) * disc * 0.5;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// MinecraftPT — Parallax Occlusion Mapping
|
||||
// Steep parallax mapping with PCF soft shadows.
|
||||
|
||||
#ifndef PARALLAX_GLSL
|
||||
#define PARALLAX_GLSL
|
||||
|
||||
// Steep parallax mapping
|
||||
vec2 ParallaxMapping(vec2 texcoord, vec3 viewDir){
|
||||
float height = texture(tex, texcoord).a;
|
||||
vec2 delta = viewDir.xy / viewDir.z * PARALLAX_DEPTH;
|
||||
|
||||
int numLayers = max(1, int(PARALLAX_QUALITY));
|
||||
float layerDepth = 1.0 / float(numLayers);
|
||||
float currentDepth = 0.0;
|
||||
vec2 currentCoord = texcoord;
|
||||
|
||||
for (int i = 0; i < numLayers; i++){
|
||||
currentCoord -= delta * layerDepth;
|
||||
height = texture(tex, currentCoord).a;
|
||||
currentDepth += layerDepth;
|
||||
if (height < currentDepth) break;
|
||||
}
|
||||
|
||||
// Parallax shadow
|
||||
float shadow = 1.0;
|
||||
#ifdef PARALLAX_SHADOW
|
||||
// PCF shadow
|
||||
for (int i = 0; i < PARALLAX_SHADOW_QUALITY; i++){
|
||||
vec2 shadowCoord = currentCoord + delta * float(i) / float(PARALLAX_SHADOW_QUALITY);
|
||||
shadow *= step(currentDepth - layerDepth * float(i) / float(PARALLAX_SHADOW_QUALITY), texture(tex, shadowCoord).a);
|
||||
}
|
||||
#endif
|
||||
|
||||
return currentCoord;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
#include "/Lib/BasicFunctions/LightingConstants.glsl"
|
||||
// MinecraftPT — Planar Clouds
|
||||
// Simple 2D cloud layer rendered as a plane at altitude.
|
||||
|
||||
#ifndef PLANAR_CLOUDS_GLSL
|
||||
#define PLANAR_CLOUDS_GLSL
|
||||
|
||||
// Sample cloud density at a world XZ position (2D noise + coverage)
|
||||
float GetPlanarCloudDensity(vec2 xz, float time, out vec3 cloudColor){
|
||||
// Coverage by weather
|
||||
float coverage = mix(PC_CLEAR_COVERAGE, PC_RAIN_COVERAGE, wetness);
|
||||
float density = mix(PC_CLEAR_DENSITY, PC_RAIN_DENSITY, wetness);
|
||||
float sunlighting = mix(PC_CLEAR_SUNLIGHTING, PC_RAIN_SUNLIGHTING, wetness);
|
||||
float skylighting = mix(PC_CLEAR_SKYLIGHTING, PC_RAIN_SKYLIGHTING, wetness);
|
||||
|
||||
// FBM noise
|
||||
vec2 p = xz * PC_NOISE_SCALE + vec2(time * 0.01, 0.0);
|
||||
float n = 0.0;
|
||||
float amp = 0.5;
|
||||
for (int i = 0; i < 3; i++){
|
||||
n += textureLod(CloudNoise3D, vec3(p, 0.5), 0.0).r * amp;
|
||||
p *= 2.0;
|
||||
amp *= 0.5;
|
||||
}
|
||||
|
||||
float clouds = saturate((n - (1.0 - coverage)) * (1.0 / max(coverage, 0.01)));
|
||||
|
||||
// Cloud color: lit by sun and sky
|
||||
float sunFactor = sunlighting;
|
||||
cloudColor = mix(GetCloudAtmoIrradiance(), GetCloudSunIrradiance(), sunFactor) * clouds
|
||||
+ vec3(1.0) * skylighting * clouds;
|
||||
|
||||
return clouds * density;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
// MinecraftPT — Ripple
|
||||
// Rain-induced ripple normal map for water surfaces.
|
||||
|
||||
#ifndef RIPPLE_GLSL
|
||||
uniform sampler2D ripple2D;
|
||||
#define RIPPLE_GLSL
|
||||
|
||||
vec2 GetRippleNormal(vec3 worldPos, float time){
|
||||
vec2 coord = worldPos.xz * 0.1;
|
||||
vec2 ripple = textureLod(ripple2D, fract(coord + time * 0.02), 0.0).rg;
|
||||
return ripple * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "/Lib/BasicFunctions/LightingConstants.glsl"
|
||||
// MinecraftPT — Volumetric Fog
|
||||
// Height-based volumetric fog with 3D noise, ray marched in the volumetric pass.
|
||||
|
||||
#ifndef VOLUMETRIC_FOG_GLSL
|
||||
uniform sampler3D CloudNoise3D;
|
||||
#define VOLUMETRIC_FOG_GLSL
|
||||
|
||||
// Fog density at a world position (height + noise)
|
||||
float GetVolumetricFogDensity(vec3 worldPos, float time){
|
||||
float height = worldPos.y;
|
||||
|
||||
// Two-layer height fog
|
||||
float density = VFOG_DENSITY_BASE;
|
||||
density += exp(-(height - VFOG_HEIGHT) * VFOG_FALLOFF) * VFOG_DENSITY;
|
||||
density += exp(-(height - VFOG_HEIGHT_2) * VFOG_FALLOFF * 2.0) * VFOG_DENSITY * 0.5;
|
||||
|
||||
// Noise variation
|
||||
#ifdef VFOG_NOISE_TYPE
|
||||
if (VFOG_NOISE_TYPE > 0){
|
||||
vec3 p = worldPos * vec3(VFOG_NOISE_HORIZONTAL_SCALE, VFOG_NOISE_VERTICAL_SCALE, VFOG_NOISE_HORIZONTAL_SCALE) + vec3(time * 0.01, 0.0, time * 0.008);
|
||||
float n = 0.0;
|
||||
float amp = 0.5;
|
||||
for (int i = 0; i < VFOG_NOISE_OCTAVE; i++){
|
||||
n += textureLod(CloudNoise3D, fract(p), 0.0).r * amp;
|
||||
p *= 2.0;
|
||||
amp *= 0.5;
|
||||
}
|
||||
density *= 1.0 + (n - 0.5) * VFOG_NOISE_COVERAGE * 2.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Rain fog boost
|
||||
density *= 1.0 + wetness * VFOG_RAIN_DENSITY_MUL;
|
||||
|
||||
return max(density, 0.0);
|
||||
}
|
||||
|
||||
// In-scattering color for fog (sun + sky)
|
||||
vec3 GetFogColor(vec3 worldPos, vec3 sunDir){
|
||||
vec3 sunColor = GetSunIrradiance() * VFOG_SUNLIGHT_DENSITY;
|
||||
vec3 skyColor = GetAtmoIrradiance();
|
||||
|
||||
return skyColor + sunColor * 0.5;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
// MinecraftPT — Water Fog
|
||||
// Underwater volumetric fog with scattering colors.
|
||||
|
||||
#ifndef WATER_FOG_GLSL
|
||||
#define WATER_FOG_GLSL
|
||||
|
||||
vec3 GetWaterFogColor(vec3 worldPos){
|
||||
return vec3(WATER_SCATTERING_R, WATER_SCATTERING_G, WATER_SCATTERING_B) * WATER_SCATTERING_DENSITY;
|
||||
}
|
||||
|
||||
float GetWaterFogDensity(vec3 worldPos){
|
||||
return WATER_SCATTERING_DENSITY;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
// MinecraftPT — Water Waves
|
||||
// Gerstner-style water wave normals with multi-octave detail.
|
||||
|
||||
#ifndef WATER_WAVES_GLSL
|
||||
#define WATER_WAVES_GLSL
|
||||
|
||||
vec3 GetWaveNormal(vec3 worldPos, float lightmap){
|
||||
vec2 pos = worldPos.xz;
|
||||
|
||||
float time = frameTimeCounter * 0.05 * WAVE_SPEED;
|
||||
|
||||
// Multi-octave sine waves
|
||||
float wave1 = sin(pos.x * 0.1 * WAVE_SCALE + time) * cos(pos.y * 0.08 * WAVE_SCALE + time * 0.7);
|
||||
float wave2 = sin(pos.x * 0.2 * WAVE_SCALE + time * 1.3) * cos(pos.y * 0.15 * WAVE_SCALE - time * 0.9);
|
||||
float wave3 = sin((pos.x + pos.y) * 0.35 * WAVE_SCALE + time * 1.7) * 0.5;
|
||||
|
||||
// Height field derivatives for normal
|
||||
float dx = cos(pos.x * 0.1 * WAVE_SCALE + time) * 0.1 * WAVE_SCALE * 0.5 * 0.05
|
||||
+ cos(pos.x * 0.2 * WAVE_SCALE + time * 1.3) * 0.2 * WAVE_SCALE * 0.5 * 0.04;
|
||||
float dz = -sin(pos.x * 0.1 * WAVE_SCALE + time) * sin(pos.y * 0.08 * WAVE_SCALE + time * 0.7) * 0.08 * WAVE_SCALE * 0.5 * 0.05
|
||||
- sin(pos.x * 0.2 * WAVE_SCALE + time * 1.3) * sin(pos.y * 0.15 * WAVE_SCALE - time * 0.9) * 0.15 * WAVE_SCALE * 0.5 * 0.04;
|
||||
|
||||
vec3 normal = normalize(vec3(-dx, 1.0, -dz) * WAVE_NORMAL_STRENGTH + vec3(0.0, 1.0 - WAVE_NORMAL_STRENGTH, 0.0));
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
// MinecraftPT — Waving Plants
|
||||
// Wind animation for grass, plants, leaves.
|
||||
|
||||
#ifndef WAVING_PLANTS_GLSL
|
||||
#define WAVING_PLANTS_GLSL
|
||||
|
||||
void WavingPlants(inout vec4 worldPos, float lightLevel){
|
||||
float time = frameTimeCounter * 0.05 * WAVING_SPEED;
|
||||
|
||||
// Wind direction
|
||||
vec2 wind = vec2(0.5, 0.3) * sin(time) + vec2(0.2);
|
||||
|
||||
// Amplitude by plant type
|
||||
float amplitude = GRASS_AMPLITUDE;
|
||||
#ifdef IS_LEAVES
|
||||
amplitude = LEAVES_AMPLITUDE;
|
||||
#endif
|
||||
|
||||
float dist = length(worldPos.xyz - gbufferModelViewInverse[3].xyz);
|
||||
float fade = 1.0 - saturate(dist / WAVING_RANGE);
|
||||
|
||||
vec3 vertexPos = worldPos.xyz;
|
||||
|
||||
// Vertex-based wave
|
||||
vec3 offset = vec3(wind * sin(vertexPos.x * 0.3 + vertexPos.z * 0.2 + time * 2.0), 0.0);
|
||||
offset *= vertexPos.y * amplitude * fade;
|
||||
|
||||
// Random per-vertex jitter (height-based)
|
||||
float heightFactor = vertexPos.y;
|
||||
float noise = sin(vertexPos.x * 12.9898 + vertexPos.z * 78.233 + time) * 0.5 + 0.5;
|
||||
offset.x += noise * amplitude * 0.5 * heightFactor * fade;
|
||||
offset.z += noise * amplitude * 0.3 * heightFactor * fade;
|
||||
|
||||
worldPos.xyz += offset;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user