Initial commit: Minecraft 光追着色器包(从零实现的 path tracing)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// MinecraftPT — RTWSM Backward Analysis
|
||||
// Computes the importance map from the shadow map depth: which shadow map texels
|
||||
// need more resolution (near-field geometry, steep normals).
|
||||
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
#include "/Lib/PathTracing/Voxelizer/VoxelProfile.glsl"
|
||||
|
||||
const ivec3 workGroups = ivec3(32, 16, 1);
|
||||
layout (local_size_x = 32, local_size_y = 32) in;
|
||||
|
||||
layout (r32f) uniform writeonly image2D img_rtwImportance2D;
|
||||
|
||||
uniform sampler2D shadowcolor0;
|
||||
|
||||
void main(){
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
vec2 uv = (vec2(texel) + 0.5) / vec2(RTW_RESOLUTION, RTW_RESOLUTION_Y);
|
||||
|
||||
// Sample shadow map depth (in the shadow region)
|
||||
vec2 shadowUv = vec2(uv.x * 0.5 + 0.5, uv.y * 0.5); // map to right region
|
||||
vec2 shadowTexel = shadowUv * shadowSize;
|
||||
|
||||
vec4 shadowData = texelFetch(shadowcolor0, ivec2(shadowTexel), 0);
|
||||
|
||||
float depth = shadowData.a;
|
||||
float importance = 0.0;
|
||||
|
||||
if (depth < 1.0){
|
||||
// Depth-based importance: closer = more important
|
||||
float dist = 1.0 - depth;
|
||||
importance = pow(dist, 2.0) * RTW_BACKWARD_DIST_FACTOR;
|
||||
|
||||
// Depth gradient importance (edges)
|
||||
float dLeft = texelFetch(shadowcolor0, ivec2(shadowTexel) + ivec2(-1, 0), 0).a;
|
||||
float dRight = texelFetch(shadowcolor0, ivec2(shadowTexel) + ivec2(1, 0), 0).a;
|
||||
float dUp = texelFetch(shadowcolor0, ivec2(shadowTexel) + ivec2(0, -1), 0).a;
|
||||
float dDown = texelFetch(shadowcolor0, ivec2(shadowTexel) + ivec2(0, 1), 0).a;
|
||||
|
||||
float gradient = abs(dLeft - dRight) + abs(dUp - dDown);
|
||||
importance += gradient * 0.5 * RTW_BACKWARD_NORMAL_FACTOR;
|
||||
}
|
||||
|
||||
imageStore(img_rtwImportance2D, texel, vec4(importance));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// MinecraftPT — RTWSM Blur Importance
|
||||
// Gaussian-blurs the importance map to make the warp smooth.
|
||||
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
|
||||
const ivec3 workGroups = ivec3(32, 16, 1);
|
||||
layout (local_size_x = 32, local_size_y = 32) in;
|
||||
|
||||
layout (r32f) uniform writeonly image2D img_rtwImportance2D;
|
||||
|
||||
uniform sampler2D rtwImportance2D;
|
||||
|
||||
void main(){
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
float importance = 0.0;
|
||||
float weightSum = 0.0;
|
||||
|
||||
int radius = int(RTW_BLUR_FACTOR);
|
||||
|
||||
for (int i = -radius; i <= radius; i++){
|
||||
for (int j = -radius; j <= radius; j++){
|
||||
vec2 coord = vec2(texel + ivec2(i, j)) / vec2(RTW_RESOLUTION, RTW_RESOLUTION_Y);
|
||||
float w = exp(-(i * i + j * j) / (2.0 * RTW_BLUR_FACTOR * RTW_BLUR_FACTOR));
|
||||
importance += textureLod(rtwImportance2D, coord, 0.0).r * w;
|
||||
weightSum += w;
|
||||
}}
|
||||
|
||||
imageStore(img_rtwImportance2D, texel, vec4(importance / weightSum));
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// MinecraftPT — RTWSM Building Warp
|
||||
// Builds the final warp curve (cumulative importance) from the importance map.
|
||||
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
|
||||
const ivec3 workGroups = ivec3(32, 1, 1);
|
||||
layout (local_size_x = 32) in;
|
||||
|
||||
layout (rg16) uniform writeonly image2D img_rtwWarp1D;
|
||||
|
||||
uniform sampler2D rtwImportance2D;
|
||||
|
||||
void main(){
|
||||
int y = int(gl_GlobalInvocationID.y);
|
||||
|
||||
// Compute the cumulative importance curve for this row
|
||||
float total = 0.0;
|
||||
for (int x = 0; x < RTW_RESOLUTION; x++){
|
||||
total += textureLod(rtwImportance2D, vec2(float(x) / float(RTW_RESOLUTION), float(y) / float(RTW_RESOLUTION_Y)), 0.0).r;
|
||||
}
|
||||
|
||||
// Write warp curve: row 0 = cumulative, row 1 = inverse
|
||||
if (total > 0.0){
|
||||
float cum = 0.0;
|
||||
for (int x = 0; x < RTW_RESOLUTION; x++){
|
||||
cum += textureLod(rtwImportance2D, vec2(float(x) / float(RTW_RESOLUTION), float(y) / float(RTW_RESOLUTION_Y)), 0.0).r;
|
||||
imageStore(img_rtwWarp1D, ivec2(x, 0), vec4(cum / total, 0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
// Inverse: for each output position find input position
|
||||
for (int x = 0; x < RTW_RESOLUTION; x++){
|
||||
float target = float(x) / float(RTW_RESOLUTION - 1);
|
||||
int lo = 0;
|
||||
int hi = RTW_RESOLUTION - 1;
|
||||
for (int i = 0; i < 10; i++){
|
||||
int mid = (lo + hi) / 2;
|
||||
float v = textureLod(rtwImportance2D, vec2(float(mid) / float(RTW_RESOLUTION), float(y) / float(RTW_RESOLUTION_Y)), 0.0).r;
|
||||
if (v < target) lo = mid; else hi = mid;
|
||||
}
|
||||
float inv = float(lo) / float(RTW_RESOLUTION);
|
||||
imageStore(img_rtwWarp1D, ivec2(x, 1), vec4(inv, 0.0, 0.0, 0.0));
|
||||
}
|
||||
}else{
|
||||
// Identity warp
|
||||
for (int x = 0; x < RTW_RESOLUTION; x++){
|
||||
float v = float(x) / float(RTW_RESOLUTION);
|
||||
imageStore(img_rtwWarp1D, ivec2(x, 0), vec4(v, 0.0, 0.0, 0.0));
|
||||
imageStore(img_rtwWarp1D, ivec2(x, 1), vec4(v, 0.0, 0.0, 0.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// MinecraftPT — RTWSM Collapse Importance
|
||||
// Collapses the 2D importance map into a 1D cumulative curve per row.
|
||||
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
|
||||
const ivec3 workGroups = ivec3(RTW_RESOLUTION, 1, 1);
|
||||
layout (local_size_x = 1) in;
|
||||
|
||||
layout (r32f) uniform writeonly image2D img_rtwImportance2D;
|
||||
layout (rg16) uniform writeonly image2D img_rtwWarp1D;
|
||||
|
||||
uniform sampler2D rtwImportance2D;
|
||||
|
||||
void main(){
|
||||
int y = int(gl_GlobalInvocationID.y);
|
||||
|
||||
// Sum importance across rows -> 1D profile
|
||||
float sum = 0.0;
|
||||
for (int x = 0; x < RTW_RESOLUTION; x++){
|
||||
sum += textureLod(rtwImportance2D, vec2(float(x) / float(RTW_RESOLUTION), float(y) / float(RTW_RESOLUTION_Y)), 0.0).r;
|
||||
}
|
||||
|
||||
// Build cumulative distribution
|
||||
float cumulative = 0.0;
|
||||
for (int x = 0; x < RTW_RESOLUTION; x++){
|
||||
float imp = textureLod(rtwImportance2D, vec2(float(x) / float(RTW_RESOLUTION), float(y) / float(RTW_RESOLUTION_Y)), 0.0).r;
|
||||
cumulative += imp;
|
||||
float normalized = sum > 0.0 ? cumulative / sum : float(x) / float(RTW_RESOLUTION);
|
||||
|
||||
imageStore(img_rtwWarp1D, ivec2(x, y), vec4(normalized, 1.0 - normalized, 0.0, 0.0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "/Lib/Settings.glsl"
|
||||
#include "/Lib/Utilities.glsl"
|
||||
// MinecraftPT — RTWSM SampleWarp
|
||||
// Samples the warp map to redistribute shadow map coordinates.
|
||||
|
||||
#ifndef SAMPLE_WARP_GLSL
|
||||
uniform sampler2D rtwWarp1D;
|
||||
#define SAMPLE_WARP_GLSL
|
||||
|
||||
// Warp curve sampling: rtwWarp1D is a RG16 texture, RTW_RESOLUTION x 2
|
||||
// Row 0: warp curve (cumulative importance), Row 1: inverse warp curve
|
||||
vec2 SampleWarp(float value){
|
||||
vec2 coord = vec2(value * (RTW_RESOLUTION - 1.0) + 0.5, 0.5) / vec2(RTW_RESOLUTION, 2.0);
|
||||
return textureLod(rtwWarp1D, coord, 0.0).rg;
|
||||
}
|
||||
|
||||
// Smooth warp sampling with lerp
|
||||
vec2 SampleRTWWarpSmooth(vec2 shadowScreenPos){
|
||||
// The warp is 1D along the shadow map's X axis (sun direction)
|
||||
float u = saturate(shadowScreenPos.x);
|
||||
|
||||
// Sample warp curve
|
||||
vec2 warp = SampleWarp(u);
|
||||
|
||||
// Apply warp: remap x based on cumulative importance
|
||||
float warpedX = warp.x;
|
||||
|
||||
// Also apply to y for 2D warping (using second channel)
|
||||
float warpedY = warp.y;
|
||||
|
||||
return vec2(warpedX - u, warpedY - shadowScreenPos.y);
|
||||
}
|
||||
|
||||
// Full warp application for shadow map sampling
|
||||
vec2 WarpShadowCoord(vec2 shadowScreenPos){
|
||||
float u = saturate(shadowScreenPos.x);
|
||||
vec2 warp = SampleWarp(u);
|
||||
|
||||
vec2 warped = vec2(warp.x, warp.y);
|
||||
|
||||
// The warp curve maps [0,1] -> [0,1] cumulative
|
||||
// Inverse: sample with the inverse curve
|
||||
return warped;
|
||||
}
|
||||
|
||||
// Unwarp (for reconstructing world positions)
|
||||
vec2 UnwarpShadowCoord(vec2 warpedCoord){
|
||||
// Binary search on the warp curve (forward map)
|
||||
float low = 0.0;
|
||||
float high = 1.0;
|
||||
|
||||
for (int i = 0; i < 8; i++){
|
||||
float mid = (low + high) * 0.5;
|
||||
vec2 sample = SampleWarp(mid);
|
||||
if (sample.x < warpedCoord.x){
|
||||
low = mid;
|
||||
}else{
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
|
||||
return vec2((low + high) * 0.5, warpedCoord.y);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user