first commit
This commit is contained in:
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
This file is specifically licensed with Mozilla Public License Version 2.0.
|
||||
You can get a copy from https://www.mozilla.org/MPL/2.0/
|
||||
*/
|
||||
|
||||
float manualDeterminant(mat2 matrix) {
|
||||
return matrix[0].x * matrix[1].y - matrix[0].y * matrix[1].x;
|
||||
}
|
||||
|
||||
mat2 inverseM(mat2 m) {
|
||||
#if MC_VERSION >= 11700
|
||||
return inverse(m);
|
||||
#else
|
||||
mat2 adj;
|
||||
adj[0][0] = m[1][1];
|
||||
adj[0][1] = -m[0][1];
|
||||
adj[1][0] = -m[1][0];
|
||||
adj[1][1] = m[0][0];
|
||||
return adj / manualDeterminant(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 textureAF(sampler2D texSampler, vec2 uv) {
|
||||
vec2 spriteDimensions = vec2(spriteBounds.z - spriteBounds.x, spriteBounds.w - spriteBounds.y);
|
||||
|
||||
mat2 J = inverseM(mat2(dFdx(uv), dFdy(uv)));
|
||||
J = transpose(J)*J;
|
||||
float d = manualDeterminant(J), t = J[0][0]+J[1][1],
|
||||
D = sqrt(abs(t*t-4.001*d)), // using 4.001 instead of 4.0 fixes a rare texture glitch with square texture atlas
|
||||
V = (t-D)/2.0, v = (t+D)/2.0,
|
||||
M = 1.0/sqrt(V), m = 1./sqrt(v);
|
||||
vec2 A = M * normalize(vec2(-J[0][1], J[0][0]-V));
|
||||
|
||||
float lod = 0.0;
|
||||
#if ANISOTROPIC_FILTER >= 8 && defined GBUFFERS_TERRAIN
|
||||
#if MC_VERSION < 12111
|
||||
// Excluding cutout blocks because cutout mipmaps suck in older mc versions
|
||||
if (texture2DLod(texSampler, uv, 10000.0).a == 1.0)
|
||||
#endif
|
||||
|
||||
// Fix257062 - Checking if absMidCoordPos is fine or else miplevel will be broken. This can be an issue for flowing lava.
|
||||
if (absMidCoordPos.x > 0.0001 && absMidCoordPos.y > 0.0001)
|
||||
lod = miplevel * 0.4;
|
||||
#endif
|
||||
|
||||
float samplesDiv2 = ANISOTROPIC_FILTER / 2.0;
|
||||
vec2 ADivSamples = A / ANISOTROPIC_FILTER;
|
||||
|
||||
vec4 filteredColor = vec4(0.0);
|
||||
float totalModifiedAlpha = 0.0;
|
||||
vec4 spriteBoundsM = mix(spriteBounds, vec4(midCoord, midCoord), 0.0001); // Fixes some mods causing issues with cutout blocks
|
||||
for (float i = -samplesDiv2 + 0.5; i < samplesDiv2; i++) {
|
||||
vec2 sampleUV = uv + ADivSamples * i;
|
||||
sampleUV = clamp(sampleUV, spriteBoundsM.xy, spriteBoundsM.zw);
|
||||
vec4 colorSample = texture2DLod(texSampler, sampleUV, lod);
|
||||
|
||||
colorSample.a = sqrt(colorSample.a); // Tweak to make cutout blocks look fuller in the distance
|
||||
|
||||
#if !defined POM || !defined POM_ALLOW_CUTOUT
|
||||
float modifiedAlpha = colorSample.a;
|
||||
#else
|
||||
// To avoid NaNs because we don't discard low alpha if POM_ALLOW_CUTOUT is enabled (see 6WIR4HT23)
|
||||
float modifiedAlpha = max(colorSample.a, 0.00001);
|
||||
#endif
|
||||
|
||||
totalModifiedAlpha += modifiedAlpha;
|
||||
filteredColor.rgb += colorSample.rgb * modifiedAlpha;
|
||||
filteredColor.a += colorSample.a;
|
||||
}
|
||||
filteredColor.rgb /= totalModifiedAlpha;
|
||||
filteredColor.a /= ANISOTROPIC_FILTER;
|
||||
|
||||
return filteredColor;
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#define ENTITY_GN_AND_CT
|
||||
#define COATED_TEXTURE_MULT 100 //[25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 110 120 130 140 150 160 170 180 190 200]
|
||||
#define COATED_TEXTURE_RES 64 //[16 32 64 80 96 112 128 144 160 176 192 208 224 240 256 320 384 448 512]
|
||||
const float packSizeNT = COATED_TEXTURE_RES;
|
||||
|
||||
void CoatTextures(inout vec3 color, float noiseFactor, vec3 playerPos, bool doTileRandomisation) {
|
||||
#ifndef ENTITY_GN_AND_CT
|
||||
#if defined GBUFFERS_ENTITIES || defined GBUFFERS_HAND
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SAFER_GENERATED_NORMALS
|
||||
vec2 noiseCoord = floor(midCoordPos / 16.0 * packSizeNT * atlasSizeM) / packSizeNT / 3.0;
|
||||
#else
|
||||
vec2 offsetR = max(absMidCoordPos.x, absMidCoordPos.y) * vec2(float(atlasSizeM.y) / float(atlasSizeM.x), 1.0);
|
||||
vec2 noiseCoord = floor(midCoordPos / 2.0 * packSizeNT / offsetR) / packSizeNT / 3.0;
|
||||
#endif
|
||||
|
||||
if (doTileRandomisation) {
|
||||
vec3 floorWorldPos = floor(playerPos + cameraPosition + 0.001);
|
||||
noiseCoord += 0.84 * (floorWorldPos.xz + floorWorldPos.y);
|
||||
}
|
||||
|
||||
float noiseTexture = texture2DLod(noisetex, noiseCoord, 0.0).r;
|
||||
noiseTexture = noiseTexture + 0.6;
|
||||
float colorBrightness = dot(color, color) * 0.3;
|
||||
#define COATED_TEXTURE_MULT_M COATED_TEXTURE_MULT * 0.0027
|
||||
noiseFactor *= COATED_TEXTURE_MULT_M * max0(1.0 - colorBrightness);
|
||||
noiseFactor *= max(1.0 - miplevel * 0.25, 0.0);
|
||||
noiseTexture = pow(noiseTexture, noiseFactor);
|
||||
color *= noiseTexture;
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
ivec3[6] glassOffsets = ivec3[](
|
||||
ivec3( 1, 0, 0),
|
||||
ivec3(-1, 0, 0),
|
||||
ivec3( 0, 1, 0),
|
||||
ivec3( 0,-1, 0),
|
||||
ivec3( 0, 0, 1),
|
||||
ivec3( 0, 0,-1)
|
||||
);
|
||||
|
||||
ivec3[12] glassCornerOffsets = ivec3[](
|
||||
ivec3( 1, 1, 0),
|
||||
ivec3( 1,-1, 0),
|
||||
ivec3(-1, 1, 0),
|
||||
ivec3(-1,-1, 0),
|
||||
ivec3( 0, 1, 1),
|
||||
ivec3( 0, 1,-1),
|
||||
ivec3( 0,-1, 1),
|
||||
ivec3( 0,-1,-1),
|
||||
ivec3( 1, 0, 1),
|
||||
ivec3( 1, 0,-1),
|
||||
ivec3(-1, 0, 1),
|
||||
ivec3(-1, 0,-1)
|
||||
);
|
||||
|
||||
vec2 GetModifiedMidCoord() {
|
||||
float epsilon1 = 0.00001;
|
||||
vec2 midCoord = texCoord - signMidCoordPos * absMidCoordPos;
|
||||
return midCoord - epsilon1;
|
||||
}
|
||||
|
||||
void DoSimpleConnectedGlass(inout vec4 color) {
|
||||
color = texture2DLod(tex, GetModifiedMidCoord() - 0.125 * absMidCoordPos, 0);
|
||||
}
|
||||
|
||||
#ifdef GBUFFERS_WATER
|
||||
void DoConnectedGlass(inout vec4 colorP, inout vec4 color, inout bool noGeneratedNormals, vec3 playerPos, vec3 worldGeoNormal, uint voxelID, bool isPane) {
|
||||
vec3 worldGeoNormalM = vec3( // Fixes Iris 1.8 normal precision issues causing the coordinates to be imperfect
|
||||
round(worldGeoNormal.x),
|
||||
round(worldGeoNormal.y),
|
||||
round(worldGeoNormal.z)
|
||||
);
|
||||
vec3 playerPosM = playerPos - worldGeoNormalM * 0.25;
|
||||
vec3 voxelPos = SceneToVoxel(playerPosM);
|
||||
|
||||
if (CheckInsideVoxelVolume(voxelPos)) {
|
||||
#if IRIS_VERSION >= 10800
|
||||
float epsilon2 = 0.0;
|
||||
#else
|
||||
float epsilon2 = 0.001;
|
||||
#endif
|
||||
float pixelOffset = 0.5 / (absMidCoordPos.y * atlasSize.y);
|
||||
float pixelOffsetPlus = pixelOffset + epsilon2;
|
||||
float pixelOffsetMinus = pixelOffset - epsilon2;
|
||||
|
||||
colorP = texture2DLod(tex, texCoord, 0);
|
||||
vec4 colorPvanilla = colorP;
|
||||
|
||||
vec2 midCoordM = GetModifiedMidCoord();
|
||||
vec3 worldPos = playerPosM + cameraPositionBestFract;
|
||||
vec3 floorWorldPos = floor(worldPos);
|
||||
|
||||
// Remove edges
|
||||
for (int i = 0; i < 6; i++) {
|
||||
uint voxel = GetVoxelVolume(ivec3(voxelPos) + glassOffsets[i]);
|
||||
if (voxel == voxelID) {
|
||||
if (floor(worldPos + glassOffsets[i] * pixelOffsetPlus) != floorWorldPos) {
|
||||
colorP = texture2DLod(tex, midCoordM, 0);
|
||||
}
|
||||
#ifdef GENERATED_NORMALS
|
||||
if (floor(worldPos + glassOffsets[i] * pixelOffsetPlus * 1.25) != floorWorldPos) {
|
||||
noGeneratedNormals = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Fixes the connections by restoring the edges that aren't connected
|
||||
for (int i = 0; i < 6; i++) {
|
||||
uint voxel = GetVoxelVolume(ivec3(voxelPos) + glassOffsets[i]);
|
||||
if (voxel != voxelID) {
|
||||
//if (floor(worldPos + glassOffsets[i] * 0.0625) != floorWorldPos) {
|
||||
if (floor(worldPos + glassOffsets[i] * pixelOffsetMinus) != floorWorldPos) {
|
||||
colorP = colorPvanilla;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPane) {
|
||||
// Fixes lines between layers of glass panes
|
||||
if (NdotU > 0.9) {
|
||||
uint voxel = GetVoxelVolume(ivec3(voxelPos) + ivec3(0, 1, 0));
|
||||
if (voxel == voxelID) discard;
|
||||
}
|
||||
if (NdotU < -0.9) {
|
||||
uint voxel = GetVoxelVolume(ivec3(voxelPos) - ivec3(0, 1, 0));
|
||||
if (voxel == voxelID) discard;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONNECTED_GLASS_CORNER_FIX
|
||||
// Restores corners
|
||||
for (int i = 0; i < 12; i++) {
|
||||
uint voxel = GetVoxelVolume(ivec3(voxelPos) + glassCornerOffsets[i]);
|
||||
if ((voxel != voxelID) && (!isPane || voxel > 0u)) {
|
||||
if (floor((worldPos - glassCornerOffsets[i] * (1.0 - pixelOffsetMinus))) == floorWorldPos) {
|
||||
colorP = colorPvanilla;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
color = colorP * vec4(glColor.rgb, 1.0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#ifndef INCLUDE_CUSTOM_EMISSION
|
||||
#define INCLUDE_CUSTOM_EMISSION
|
||||
|
||||
float GetCustomEmission(vec4 specularMap, vec2 texCoordM) {
|
||||
#if CUSTOM_EMISSION_INTENSITY > 0
|
||||
#if RP_MODE == 2 || RP_MODE == 1 && IPBR_EMISSIVE_MODE == 2 // seuspbr
|
||||
float emission = specularMap.b;
|
||||
#elif RP_MODE == 3 || RP_MODE == 1 && IPBR_EMISSIVE_MODE == 3 // labPBR
|
||||
float emission = specularMap.a < 1.0 ? specularMap.a : 0.0;
|
||||
|
||||
vec4 specularMapL0 = texture2DLod(specular, texCoordM, 0);
|
||||
float emissionL0 = specularMapL0.a < 1.0 ? specularMapL0.a : 0.0;
|
||||
emission = min(emission, emissionL0); // Fixes issues caused by mipmaps
|
||||
#endif
|
||||
|
||||
return emission * 0.03 * CUSTOM_EMISSION_INTENSITY;
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef IPBR
|
||||
float GetCustomEmissionForIPBR(inout vec4 color, float emission) {
|
||||
vec4 specularMapCheck = texture2DLod(specular, texCoord, 1000.0);
|
||||
if (specularMapCheck.a == 0.0) return emission;
|
||||
|
||||
color = texture2D(tex, texCoord);
|
||||
|
||||
vec4 specularMap = texture2D(specular, texCoord);
|
||||
float customEmission = GetCustomEmission(specularMap, texCoord);
|
||||
return customEmission;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //INCLUDE_CUSTOM_EMISSION
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
#define ENTITY_GN_AND_CT
|
||||
#define GENERATED_NORMAL_MULT 100 //[25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 110 120 130 140 150 160 170 180 190 200 250 300 400]
|
||||
#define GENERATED_NORMAL_ENTITY_MULT 0 //[0 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 110 120 130 140 150 160 170 180 190 200 250 300 400]
|
||||
#define NORMAL_RES 128 //[16 32 64 80 96 112 128 144 160 176 192 208 224 240 256 320 384 448 512]
|
||||
|
||||
const float normalThreshold = 0.05;
|
||||
const float normalClamp = 0.2;
|
||||
const float packSizeGN = 128.0;
|
||||
|
||||
#ifdef GBUFFERS_ENTITIES
|
||||
#if GENERATED_NORMAL_ENTITY_MULT > 0
|
||||
const float normalMult = GENERATED_NORMAL_ENTITY_MULT * 0.025;
|
||||
#else
|
||||
const float normalMult = GENERATED_NORMAL_MULT * 0.025;
|
||||
#endif
|
||||
#elif !defined GBUFFERS_HAND
|
||||
const float normalMult = GENERATED_NORMAL_MULT * 0.025;
|
||||
#else
|
||||
const float normalMult = GENERATED_NORMAL_MULT * 0.015;
|
||||
#endif
|
||||
|
||||
float GetDif(float lOriginalAlbedo, vec2 offsetCoord) {
|
||||
#ifndef GBUFFERS_WATER
|
||||
float lNearbyAlbedo = length(texture2D(tex, offsetCoord).rgb);
|
||||
#else
|
||||
vec4 textureSample = texture2D(tex, offsetCoord);
|
||||
float lNearbyAlbedo = length(textureSample.rgb * textureSample.a * 1.5);
|
||||
#endif
|
||||
|
||||
#ifdef GBUFFERS_ENTITIES
|
||||
lOriginalAlbedo = abs(lOriginalAlbedo - 1.0);
|
||||
lNearbyAlbedo = abs(lNearbyAlbedo - 1.0);
|
||||
#endif
|
||||
|
||||
float dif = lOriginalAlbedo - lNearbyAlbedo;
|
||||
|
||||
#ifdef GBUFFERS_ENTITIES
|
||||
dif = -dif;
|
||||
#endif
|
||||
|
||||
#ifndef GBUFFERS_WATER
|
||||
if (dif > 0.0) dif = max(dif - normalThreshold, 0.0);
|
||||
else dif = min(dif + normalThreshold, 0.0);
|
||||
#endif
|
||||
|
||||
return clamp(dif, -normalClamp, normalClamp);
|
||||
}
|
||||
|
||||
void GenerateNormals(inout vec3 normalM, vec3 color) {
|
||||
#ifndef ENTITY_GN_AND_CT
|
||||
#if defined GBUFFERS_ENTITIES || defined GBUFFERS_HAND
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec2 absMidCoordPos2 = absMidCoordPos * 2.0;
|
||||
float lOriginalAlbedo = length(color.rgb);
|
||||
|
||||
float normalMult = max0(1.0 - mipDelta) * normalMult;
|
||||
|
||||
#ifndef SAFER_GENERATED_NORMALS
|
||||
vec2 offsetR = 16.0 / atlasSizeM;
|
||||
#else
|
||||
vec2 offsetR = max(absMidCoordPos2.x, absMidCoordPos2.y) * vec2(float(atlasSizeM.y) / float(atlasSizeM.x), 1.0);
|
||||
#endif
|
||||
offsetR /= NORMAL_RES;
|
||||
|
||||
vec2 midCoord = texCoord - midCoordPos;
|
||||
vec2 maxOffsetCoord = midCoord + absMidCoordPos;
|
||||
vec2 minOffsetCoord = midCoord - absMidCoordPos;
|
||||
if (normalMult > 0.0) {
|
||||
vec3 normalMap = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
vec2 offsetCoord = texCoord + vec2( 0.0, offsetR.y);
|
||||
if (offsetCoord.y < maxOffsetCoord.y)
|
||||
normalMap.y += GetDif(lOriginalAlbedo, offsetCoord);
|
||||
|
||||
offsetCoord = texCoord + vec2( offsetR.x, 0.0);
|
||||
if (offsetCoord.x < maxOffsetCoord.x)
|
||||
normalMap.x += GetDif(lOriginalAlbedo, offsetCoord);
|
||||
|
||||
offsetCoord = texCoord + vec2( 0.0,-offsetR.y);
|
||||
if (offsetCoord.y > minOffsetCoord.y)
|
||||
normalMap.y -= GetDif(lOriginalAlbedo, offsetCoord);
|
||||
|
||||
offsetCoord = texCoord + vec2(-offsetR.x, 0.0);
|
||||
if (offsetCoord.x > minOffsetCoord.x)
|
||||
normalMap.x -= GetDif(lOriginalAlbedo, offsetCoord);
|
||||
|
||||
normalMap.xy *= normalMult;
|
||||
normalMap.xy = clamp(normalMap.xy, vec2(-1.0), vec2(1.0));
|
||||
|
||||
if (normalMap.xy != vec2(0.0, 0.0))
|
||||
normalM = clamp(normalize(normalMap * tbnMatrix), vec3(-1.0), vec3(1.0));
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
bool intersectsAABB(vec3 ro, vec3 rd, vec3 aabbMin, vec3 aabbMax) {
|
||||
vec3 t0 = (aabbMin - ro) / rd;
|
||||
vec3 t1 = (aabbMax - ro) / rd;
|
||||
|
||||
vec3 tMin = min(t0, t1);
|
||||
vec3 tMax = max(t0, t1);
|
||||
|
||||
float m0 = max(max(tMin.x, tMin.y), tMin.z);
|
||||
float m1 = min(min(tMax.x, tMax.y), tMax.z);
|
||||
|
||||
return m1 > max0(m0);
|
||||
}
|
||||
|
||||
bool intersectsParallelogram(vec3 ro, vec3 rd, vec3 v0, vec3 v1, vec3 v2, float tMin, out float t, out vec2 uv, inout vec3 normal) {
|
||||
vec3 a = v1 - v0, n = cross(a, v2 - v0);
|
||||
|
||||
t = dot(v0 - ro, n) / dot(n, rd);
|
||||
if (t < 0.0 || t > tMin) return false;
|
||||
|
||||
vec3 b = v2 - v1;
|
||||
vec3 c = ro + rd * t - v0;
|
||||
|
||||
uv = vec2(dot(c, a) / dot(a, a), dot(c, b) / dot(b, b));
|
||||
if (uv.x < 0.0 || uv.y < 0.0 || uv.x > 1.0 || uv.y > 1.0) return false;
|
||||
|
||||
normal = normalize(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckQuadAt(int i, vec3 playerPos, vec3 rayDir, inout vec3 albedo, inout float tMin, inout vec3 normal, inout float emissionOut) {
|
||||
int i0 = 3 * i, i1 = 3 * i + 1, i2 = 3 * i + 2;
|
||||
|
||||
vec3 v0 = playerVerticesSSBO.vertexPositions[i0];
|
||||
vec3 v1 = playerVerticesSSBO.vertexPositions[i1];
|
||||
vec3 v2 = playerVerticesSSBO.vertexPositions[i2];
|
||||
|
||||
float t;
|
||||
vec2 uv;
|
||||
|
||||
vec3 colorP;
|
||||
vec3 color;
|
||||
float emission = 0.0;
|
||||
float smoothnessD, smoothnessG;
|
||||
if (intersectsParallelogram(playerPos, rayDir, v0, v1, v2, tMin, t, uv, normal)) {
|
||||
vec2 texCoord0 = playerVerticesSSBO.vertexData[i0];
|
||||
vec2 texCoord1 = playerVerticesSSBO.vertexData[i1];
|
||||
vec2 texCoord2 = playerVerticesSSBO.vertexData[i2];
|
||||
|
||||
vec2 quadTexCoord = mix(texCoord0, texCoord1, uv.x) + uv.y * (texCoord2 - texCoord1);
|
||||
vec4 playerAtlasSample = texelFetch(playerAtlas_sampler, ivec2(64 * quadTexCoord), 0);
|
||||
|
||||
vec3 colorP = playerAtlasSample.rgb;
|
||||
vec3 color = playerAtlasSample.rgb;
|
||||
|
||||
#ifdef SPACEAGLE17
|
||||
#include "/lib/materials/specificMaterials/others/SpacEagle17.glsl"
|
||||
#endif
|
||||
if (playerAtlasSample.a > 0.2) {albedo = color * (emission * 0.2 + 1.0); tMin = t; emissionOut = emission;}
|
||||
}
|
||||
}
|
||||
|
||||
bool rayTracePlayer(vec3 playerPos, vec3 rayDir, float wsrTraceLength, out vec3 albedo, out vec3 normal, out float emission) {
|
||||
float tMin = wsrTraceLength;
|
||||
vec3 aabbPos = playerPos * 1000.0;
|
||||
|
||||
// Head
|
||||
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.headMin, playerVerticesSSBO.bounds.headMax)) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
||||
}
|
||||
}
|
||||
// Right Hand
|
||||
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.rightHandMin, playerVerticesSSBO.bounds.rightHandMax)) {
|
||||
for (int i = 12; i < 24; i++) {
|
||||
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
||||
}
|
||||
}
|
||||
// Left Leg
|
||||
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.leftLegMin, playerVerticesSSBO.bounds.leftLegMax)) {
|
||||
for (int i = 24; i < 36; i++) {
|
||||
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
||||
}
|
||||
}
|
||||
// Left Hand
|
||||
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.leftHandMin, playerVerticesSSBO.bounds.leftHandMax)) {
|
||||
for (int i = 36; i < 48; i++) {
|
||||
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
||||
}
|
||||
}
|
||||
// Right leg
|
||||
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.rightLegMin, playerVerticesSSBO.bounds.rightLegMax)) {
|
||||
for (int i = 48; i < 60; i++) {
|
||||
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
||||
}
|
||||
}
|
||||
// Torso
|
||||
if (intersectsAABB(aabbPos, rayDir, playerVerticesSSBO.bounds.torsoMin, playerVerticesSSBO.bounds.torsoMax)) {
|
||||
for (int i = 60; i < 72; i++) {
|
||||
CheckQuadAt(i, playerPos, rayDir, albedo, tMin, normal, emission);
|
||||
}
|
||||
}
|
||||
|
||||
return tMin < wsrTraceLength;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "/lib/util/dither.glsl"
|
||||
|
||||
vec2 vTexCoord = signMidCoordPos * 0.5 + 0.5;
|
||||
|
||||
#include "/lib/util/dFdxdFdy.glsl"
|
||||
|
||||
vec4 ReadNormal(vec2 coord) {
|
||||
coord = fract(coord) * vTexCoordAM.pq + vTexCoordAM.st;
|
||||
return textureGrad(normals, coord, dcdx, dcdy);
|
||||
}
|
||||
|
||||
vec2 GetParallaxCoord(float parallaxFade, float dither, inout vec2 newCoord, inout float texDepth, inout vec3 traceCoordDepth) {
|
||||
float invParallaxQuality = 1.0 / POM_QUALITY;
|
||||
vec4 normalMap = ReadNormal(vTexCoord.st);
|
||||
vec2 normalMapM = normalMap.xy * 2.0 - 1.0;
|
||||
float normalCheck = normalMapM.x + normalMapM.y;
|
||||
float minHeight = 1.0 - invParallaxQuality;
|
||||
|
||||
if (viewVector.z >= 0.0 || normalMap.a >= minHeight || normalCheck <= -1.999) return vTexCoord.st;
|
||||
|
||||
vec2 interval = viewVector.xy * 0.25 * (1.0 - parallaxFade) * POM_DEPTH / (-viewVector.z * POM_QUALITY);
|
||||
|
||||
float i = 0.0;
|
||||
vec2 localCoord;
|
||||
#if defined GBUFFERS_TERRAIN || defined GBUFFERS_BLOCK
|
||||
if (texDepth <= 1.0 - i * invParallaxQuality) {
|
||||
localCoord = vTexCoord.st + i * interval;
|
||||
texDepth = ReadNormal(localCoord).a;
|
||||
i = dither;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; i < POM_QUALITY && texDepth <= 1.0 - i * invParallaxQuality; i++) {
|
||||
localCoord = vTexCoord.st + i * interval;
|
||||
texDepth = ReadNormal(localCoord).a;
|
||||
}
|
||||
|
||||
float pI = float(max(i - 1, 0));
|
||||
traceCoordDepth.xy -= pI * interval;
|
||||
traceCoordDepth.z -= pI * invParallaxQuality;
|
||||
|
||||
localCoord = fract(vTexCoord.st + pI * interval);
|
||||
newCoord = localCoord * vTexCoordAM.pq + vTexCoordAM.st;
|
||||
return localCoord;
|
||||
}
|
||||
|
||||
float GetParallaxShadow(float parallaxFade, float dither, float height, vec2 coord, vec3 lightVec, mat3 tbn) {
|
||||
float parallaxshadow = 1.0;
|
||||
|
||||
vec3 parallaxdir = tbn * lightVec;
|
||||
parallaxdir.xy *= 1.0 * POM_DEPTH; // Angle
|
||||
|
||||
for (int i = 0; i < 4 && parallaxshadow >= 0.01; i++) {
|
||||
float stepLC = 0.025 * (i + dither);
|
||||
|
||||
float currentHeight = height + parallaxdir.z * stepLC;
|
||||
|
||||
vec2 parallaxCoord = fract(coord + parallaxdir.xy * stepLC) * vTexCoordAM.pq + vTexCoordAM.st;
|
||||
float offsetHeight = textureGrad(normals, parallaxCoord, dcdx, dcdy).a;
|
||||
|
||||
parallaxshadow *= clamp(1.0 - (offsetHeight - currentHeight) * 4.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
return mix(parallaxshadow, 1.0, parallaxFade);
|
||||
}
|
||||
|
||||
// Big thanks to null511 for slope normals
|
||||
vec3 GetParallaxSlopeNormal(vec2 texCoord, float traceDepth, vec3 viewDir) {
|
||||
vec2 atlasPixelSize = 1.0 / atlasSize;
|
||||
float atlasAspect = atlasSize.x / atlasSize.y;
|
||||
vec2 atlasCoord = fract(texCoord) * vTexCoordAM.pq + vTexCoordAM.st;
|
||||
|
||||
vec2 tileSize = atlasSize * vTexCoordAM.pq;
|
||||
vec2 tilePixelSize = 1.0 / tileSize;
|
||||
|
||||
vec2 tex_snapped = floor(atlasCoord * atlasSize) * atlasPixelSize;
|
||||
vec2 tex_offset = atlasCoord - (tex_snapped + 0.5 * atlasPixelSize);
|
||||
|
||||
vec2 stepSign = sign(tex_offset);
|
||||
vec2 viewSign = sign(viewDir.xy);
|
||||
|
||||
bool dir = abs(tex_offset.x * atlasAspect) < abs(tex_offset.y);
|
||||
vec2 tex_x, tex_y;
|
||||
|
||||
if (dir) {
|
||||
tex_x = texCoord - vec2(tilePixelSize.x * viewSign.x, 0.0);
|
||||
tex_y = texCoord + vec2(0.0, stepSign.y * tilePixelSize.y);
|
||||
}
|
||||
else {
|
||||
tex_x = texCoord + vec2(tilePixelSize.x * stepSign.x, 0.0);
|
||||
tex_y = texCoord - vec2(0.0, viewSign.y * tilePixelSize.y);
|
||||
}
|
||||
|
||||
float height_x = ReadNormal(tex_x).a;
|
||||
float height_y = ReadNormal(tex_y).a;
|
||||
|
||||
if (dir) {
|
||||
if (!(traceDepth > height_y && viewSign.y != stepSign.y)) {
|
||||
if (traceDepth > height_x) return vec3(-viewSign.x, 0.0, 0.0);
|
||||
|
||||
if (abs(viewDir.y) > abs(viewDir.x))
|
||||
return vec3(0.0, -viewSign.y, 0.0);
|
||||
else
|
||||
return vec3(-viewSign.x, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return vec3(0.0, -viewSign.y, 0.0);
|
||||
}
|
||||
else {
|
||||
if (!(traceDepth > height_x && viewSign.x != stepSign.x)) {
|
||||
if (traceDepth > height_y) return vec3(0.0, -viewSign.y, 0.0);
|
||||
|
||||
if (abs(viewDir.y) > abs(viewDir.x))
|
||||
return vec3(0.0, -viewSign.y, 0.0);
|
||||
else
|
||||
return vec3(-viewSign.x, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return vec3(-viewSign.x, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
void AddBackgroundReflection(inout vec4 reflection, vec3 color, vec3 playerPos, vec3 normalM, vec3 normalMR, vec3 viewPos, vec3 nViewPos, vec3 nViewPosR,
|
||||
vec3 shadowMult, float RVdotU, float RVdotS, float z0, float dither, float skyLightFactor, float smoothness, float highlightMult) {
|
||||
#ifdef OVERWORLD
|
||||
#if defined COMPOSITE || WATER_REFLECT_QUALITY >= 2
|
||||
vec3 skyReflection = GetSky(RVdotU, RVdotS, dither, isEyeInWater == 0, true);
|
||||
#else
|
||||
vec3 skyReflection = GetLowQualitySky(RVdotU, RVdotS, dither, isEyeInWater == 0, true);
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
skyReflection *= atmColorMult;
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_ATMOSPHERE
|
||||
skyReflection *= moonPhaseInfluence;
|
||||
#endif
|
||||
|
||||
#ifdef COMPOSITE
|
||||
skyReflection *= skyLightFactor;
|
||||
#else
|
||||
float specularHighlight = GGX(normalM, nViewPos, lightVec, max(dot(normalM, lightVec), 0.0), smoothness);
|
||||
skyReflection += specularHighlight * highlightColor * shadowMult * highlightMult * invRainFactor;
|
||||
|
||||
#if WATER_REFLECT_QUALITY >= 1
|
||||
#ifdef SKY_EFFECT_REFLECTION
|
||||
float cloudLinearDepth = 1.0;
|
||||
float skyFade = 1.0;
|
||||
vec3 auroraBorealis = vec3(0.0);
|
||||
vec3 nightNebula = vec3(0.0);
|
||||
|
||||
#if AURORA_STYLE > 0
|
||||
auroraBorealis = GetAuroraBorealis(nViewPosR, RVdotU, dither);
|
||||
skyReflection += auroraBorealis;
|
||||
#endif
|
||||
#if NIGHT_NEBULAE == 1
|
||||
nightNebula += GetNightNebula(nViewPosR, RVdotU, RVdotS);
|
||||
skyReflection += nightNebula;
|
||||
#endif
|
||||
|
||||
vec2 starCoord = GetStarCoord(nViewPos, 0.5);
|
||||
#ifdef PIXELATED_WATER_REFLECTIONS
|
||||
vec3 absPlayerPos = abs(playerPos);
|
||||
float sizeDecider = -clamp01(pow2(min1(length(absPlayerPos) / 10))) + 1.0; // The effect will only be around the player
|
||||
float starSize = mix(1.0, 2.0, step(0.2, sizeDecider));
|
||||
#else
|
||||
float starSize = 1.0;
|
||||
#endif
|
||||
#if STAR_BRIGHTNESS != 3
|
||||
vec3 starColor = GetStars(starCoord, RVdotU, RVdotS, 1.0 * starSize, 0.0);
|
||||
|
||||
#define ADD_STAR_LAYER_OW1 (STAR_LAYER_OW == 1 || STAR_LAYER_OW == 3)
|
||||
#define ADD_STAR_LAYER_OW2 (STAR_LAYER_OW == 2 || STAR_LAYER_OW == 3)
|
||||
|
||||
#if ADD_STAR_LAYER_OW1
|
||||
starColor = max(starColor, GetStars(starCoord, RVdotU, RVdotS, 0.66 * starSize, 0.0));
|
||||
#endif
|
||||
|
||||
#if ADD_STAR_LAYER_OW2
|
||||
starColor = max(starColor, GetStars(starCoord, RVdotU, RVdotS, 2.2 * starSize, 0.45));
|
||||
#endif
|
||||
|
||||
skyReflection += starColor;
|
||||
#endif
|
||||
|
||||
#ifdef VL_CLOUDS_ACTIVE
|
||||
vec3 worldNormalMR = normalize(mat3(gbufferModelViewInverse) * normalMR);
|
||||
vec3 cameraPosOffset = 2.0 * worldNormalMR * dot(playerPos, worldNormalMR);
|
||||
vec3 RPlayerPos = normalize(mat3(gbufferModelViewInverse) * nViewPosR);
|
||||
float RlViewPos = 100000.0;
|
||||
|
||||
vec4 clouds = GetClouds(cloudLinearDepth, skyFade, cameraPosOffset, RPlayerPos,
|
||||
viewPos, RlViewPos, RVdotS, RVdotU, dither, auroraBorealis, nightNebula, sunVec);
|
||||
|
||||
skyReflection = mix(skyReflection, clouds.rgb, clouds.a);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
skyReflection = mix(color * 0.5, skyReflection, skyLightFactor);
|
||||
#else
|
||||
skyReflection = mix(color, skyReflection, skyLightFactor * 0.5);
|
||||
#endif
|
||||
#endif
|
||||
#elif defined END
|
||||
#ifdef COMPOSITE
|
||||
#ifdef END_BEAMS
|
||||
vec3 skyReflection = (endSkyColor + 0.4 * DrawEnderBeams(RVdotU, playerPos, nViewPosR)) * skyLightFactor;
|
||||
#else
|
||||
vec3 skyReflection = endSkyColor * skyLightFactor;
|
||||
#endif
|
||||
#else
|
||||
vec3 skyReflection = endSkyColor * shadowMult;
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
skyReflection *= atmColorMult;
|
||||
#endif
|
||||
#else
|
||||
vec3 skyReflection = vec3(0.0);
|
||||
#endif
|
||||
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL > 0 && defined COMPOSITE && (BLOCK_REFLECT_QUALITY >= 2 || WATER_REFLECT_QUALITY >= 2)
|
||||
vec4 wsrReflection = getWSR(playerPos, normalMR, nViewPosR, RVdotU, RVdotS, z0, dither);
|
||||
reflection = mix(wsrReflection, vec4(reflection.rgb, 1.0), reflection.a);
|
||||
refDist = min(refDist, length(wsrHitPos - playerPos));
|
||||
#endif
|
||||
|
||||
reflection.rgb = mix(skyReflection, reflection.rgb, reflection.a);
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
vec4 sampleBlurFilteredReflection(vec4 centerCol, float dither, float z0) {
|
||||
vec4 texture4 = texture2D(colortex4, texCoord);
|
||||
vec3 texture6 = texelFetch(colortex6, texelCoord, 0).rgb;
|
||||
float smoothnessD = texture6.r;
|
||||
//float linearZ0 = GetLinearDepth(z0);
|
||||
|
||||
const float spatialFactor = 2.5; // higher = smoother in space
|
||||
const float spatialFactorM = 2.0 * spatialFactor * spatialFactor;
|
||||
|
||||
vec4 sum = vec4(0.0);
|
||||
float wsum = 0.0;
|
||||
vec2 texelSize = (3.0 + 6.0 * dither) / view; // 1 pixel range doesn't seem to be enough to smooth things out
|
||||
texelSize *= 1.0 - 0.75 * pow2(pow2(pow2(smoothnessD)));
|
||||
|
||||
int k = 2;
|
||||
for (int dy = -k; dy <= k; dy++) {
|
||||
for (int dx = -k; dx <= k; dx++) {
|
||||
vec2 offset = vec2(float(dx), float(dy)) * texelSize;
|
||||
vec2 sampleCoord = texCoord + offset;
|
||||
vec4 sampleCol = texture2D(colortex7, sampleCoord);
|
||||
|
||||
// Skip step if normals are too different
|
||||
vec4 texture1Sample = texture2D(colortex1, sampleCoord);
|
||||
if (length(texture4.rgb - texture1Sample.rgb) > 0.1) continue;
|
||||
|
||||
// Skip if depth is too different (costs performance for a tiny fix)
|
||||
#ifdef REFLECTION_BLUR_DEPTH_CHECK
|
||||
if (abs(GetLinearDepth(texture2D(depthtex0, sampleCoord).r) - linearZ0) * far > 2.0) continue;
|
||||
#endif
|
||||
|
||||
// Spatial weight (gaussian)
|
||||
float spatialDist2 = float(dx*dx + dy*dy);
|
||||
float w_s = exp(-spatialDist2 / spatialFactorM);
|
||||
|
||||
float w = w_s;
|
||||
|
||||
sum += sampleCol * w;
|
||||
wsum += w_s;
|
||||
}
|
||||
}
|
||||
|
||||
return sum / wsum;
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
#include "/lib/misc/reprojection.glsl"
|
||||
|
||||
#ifdef OVERWORLD
|
||||
#include "/lib/atmospherics/sky.glsl"
|
||||
#include "/lib/shaderSettings/stars.glsl"
|
||||
#ifdef END_PORTAL_BEAM_INTERNAL
|
||||
#include "/lib/atmospherics/endPortalBeam.glsl"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef END
|
||||
#include "/lib/shaderSettings/endBeams.glsl"
|
||||
#ifdef COMPOSITE
|
||||
#include "/lib/atmospherics/enderBeams.glsl"
|
||||
#endif
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL > 0 || DRAGON_DEATH_EFFECT_INTERNAL > 0
|
||||
#include "/lib/atmospherics/endCrystalVortex.glsl"
|
||||
#endif
|
||||
#include "/lib/atmospherics/fog/endCenterFog.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
#include "/lib/colors/colorMultipliers.glsl"
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_ATMOSPHERE
|
||||
#include "/lib/colors/moonPhaseInfluence.glsl"
|
||||
#endif
|
||||
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL > 0 && defined COMPOSITE
|
||||
#include "/lib/voxelization/lightVoxelization.glsl"
|
||||
#include "/lib/materials/materialMethods/worldSpaceRef.glsl"
|
||||
#endif
|
||||
|
||||
float GetApproxDistance(float depth) {
|
||||
return near * far / (far - depth * far);
|
||||
}
|
||||
|
||||
vec3 nvec3(vec4 pos) {
|
||||
return pos.xyz/pos.w;
|
||||
}
|
||||
|
||||
float refDist = far;
|
||||
|
||||
#include "/lib/materials/materialMethods/reflectionBackground.glsl"
|
||||
|
||||
vec4 GetReflection(vec3 normalM, vec3 viewPos, vec3 nViewPos, vec3 playerPos, float lViewPos, float z0,
|
||||
sampler2D depthtex, float dither, float skyLightFactor, float fresnel,
|
||||
float smoothness, vec3 geoNormal, vec3 color, vec3 shadowMult, float highlightMult, float enderDragonDead, vec2 texelOffset) {
|
||||
// ============================== Step 1: Prepare ============================== //
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL == -1
|
||||
vec2 rEdge = vec2(0.6, 0.55);
|
||||
#else
|
||||
vec2 rEdge = vec2(0.525, 0.525);
|
||||
#endif
|
||||
vec3 normalMR = normalM;
|
||||
#if defined PIXELATED_WATER_REFLECTIONS && defined GBUFFERS_WATER
|
||||
playerPos = TexelSnap(playerPos, texelOffset);
|
||||
viewPos = TexelSnap(viewPos, texelOffset);
|
||||
nViewPos = TexelSnap(nViewPos, texelOffset);
|
||||
lViewPos = TexelSnap(lViewPos, texelOffset);
|
||||
fresnel = TexelSnap(fresnel, texelOffset);
|
||||
#endif
|
||||
|
||||
#if defined GBUFFERS_WATER && WATER_STYLE == 1 && defined GENERATED_NORMALS
|
||||
normalMR = normalize(mix(geoNormal, normalM, 0.05));
|
||||
#endif
|
||||
|
||||
vec3 nViewPosR = normalize(reflect(nViewPos, normalMR));
|
||||
float RVdotU = dot(nViewPosR, upVec);
|
||||
float RVdotS = dot(nViewPosR, sunVec);
|
||||
vec3 worldRefDir = 0.5 * far * (mat3(gbufferModelViewInverse) * nViewPosR);
|
||||
|
||||
#if defined GBUFFERS_WATER && WATER_STYLE >= 2
|
||||
normalMR = normalize(mix(geoNormal, normalM, 0.8));
|
||||
#endif
|
||||
// ============================== End of Step 1 ============================== //
|
||||
|
||||
// ============================== Step 2: Calculate Terrain Reflection and Alpha ============================== //
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL > 0 && defined COMPOSITE && WATER_REFLECT_QUALITY >= 1
|
||||
// In COMPOSITE for translucents we just need to return WSR and that's it
|
||||
if (z0 != z1) {
|
||||
/*vec4 reflection;
|
||||
AddBackgroundReflection(reflection, color, playerPos, normalM, normalMR, viewPos, nViewPos, nViewPosR,
|
||||
shadowMult, RVdotU, RVdotS, z0, dither, skyLightFactor, smoothness, highlightMult);
|
||||
|
||||
return reflection;*/
|
||||
vec4 reflection = getWSR(playerPos, normalMR, nViewPosR, RVdotU, RVdotS, z0, dither);
|
||||
refDist = length(playerPos - wsrHitPos);
|
||||
return reflection;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 reflection = vec4(0.0);
|
||||
vec3 refPos = vec3(0.0);
|
||||
vec3 reflectionColor = vec3(0.0);
|
||||
#if (defined COMPOSITE || WATER_REFLECT_QUALITY >= 1) && (WORLD_SPACE_REFLECTIONS_INTERNAL == -1 || WORLD_SPACE_REF_MODE == 2)
|
||||
#if defined COMPOSITE || WATER_REFLECT_QUALITY >= 2 && !defined DH_WATER
|
||||
// Method 1: Ray Marched Reflection //
|
||||
|
||||
// Ray Marching
|
||||
vec3 start = viewPos + normalMR * (lViewPos * 0.025 * (1.0 - fresnel) + 0.05);
|
||||
#if defined GBUFFERS_WATER && WATER_STYLE >= 2
|
||||
vec3 vector = normalize(reflect(nViewPos, normalMR)); // Not using nViewPosR because normalMR changed
|
||||
#else
|
||||
vec3 vector = nViewPosR;
|
||||
#endif
|
||||
//vector = normalize(vector - 0.5 * (1.0 - smoothness) * (1.0 - fresnel) * normalMR); // reflection anisotropy test
|
||||
//vector = normalize(vector - 0.075 * dither * (1.0 - pow2(pow2(fresnel))) * normalMR);
|
||||
vector *= 0.5;
|
||||
vec3 vectorBase = vector;
|
||||
vec3 viewPosRT = viewPos + vector;
|
||||
vec3 tvector = vector;
|
||||
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL == -1
|
||||
int sampleCount = 30;
|
||||
int refinementCount = 6;
|
||||
#else
|
||||
int sampleCount = 38;
|
||||
int refinementCount = 10;
|
||||
#endif
|
||||
|
||||
int sr = 0;
|
||||
float dist = 0.0;
|
||||
vec3 rfragpos = vec3(0.0);
|
||||
float err = 9999999.0;
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
refPos = nvec3(gbufferProjection * vec4(viewPosRT, 1.0)) * 0.5 + 0.5;
|
||||
if (abs(refPos.x - 0.5) > rEdge.x || abs(refPos.y - 0.5) > rEdge.y) break;
|
||||
|
||||
rfragpos = vec3(refPos.xy, texture2D(depthtex, refPos.xy).r);
|
||||
rfragpos = nvec3(gbufferProjectionInverse * vec4(rfragpos * 2.0 - 1.0, 1.0));
|
||||
dist = length(start - rfragpos);
|
||||
|
||||
err = length(viewPosRT - rfragpos);
|
||||
if (err * 0.33333 < length(vector)) {
|
||||
sr++;
|
||||
if (sr >= refinementCount) break;
|
||||
tvector -= vector;
|
||||
vector *= 0.1;
|
||||
}
|
||||
vector *= 2.0;
|
||||
tvector += vector * (0.95 + 0.1 * dither);
|
||||
viewPosRT = start + tvector;
|
||||
}
|
||||
|
||||
float lViewPosRT = length(rfragpos);
|
||||
|
||||
// Finalizing Terrain Reflection and Alpha
|
||||
if (
|
||||
refPos.z < 0.99997
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL > 0 && COLORED_LIGHTING_INTERNAL >= 256
|
||||
&& (err < 2.0 + pow2(lViewPosRT) * 0.001 || lViewPosRT > 0.25 * COLORED_LIGHTING_INTERNAL)
|
||||
#endif
|
||||
) {
|
||||
vec2 absPos = abs(refPos.xy - 0.5);
|
||||
vec2 cdist = absPos / rEdge;
|
||||
float border = clamp(1.0 - pow(max(cdist.x, cdist.y), 50.0), 0.0, 1.0);
|
||||
reflection.a = border;
|
||||
|
||||
if (reflection.a > 0.001) {
|
||||
vec2 edgeFactor = pow2(pow2(pow2(cdist)));
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL == -1
|
||||
refPos.y += (dither - 0.5) * (0.05 * (edgeFactor.x + edgeFactor.y));
|
||||
#endif
|
||||
|
||||
#ifdef GBUFFERS_WATER
|
||||
reflection = texture2D(gaux2, refPos.xy);
|
||||
reflection.rgb = pow2(reflection.rgb * 2.0);
|
||||
#else
|
||||
float smoothnessDM = pow2(smoothness);
|
||||
float lodFactor = 1.0 - exp(-0.125 * (1.0 - smoothnessDM) * dist);
|
||||
float lod = log2(viewHeight / 8.0 * (1.0 - smoothnessDM) * lodFactor) * 0.45;
|
||||
if (z0 <= 0.56) lod *= 2.22; // Using more lod to compensate for less roughness noise on held items
|
||||
lod = max(lod - 1.0, 0.0);
|
||||
|
||||
reflection.rgb = texture2DLod(colortex0, refPos.xy, lod).rgb;
|
||||
reflectionColor = reflection.rgb;
|
||||
|
||||
#endif
|
||||
|
||||
float skyFade = 0.0;
|
||||
|
||||
#ifdef GBUFFERS_WATER
|
||||
float reflectionPrevAlpha = reflection.a;
|
||||
DoFog(reflection, skyFade, lViewPosRT, ViewToPlayer(rfragpos.xyz), RVdotU, RVdotS, dither, true, lViewPos);
|
||||
reflection.a = reflectionPrevAlpha;
|
||||
//reflection.a *= 1.0 - skyFade;
|
||||
#endif
|
||||
|
||||
edgeFactor.x = pow2(edgeFactor.x);
|
||||
edgeFactor = 1.0 - edgeFactor;
|
||||
float refFactor = pow(edgeFactor.x * edgeFactor.y, 2.0 + 3.0 * GetLuminance(reflection.rgb));
|
||||
#if WORLD_SPACE_REFLECTIONS_INTERNAL > 0 && defined GBUFFERS_WATER
|
||||
refFactor = min(refFactor, 0.1) * 10.0;
|
||||
#endif
|
||||
reflection.a *= refFactor;
|
||||
refDist = dist;
|
||||
}
|
||||
|
||||
float posDif = lViewPosRT - lViewPos;
|
||||
reflection.a *= clamp(posDif + 3.0, 0.0, 1.0);
|
||||
}
|
||||
#if !defined COMPOSITE && defined DISTANT_HORIZONS
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
#if !defined COMPOSITE && (WATER_REFLECT_QUALITY < 2 || defined DISTANT_HORIZONS) || defined DH_WATER
|
||||
{ // Method 2: Mirorred Image Reflection //
|
||||
|
||||
#if WATER_REFLECT_QUALITY < 2 && !defined DISTANT_HORIZONS
|
||||
float verticalStretch = 0.013; // for potato quality reflections
|
||||
#else
|
||||
float verticalStretch = 0.0025; // for distant horizons reflections
|
||||
#endif
|
||||
|
||||
vec4 clipPosR = gbufferProjection * vec4(nViewPosR + verticalStretch * viewPos, 1.0);
|
||||
vec3 screenPosR = clipPosR.xyz / clipPosR.w * 0.5 + 0.5;
|
||||
vec2 screenPosRM = abs(screenPosR.xy - 0.5);
|
||||
|
||||
if (screenPosRM.x < rEdge.x && screenPosRM.y < rEdge.y) {
|
||||
vec2 edgeFactor = pow2(pow2(pow2(screenPosRM / rEdge)));
|
||||
screenPosR.y += (dither - 0.5) * (0.03 * (edgeFactor.x + edgeFactor.y) + 0.004);
|
||||
float z1R = texture2D(depthtex1, screenPosR.xy).x;
|
||||
screenPosR.z = z1R;
|
||||
vec3 viewPosR = ScreenToView(screenPosR);
|
||||
float lViewPosR = length(viewPosR);
|
||||
|
||||
#ifdef DISTANT_HORIZONS
|
||||
float z1RDH = texture2D(dhDepthTex, screenPosR.xy).x;
|
||||
vec4 screenPos1DH = vec4(screenPosR.xy, z1RDH, 1.0);
|
||||
vec4 viewPos1DH = dhProjectionInverse * (screenPos1DH * 2.0 - 1.0);
|
||||
viewPos1DH /= viewPos1DH.w;
|
||||
lViewPosR = min(lViewPosR, length(viewPos1DH.xyz));
|
||||
|
||||
z1R = min(z1R, z1RDH);
|
||||
#endif
|
||||
|
||||
if (z1R < 0.9997 && lViewPos <= 2.0 + lViewPosR) {
|
||||
reflection.rgb = texture2D(gaux2, screenPosR.xy).rgb;
|
||||
reflection.rgb = pow2(reflection.rgb * 2.0);
|
||||
|
||||
edgeFactor = 1.0 - edgeFactor;
|
||||
reflection.a = edgeFactor.x * pow2(edgeFactor.y);
|
||||
reflection.a *= clamp01((dot(nViewPos, nViewPosR) - 0.45) * 10.0); // Fixes perpendicular ref bug
|
||||
|
||||
#ifdef BORDER_FOG
|
||||
float fog = lViewPosR / renderDistance;
|
||||
fog = pow2(pow2(fog));
|
||||
#ifndef DISTANT_HORIZONS
|
||||
fog = pow2(pow2(fog));
|
||||
#endif
|
||||
reflection.a *= exp(-3.0 * fog);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ============================== End of Step 2 ============================== //
|
||||
|
||||
// ============================== Step 3: Add Sky or WSR Reflection ============================== //
|
||||
#if defined COMPOSITE || WATER_REFLECT_QUALITY >= 1
|
||||
if (reflection.a < 1.0)
|
||||
#endif
|
||||
{
|
||||
AddBackgroundReflection(reflection, color, playerPos, normalM, normalMR, viewPos, nViewPos, nViewPosR,
|
||||
shadowMult, RVdotU, RVdotS, z0, dither, skyLightFactor, smoothness, highlightMult);
|
||||
}
|
||||
// ============================== End of Step 3 ============================== //
|
||||
|
||||
#if (defined COMPOSITE || (WATER_REFLECT_QUALITY >= 2 && defined SKY_EFFECT_REFLECTION)) && (END_CRYSTAL_VORTEX_INTERNAL > 0 || DRAGON_DEATH_EFFECT_INTERNAL > 0)
|
||||
reflection.rgb += EndCrystalVortices(playerPos, worldRefDir, dither).rgb;
|
||||
#endif
|
||||
#if (defined COMPOSITE || (WATER_REFLECT_QUALITY >= 2 && defined SKY_EFFECT_REFLECTION)) && defined END_PORTAL_BEAM_INTERNAL && !defined DH_WATER
|
||||
vec4 refPosPlayer = gbufferModelViewInverse * (gbufferProjectionInverse * vec4(refPos * 2.0 - 1.0, 1.0));
|
||||
refPosPlayer /= refPosPlayer.w;
|
||||
reflection.rgb += sqrt(GetEndPortalBeam(playerPos, refPosPlayer.xyz * reflection.a - playerPos).rgb);
|
||||
#endif
|
||||
|
||||
#if (defined COMPOSITE || WATER_REFLECT_QUALITY >= 2) && (WORLD_SPACE_REFLECTIONS_INTERNAL == -1 || WORLD_SPACE_REF_MODE == 2) && defined END && END_CENTER_LIGHTING > 0 && MC_VERSION >= 10900 && !defined DH_WATER
|
||||
if (reflection.a < 1.0) {
|
||||
float attentuation = doEndCenterFog(playerPos + cameraPositionBest, worldRefDir.xyz, length(viewPosRT - start), 0.07);
|
||||
vec3 pointLightFog = vec3(END_CENTER_LIGHTING_R, END_CENTER_LIGHTING_G + 0.05, END_CENTER_LIGHTING_B) * 0.355 * END_CENTER_LIGHTING * attentuation * enderDragonDead;
|
||||
reflection.rgb += sqrt(clamp01(pointLightFog - reflectionColor));
|
||||
}
|
||||
#endif
|
||||
|
||||
return reflection;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
float GetApproxDistance(float depth) {
|
||||
return near * far / (far - depth * far);
|
||||
}
|
||||
|
||||
vec2 DoRefraction(inout vec3 color, inout float z0, inout float z1, vec3 viewPos, float lViewPos) {
|
||||
// Prep
|
||||
if (int(texelFetch(colortex6, texelCoord, 0).g * 255.1) != 241) return texCoord.xy;
|
||||
|
||||
float fovScale = gbufferProjection[1][1];
|
||||
|
||||
vec3 playerPos = ViewToPlayer(viewPos.xyz);
|
||||
vec3 worldPos = playerPos.xyz + cameraPosition.xyz;
|
||||
vec2 worldPosRM = worldPos.xz * 0.02 + worldPos.y * 0.01 + 0.01 * frameTimeCounter;
|
||||
|
||||
vec2 refractNoise = texture2DLod(noisetex, worldPosRM, 0.0).rb - vec2(0.5);
|
||||
refractNoise *= WATER_REFRACTION_INTENSITY * fovScale / (3.0 + lViewPos);
|
||||
|
||||
#if WATER_STYLE < 3
|
||||
refractNoise *= 0.015;
|
||||
#else
|
||||
refractNoise *= 0.02;
|
||||
#endif
|
||||
|
||||
// Check
|
||||
float approxDif = GetApproxDistance(z1) - GetApproxDistance(z0);
|
||||
refractNoise *= clamp(approxDif, 0.0, 1.0);
|
||||
|
||||
vec2 refractCoord = texCoord.xy + refractNoise;
|
||||
|
||||
if (int(texture2D(colortex6, refractCoord).g * 255.1) != 241) return texCoord.xy;
|
||||
|
||||
float z0check = texture2D(depthtex0, refractCoord).r;
|
||||
float z1check = texture2D(depthtex1, refractCoord).r;
|
||||
float approxDifCheck = GetApproxDistance(z1check) - GetApproxDistance(z0check);
|
||||
refractNoise *= clamp(approxDifCheck, 0.0, 1.0);
|
||||
|
||||
// Sample
|
||||
refractCoord = texCoord.xy + refractNoise;
|
||||
color = texture2D(colortex0, refractCoord).rgb;
|
||||
z0 = texture2D(depthtex0, refractCoord).r;
|
||||
z1 = texture2D(depthtex1, refractCoord).r;
|
||||
return refractCoord;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
const float packSizeSW = 16.0;
|
||||
|
||||
void DoSnowyWorld(inout vec4 color, inout float smoothnessG, inout float highlightMult, inout float smoothnessD, inout float emission,
|
||||
vec3 playerPos, vec2 lmCoord, float snowFactor, float snowMinNdotU, float NdotU, int subsurfaceMode) {
|
||||
float snowFactorM = snowFactor * 1000.0 * max(NdotU - 0.9, snowMinNdotU) * max0(lmCoord.y - 0.9) * (0.9 - clamp(lmCoord.x, 0.8, 0.9));
|
||||
if (snowFactorM <= 0.0001) return;
|
||||
|
||||
vec3 worldPos = playerPos + cameraPosition;
|
||||
vec2 noiseCoord = floor(packSizeSW * worldPos.xz + 0.001) / packSizeSW;
|
||||
noiseCoord += floor(packSizeSW * worldPos.y + 0.001) / packSizeSW;
|
||||
float noiseTexture = dot(vec2(0.25, 0.75), texture2DLod(noisetex, noiseCoord * 0.45, 0.0).rg);
|
||||
vec3 snowColor = mix(vec3(0.65, 0.8, 0.85), vec3(1.0, 1.0, 1.0), noiseTexture * 0.75 + 0.125);
|
||||
|
||||
color.rgb = mix(color.rgb, snowColor + color.rgb * emission * 0.2, snowFactorM);
|
||||
smoothnessG = mix(smoothnessG, 0.25 + 0.25 * noiseTexture, snowFactorM);
|
||||
highlightMult = mix(highlightMult, 2.0 - subsurfaceMode * 0.666, snowFactorM);
|
||||
smoothnessD = mix(smoothnessD, 0.0, snowFactorM);
|
||||
emission *= 1.0 - snowFactorM * 0.85;
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
float random (in float x) { return fract(sin(x)*1e4);}
|
||||
float random (in vec2 st) {return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);}
|
||||
vec2 random2( vec2 p ) {
|
||||
return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
|
||||
}
|
||||
|
||||
vec4 hash4( vec2 p ) { return fract(sin(vec4( 1.0+dot(p,vec2(37.0,17.0)),
|
||||
2.0+dot(p,vec2(11.0,47.0)),
|
||||
3.0+dot(p,vec2(41.0,29.0)),
|
||||
4.0+dot(p,vec2(23.0,31.0))))*103.0); }
|
||||
|
||||
vec4 textureNoTile( sampler2D samp, in vec2 uv )
|
||||
{
|
||||
vec2 iuv = floor( uv );
|
||||
vec2 fuv = fract( uv );
|
||||
|
||||
// #ifdef USEHASH
|
||||
// // generate per-tile transform (needs GL_NEAREST_MIPMAP_LINEARto work right)
|
||||
// vec4 ofa = texture( samp, (iuv + vec2(0.5,0.5))/256.0 );
|
||||
// vec4 ofb = texture( samp, (iuv + vec2(1.5,0.5))/256.0 );
|
||||
// vec4 ofc = texture( samp, (iuv + vec2(0.5,1.5))/256.0 );
|
||||
// vec4 ofd = texture( samp, (iuv + vec2(1.5,1.5))/256.0 );
|
||||
// #else
|
||||
// generate per-tile transform
|
||||
vec4 ofa = hash4( iuv + vec2(0.0,0.0) );
|
||||
vec4 ofb = hash4( iuv + vec2(1.0,0.0) );
|
||||
vec4 ofc = hash4( iuv + vec2(0.0,1.0) );
|
||||
vec4 ofd = hash4( iuv + vec2(1.0,1.0) );
|
||||
//#endif
|
||||
|
||||
vec2 ddx = dFdx( uv );
|
||||
vec2 ddy = dFdy( uv );
|
||||
|
||||
// transform per-tile uvs
|
||||
ofa.zw = sign(ofa.zw-0.5);
|
||||
ofb.zw = sign(ofb.zw-0.5);
|
||||
ofc.zw = sign(ofc.zw-0.5);
|
||||
ofd.zw = sign(ofd.zw-0.5);
|
||||
|
||||
// uv's, and derivarives (for correct mipmapping)
|
||||
vec2 uva = uv*ofa.zw + ofa.xy; vec2 ddxa = ddx*ofa.zw; vec2 ddya = ddy*ofa.zw;
|
||||
vec2 uvb = uv*ofb.zw + ofb.xy; vec2 ddxb = ddx*ofb.zw; vec2 ddyb = ddy*ofb.zw;
|
||||
vec2 uvc = uv*ofc.zw + ofc.xy; vec2 ddxc = ddx*ofc.zw; vec2 ddyc = ddy*ofc.zw;
|
||||
vec2 uvd = uv*ofd.zw + ofd.xy; vec2 ddxd = ddx*ofd.zw; vec2 ddyd = ddy*ofd.zw;
|
||||
|
||||
// fetch and blend
|
||||
vec2 b = smoothstep(0.25,0.75,fuv);
|
||||
|
||||
return mix( mix( textureGrad( samp, uva, ddxa, ddya ),
|
||||
textureGrad( samp, uvb, ddxb, ddyb ), b.x ),
|
||||
mix( textureGrad( samp, uvc, ddxc, ddyc ),
|
||||
textureGrad( samp, uvd, ddxd, ddyd ), b.x), b.y );
|
||||
}
|
||||
|
||||
vec3 voronoi( in vec2 x, float rnd ) {
|
||||
vec2 n = floor(x);
|
||||
vec2 f = fract(x);
|
||||
|
||||
// first pass: regular voronoi
|
||||
vec2 mg, mr;
|
||||
float md = 8.0;
|
||||
for (int j=-1; j<=1; j++ ) {
|
||||
for (int i=-1; i<=1; i++ ) {
|
||||
vec2 g = vec2(float(i),float(j));
|
||||
vec2 o = random2( n + g )*rnd;
|
||||
o = 0.5 + 0.5*sin( frameTimeCounter + 6.2831*o );
|
||||
vec2 r = g + o - f;
|
||||
float d = dot(r,r);
|
||||
|
||||
if( d<md ) {
|
||||
md = d;
|
||||
mr = r;
|
||||
mg = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// second pass: distance to borders
|
||||
md = 8.0;
|
||||
for (int j=-2; j<=2; j++ ) {
|
||||
for (int i=-2; i<=2; i++ ) {
|
||||
vec2 g = mg + vec2(float(i),float(j));
|
||||
vec2 o = random2(n + g)*rnd;
|
||||
o = 0.5 + 0.5*sin( frameTimeCounter + 6.2831*o );
|
||||
vec2 r = g + o - f;
|
||||
|
||||
if( dot(mr-r,mr-r)>0.00001 )
|
||||
md = min( md, dot( 0.5*(mr+r), normalize(r-mr) ) );
|
||||
}
|
||||
}
|
||||
return vec3( md, mr );
|
||||
}
|
||||
|
||||
vec3 waterMaskFunc(vec3 worldPos, const float water_scroll_speed, vec3 waterColor, int mat, vec3 normal) {
|
||||
const float foam_speed = 0.05;
|
||||
const float water_warp = 0.005;
|
||||
vec3 water_color = vec3(0);
|
||||
if (mat == 10049) { // Water Cauldron
|
||||
water_color = saturateColors(waterColor, 0.3) * 0.7;
|
||||
} else {
|
||||
water_color = mix(waterColor * 0.4, vec3(0.22, 0.22, 0.22), 0.5);
|
||||
}
|
||||
|
||||
//pixelated coord to created pixelated visual
|
||||
vec3 uv = worldPos;
|
||||
uv = (uv-.5)*.25+.5;
|
||||
float pixelWaterSize = 16;
|
||||
uv = floor(uv * (pixelWaterSize * 4)) / (pixelWaterSize * 4);
|
||||
|
||||
float d = dot(uv.xz-0.5,uv.xz-0.5);
|
||||
vec3 c = voronoi(5.0*uv.xz, pow(d,.6) );
|
||||
|
||||
vec2 water_pos = vec2(frameTimeCounter) * water_scroll_speed;
|
||||
vec3 foamNoise = textureNoTile(noisetex, uv.xz + vec2(frameTimeCounter) * foam_speed).xyz;
|
||||
|
||||
vec3 result = vec3(0.0);
|
||||
// borders
|
||||
vec3 waterMask = mix(vec3(1.00), vec3(0.0), smoothstep( 0.04, 0.06, c.x ));
|
||||
vec3 foam = waterMask * vec3(foamNoise.y - 0.55);
|
||||
foam = clamp(foam, vec3(0.02), vec3(1.0));
|
||||
foam *= 1.3;
|
||||
|
||||
//not regular structure water
|
||||
float water_sample = floor(texture2DLod(noisetex, uv.xz * 0.25 + foamNoise.xz * water_warp + water_pos, 0.0).r * 16) / 16;
|
||||
vec3 water = mix(water_color, vec3(0.001), water_sample * float(foam));
|
||||
|
||||
// small particles in water
|
||||
// Grid
|
||||
vec2 st = uv.xz;
|
||||
st *= vec2(100.0,100.);
|
||||
vec2 ipos = floor(st); // integer
|
||||
vec2 vel = vec2(frameTimeCounter); // time
|
||||
vel *= vec2(-1.,0.); // direction
|
||||
vel *= (step(1.0, mod(ipos.y,5.024))-0.5)*2.; // Oposite directions
|
||||
vel *= vec2(-1.,0.); // direction
|
||||
vel *= random(ipos.y); // random speed
|
||||
|
||||
//Creating particles
|
||||
vec3 pixelParticle = vec3(1.0);
|
||||
pixelParticle *= random(floor(vec2(st.x*0.32, st.y)+vel));
|
||||
float mixFactor = clamp((sin(frameTimeCounter*0.1) + 1.0)*0.5, 0.005, 0.15);
|
||||
pixelParticle = smoothstep(0.0,mixFactor,pixelParticle);
|
||||
pixelParticle = (1.0 - pixelParticle) * (foamNoise.y - 0.55);
|
||||
pixelParticle = clamp(pixelParticle, vec3(0.02), vec3(1.0));
|
||||
|
||||
result = foam * 2.0 + pixelParticle * 2.0 + water;
|
||||
//result = vec3(foamNoise.y - 0.55);
|
||||
return result;
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
#include "/lib/shaderSettings/wavingBlocks.glsl"
|
||||
|
||||
#if COLORED_LIGHTING_INTERNAL > 0
|
||||
#include "/lib/voxelization/lightVoxelization.glsl"
|
||||
#endif
|
||||
|
||||
vec3 GetRawWave(in vec3 pos, float wind) {
|
||||
float magnitude = sin(wind * 0.0027 + pos.x + pos.y) * 0.04 + 0.04;
|
||||
float d0 = sin(wind * 0.0127);
|
||||
float d1 = sin(wind * 0.0089);
|
||||
float d2 = sin(wind * 0.0114);
|
||||
vec3 wave;
|
||||
wave.x = magnitude * sin(wind*0.0224 + d1 + d2 + pos.x - pos.z + pos.y);
|
||||
wave.y = magnitude * sin(wind*0.0015 + d2 + d0 + pos.x);
|
||||
wave.z = magnitude * sin(wind*0.0063 + d0 + d1 - pos.x + pos.z + pos.y);
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
vec3 GetWave(in vec3 pos, float waveSpeed) {
|
||||
float wind = frameTimeCounter * waveSpeed * WAVING_SPEED;
|
||||
vec3 wave = GetRawWave(pos, wind);
|
||||
|
||||
#define WAVING_I_RAIN_MULT_M WAVING_I_RAIN_MULT * 0.01
|
||||
|
||||
#if WAVING_I_RAIN_MULT > 100
|
||||
float windRain = frameTimeCounter * waveSpeed * WAVING_I_RAIN_MULT_M * WAVING_SPEED;
|
||||
vec3 waveRain = GetRawWave(pos, windRain);
|
||||
wave = mix(wave, waveRain, rainFactor);
|
||||
#endif
|
||||
|
||||
float wavingIntensity = WAVING_I * mix(1.0, WAVING_I_RAIN_MULT_M, rainFactor);
|
||||
|
||||
return wave * wavingIntensity;
|
||||
}
|
||||
|
||||
void DoWave_Foliage(inout vec3 playerPos, vec3 worldPos, float waveMult) {
|
||||
worldPos.y *= 0.5;
|
||||
|
||||
vec3 wave = GetWave(worldPos, 170.0);
|
||||
wave.x = wave.x * 3.0;
|
||||
wave.y = 0.0;
|
||||
wave.z = wave.z * 8.0 + wave.y * 4.0;
|
||||
|
||||
#ifdef NO_WAVING_INDOORS
|
||||
#ifndef WAVE_EVERYTHING
|
||||
wave *= clamp(lmCoord.y - 0.87, 0.0, 0.1);
|
||||
#else
|
||||
wave *= 0.1;
|
||||
#endif
|
||||
#else
|
||||
wave *= 0.1;
|
||||
#endif
|
||||
|
||||
playerPos.xyz += wave * waveMult;
|
||||
}
|
||||
|
||||
void DoWave_Leaves(inout vec3 playerPos, vec3 worldPos, float waveMult) {
|
||||
worldPos *= vec3(0.75, 0.375, 0.75);
|
||||
|
||||
vec3 wave = GetWave(worldPos, 170.0);
|
||||
wave *= vec3(4.0, 3.0, 8.0);
|
||||
|
||||
wave *= 1.0 - inSnowy; // Leaves with snow on top look wrong
|
||||
|
||||
#if defined NO_WAVING_INDOORS && !defined WAVE_EVERYTHING
|
||||
wave *= clamp(lmCoord.y - 0.87, 0.0, 0.1);
|
||||
#else
|
||||
wave *= 0.1;
|
||||
#endif
|
||||
|
||||
playerPos.xyz += wave * waveMult;
|
||||
}
|
||||
|
||||
void DoWave_Water(inout vec3 playerPos, vec3 worldPos) {
|
||||
float waterWaveTime = frameTimeCounter * 6.0 * WAVING_SPEED;
|
||||
worldPos.xz *= 14.0;
|
||||
|
||||
float wave = sin(waterWaveTime * 0.7 - worldPos.z * 0.14 + worldPos.x * 0.07);
|
||||
wave += sin(waterWaveTime * 0.5 - worldPos.z * 0.10 + worldPos.x * 0.05);
|
||||
|
||||
#if defined NO_WAVING_INDOORS && !defined WAVE_EVERYTHING
|
||||
wave *= clamp(lmCoord.y - 0.87, 0.0, 0.1);
|
||||
#else
|
||||
wave *= 0.1;
|
||||
#endif
|
||||
|
||||
playerPos.y += wave * 0.125 - 0.05;
|
||||
|
||||
#if defined GBUFFERS_WATER && WATER_STYLE == 1
|
||||
normal = mix(normal, tangent, wave * 0.01);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DoWave_Lava(inout vec3 playerPos, vec3 worldPos) {
|
||||
if (fract(worldPos.y + 0.005) > 0.06) {
|
||||
float lavaWaveTime = frameTimeCounter * 3.0 * WAVING_SPEED;
|
||||
worldPos.xz *= 14.0;
|
||||
|
||||
float wave = sin(lavaWaveTime * 0.7 - worldPos.z * 0.14 + worldPos.x * 0.07);
|
||||
wave += sin(lavaWaveTime * 0.5 - worldPos.z * 0.05 + worldPos.x * 0.10);
|
||||
|
||||
#if defined NETHER && defined WAVIER_LAVA
|
||||
if (worldPos.y > 30 && worldPos.y < 32) wave *= 4.5;
|
||||
else wave *= 2.0;
|
||||
#endif
|
||||
|
||||
playerPos.y += wave * 0.0125;
|
||||
}
|
||||
}
|
||||
|
||||
void DoWave(inout vec3 playerPos, int mat) {
|
||||
vec3 worldPos = playerPos.xyz + cameraPosition.xyz;
|
||||
|
||||
#if defined GBUFFERS_TERRAIN || defined SHADOW
|
||||
#ifdef WAVING_FOLIAGE
|
||||
if (mat == 10003 || mat == 10005 || mat == 10029 || mat == 10025 // Grounded Foliage
|
||||
#ifdef DO_MORE_FOLIAGE_WAVING
|
||||
|| mat == 10769 // Torchflower
|
||||
|| mat == 10976 // Open Eye Blossom
|
||||
#endif
|
||||
) {
|
||||
if (gl_MultiTexCoord0.t < mc_midTexCoord.t || fract(worldPos.y + 0.21) > 0.26)
|
||||
DoWave_Foliage(playerPos.xyz, worldPos, 1.0);
|
||||
}
|
||||
|
||||
else if (mat == 10021 || mat == 10023 || mat == 10027) { // Upper Layer Foliage
|
||||
DoWave_Foliage(playerPos.xyz, worldPos, 1.0);
|
||||
}
|
||||
|
||||
#ifdef DO_MORE_FOLIAGE_WAVING
|
||||
else if (mat == 10972) { // Firefly Bush
|
||||
if (gl_MultiTexCoord0.t < mc_midTexCoord.t || fract(worldPos.y + 0.21) > 0.26) {
|
||||
vec3 wave = GetWave(worldPos, 170.0);
|
||||
wave.x = wave.x * 8.0 + wave.y * 4.0;
|
||||
wave.y = 0.0;
|
||||
wave.z = wave.z * 3.0;
|
||||
|
||||
playerPos.xyz += wave * 0.1 * eyeBrightnessM; // lmCoord.y is unreliable for firefly bushes
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined WAVING_LEAVES_ENABLED || defined WAVING_LAVA || defined WAVING_LILY_PAD
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WAVING_LEAVES_ENABLED
|
||||
if (mat == 10007 || mat == 10009 || mat == 10011) { // Leaves
|
||||
DoWave_Leaves(playerPos.xyz, worldPos, 1.0);
|
||||
} else if (mat == 10013 || mat == 10923) { // Vine
|
||||
// Reduced waving on vines to prevent clipping through blocks
|
||||
DoWave_Leaves(playerPos.xyz, worldPos, 0.75);
|
||||
}
|
||||
#if defined NETHER || defined DO_NETHER_VINE_WAVING_OUTSIDE_NETHER
|
||||
else if (mat == 10884 || mat == 10885) { // Weeping Vines, Twisting Vines
|
||||
float waveMult = 1.0;
|
||||
#if COLORED_LIGHTING_INTERNAL > 0
|
||||
vec3 playerPosP = playerPos + vec3(0.0, 0.1, 0.0);
|
||||
vec3 voxelPosP = SceneToVoxel(playerPosP);
|
||||
vec3 playerPosN = playerPos - vec3(0.0, 0.1, 0.0);
|
||||
vec3 voxelPosN = SceneToVoxel(playerPosN);
|
||||
|
||||
if (CheckInsideVoxelVolume(voxelPosP)) {
|
||||
int voxelP = int(GetVoxelVolume(ivec3(voxelPosP)));
|
||||
int voxelN = int(GetVoxelVolume(ivec3(voxelPosN)));
|
||||
if (voxelP != 0 && voxelP != 65 || voxelN != 0 && voxelN != 65) // not air, not weeping vines
|
||||
waveMult = 0.0;
|
||||
}
|
||||
#endif
|
||||
DoWave_Foliage(playerPos.xyz, worldPos, waveMult);
|
||||
}
|
||||
#endif
|
||||
#ifdef WAVING_SUGAR_CANE
|
||||
if (mat == 10039) { // Sugar Cane
|
||||
float waveMult = 0.75;
|
||||
#if COLORED_LIGHTING_INTERNAL > 0
|
||||
vec3 voxelPosP = SceneToVoxel(playerPos - vec3(0.0, 0.1, 0.0));
|
||||
|
||||
if (CheckInsideVoxelVolume(voxelPosP)) {
|
||||
int voxelP = int(texelFetch(voxel_sampler, ivec3(voxelPosP), 0).r);
|
||||
if (voxelP != 0) // not air
|
||||
waveMult = 0.0;
|
||||
}
|
||||
#endif
|
||||
DoWave_Foliage(playerPos.xyz, worldPos, waveMult);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined WAVING_LAVA || defined WAVING_LILY_PAD
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WAVING_LAVA
|
||||
if (mat == 10068 || mat == 10070) { // Lava
|
||||
DoWave_Lava(playerPos.xyz, worldPos);
|
||||
|
||||
#ifdef GBUFFERS_TERRAIN
|
||||
// G8FL735 Fixes Optifine-Iris parity. Optifine has 0.9 gl_Color.rgb on a lot of versions
|
||||
glColorRaw.rgb = min(glColorRaw.rgb, vec3(0.9));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WAVING_LILY_PAD
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WAVING_LILY_PAD
|
||||
if (mat == 10489) { // Lily Pad
|
||||
DoWave_Water(playerPos.xyz, worldPos);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined GBUFFERS_WATER || defined SHADOW || defined GBUFFERS_TERRAIN
|
||||
#ifdef WAVING_WATER_VERTEX
|
||||
#if defined WAVING_ANYTHING_TERRAIN && defined SHADOW
|
||||
else
|
||||
#endif
|
||||
|
||||
if (mat == 32000) { // Water
|
||||
if (fract(worldPos.y + 0.005) > 0.06)
|
||||
DoWave_Water(playerPos.xyz, worldPos);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
void DoInteractiveWave(inout vec3 playerPos, int mat) {
|
||||
float strength = 2.0;
|
||||
if (mat == 10003 || mat == 10023 || mat == 10015) { // Flowers
|
||||
strength = 1.0;
|
||||
}
|
||||
if (length(playerPos) < 2.0) playerPos.xz += playerPos.xz * max(5.0 / max(length(playerPos * vec3(8.0, 2.0, 8.0) - vec3(0.0, 2.0, 0.0)), 2.0) -0.625, 0.0) * clamp(2.0 / length(playerPos) - 1.0, 0.0, 1.0) * strength; // Emin's code from v4 + smooth transition by me
|
||||
}
|
||||
|
||||
void DoWaveEverything(inout vec3 playerPos) {
|
||||
vec3 worldPos = playerPos.xyz + cameraPosition.xyz;
|
||||
DoWave_Leaves(playerPos.xyz, worldPos, 1.0);
|
||||
DoWave_Foliage(playerPos.xyz, worldPos, 1.0);
|
||||
}
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
#extension GL_ARB_shader_image_load_store : enable
|
||||
|
||||
#include "/lib/voxelization/reflectionVoxelization.glsl"
|
||||
#include "/lib/lighting/minimumLighting.glsl"
|
||||
#include "/lib/shaderSettings/mainLighting.glsl"
|
||||
|
||||
#if WORLD_SPACE_PLAYER_REF == 1
|
||||
#include "/lib/materials/materialMethods/playerRayTracer.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
#include "/lib/atmospherics/auroraBorealis.glsl"
|
||||
#endif
|
||||
|
||||
#if defined OVERWORLD || defined END
|
||||
#ifndef GBUFFERS_WATER
|
||||
#include "/lib/lighting/shadowSampling.glsl"
|
||||
#if defined DO_PIXELATION_EFFECTS && defined PIXELATED_SHADOWS
|
||||
#include "/lib/misc/pixelation.glsl"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SHADOW_SMOOTHING == 4 || SHADOW_QUALITY == 0
|
||||
const float offset = 0.00098;
|
||||
#elif SHADOW_SMOOTHING == 3
|
||||
const float offset = 0.00075;
|
||||
#elif SHADOW_SMOOTHING == 2
|
||||
const float offset = 0.0005;
|
||||
#elif SHADOW_SMOOTHING == 1
|
||||
const float offset = 0.0003;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HELD_LIGHTING_MODE >= 1
|
||||
#include "/lib/lighting/heldLighting.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef CLOUD_SHADOWS
|
||||
#include "/lib/lighting/cloudShadows.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef LIGHT_COLOR_MULTS
|
||||
#include "/lib/colors/colorMultipliers.glsl"
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_LIGHT
|
||||
#include "/lib/colors/moonPhaseInfluence.glsl"
|
||||
#endif
|
||||
|
||||
vec2 getLocalTexCoord(vec3 local, vec3 normal) {
|
||||
vec3 absNormal = abs(normal);
|
||||
return 1.0 - local.zy * absNormal.x - local.xz * absNormal.y - local.xy * absNormal.z;
|
||||
}
|
||||
|
||||
float getVoxelSpaceAO(vec3 playerPos, ivec3 normal, vec2 localTexCoord) {
|
||||
ivec3 voxelPos = ivec3(playerToSceneVoxel(playerPos + normal * 0.5));
|
||||
ivec3 absNormal = ivec3(abs(normal));
|
||||
ivec3 right = ivec3(0, 0, 1) * absNormal.x + ivec3(1, 0, 0) * absNormal.y + ivec3(1, 0, 0) * absNormal.z;
|
||||
ivec3 up = ivec3(0, 1, 0) * absNormal.x + ivec3(0, 0, 1) * absNormal.y + ivec3(0, 1, 0) * absNormal.z;
|
||||
|
||||
vec2 centerFactorPos = sqrt1(2.0 * clamp01(0.5 - localTexCoord));
|
||||
vec2 centerFactorNeg = sqrt1(2.0 * clamp01(localTexCoord - 0.5));
|
||||
ivec3 voxel0 = voxelPos + right;
|
||||
ivec3 voxel1 = voxelPos - right;
|
||||
ivec3 voxel2 = voxelPos + up;
|
||||
ivec3 voxel3 = voxelPos - up;
|
||||
|
||||
float occlusion0 = mix(0.0, float(checkVoxelAt(voxel0)), centerFactorPos.x);
|
||||
float occlusion1 = mix(0.0, float(checkVoxelAt(voxel1)), centerFactorNeg.x);
|
||||
float occlusion2 = mix(0.0, float(checkVoxelAt(voxel2)), centerFactorPos.y);
|
||||
float occlusion3 = mix(0.0, float(checkVoxelAt(voxel3)), centerFactorNeg.y);
|
||||
|
||||
return 1.0 - (occlusion0 + occlusion1 + occlusion2 + occlusion3) * 0.25;
|
||||
}
|
||||
|
||||
vec4 getShadedReflection(ivec3 voxelPos, vec3 oldPlayerPos, vec3 playerPos, vec3 rayDir, vec3 normal, float dither) {
|
||||
faceData faceData = getFaceData(voxelPos, normal);
|
||||
if (faceData.textureBounds.z < 1e-6) return vec4(-1.0);
|
||||
|
||||
vec2 localTexCoord = getLocalTexCoord(fract(playerPos + cameraPositionBestFract), normal);
|
||||
|
||||
vec2 textureSizeAtlas = textureSize(textureAtlas, 0);
|
||||
vec2 textureRadVec2 = faceData.textureBounds.z * vec2(1.0, textureSizeAtlas.x / textureSizeAtlas.y);
|
||||
vec2 textureCoord = faceData.textureBounds.xy + 2.0 * textureRadVec2 * localTexCoord;
|
||||
|
||||
float virtualDist = length(playerPos - oldPlayerPos) + length(oldPlayerPos);
|
||||
float textureFactor = length(textureRadVec2 * textureSizeAtlas) * 3.0;
|
||||
float lod = 0.5 * log2(virtualDist * textureFactor / gbufferProjection[0][0] / abs(dot(normal, rayDir)) / viewHeight / REFLECTION_RES);
|
||||
|
||||
vec4 color = texture2DLod(textureAtlas, textureCoord, lod) * vec4(faceData.glColor, 1.0);
|
||||
|
||||
#if MC_VERSION >= 12111 && IRIS_VERSION < 11005
|
||||
// stupid fake lods because custom texture lods broke with Iris in newer mc versions
|
||||
vec2 lodCoordSpan = localTexCoord / pow(2.0, int(1.5 + pow2(max0(lod)) + 0.0 * dither));
|
||||
|
||||
vec2 lodCoord1 = faceData.textureBounds.xy + 2.0 * textureRadVec2 * (0.5 + lodCoordSpan);
|
||||
vec2 lodCoord2 = faceData.textureBounds.xy + 2.0 * textureRadVec2 * (0.25 + lodCoordSpan);
|
||||
vec2 lodCoord3 = faceData.textureBounds.xy + 2.0 * textureRadVec2 * lodCoordSpan;
|
||||
vec4 lodColor1 = texture2DLod(textureAtlas, lodCoord1, lod) * vec4(faceData.glColor, 1.0);
|
||||
vec4 lodColor2 = texture2DLod(textureAtlas, lodCoord2, lod) * vec4(faceData.glColor, 1.0);
|
||||
vec4 lodColor3 = texture2DLod(textureAtlas, lodCoord3, lod) * vec4(faceData.glColor, 1.0);
|
||||
|
||||
float lodMix = clamp01(lod - 0.75 + 0.25 * dither);
|
||||
color = mix(color, 0.333333 * (lodColor1 + lodColor2 + lodColor3), lodMix);
|
||||
if (dot(color.rgb, vec3(0.333333)) - 0.5 < 0.49) color.a = mix(color.a, 1.0, lodMix);
|
||||
//
|
||||
#endif
|
||||
|
||||
if (color.a < 0.0041) return vec4(-1.0); // Note that the cutout parts of leaves have a color.a of about 0.004
|
||||
|
||||
int mat = int(texelFetch(wsr_sampler, voxelPos, 0).r);
|
||||
|
||||
bool noSmoothLighting = false, noDirectionalShading = false, isFoliage = false;
|
||||
int subsurfaceMode = 0;
|
||||
float emission = 0.0, NdotU = normal.y, NdotE = normal.x, snowMinNdotU = 0.0;
|
||||
vec2 lmCoordM = vec2(1.0);
|
||||
vec3 shadowMult = vec3(1.0), maRecolor = vec3(0.0);
|
||||
float skyLightCheck = 0.0;
|
||||
float overlayNoiseIntensity = 1.0, snowNoiseIntensity = 1.0, sandNoiseIntensity = 1.0, mossNoiseIntensity = 1.0, overlayNoiseTransparentOverwrite = 0.0, overlayNoiseEmission = 1.0, lavaNoiseIntensity = LAVA_NOISE_INTENSITY;
|
||||
vec3 normalM = normal, geoNormal = normal;
|
||||
#ifdef IPBR
|
||||
float lViewPos = length(playerPos);
|
||||
vec4 glColor = vec4(faceData.glColor, 1.0);
|
||||
vec2 absMidCoordPos = vec2(textureRadVec2);
|
||||
vec2 midCoord = faceData.textureBounds.xy + 2.0 * textureRadVec2 * vec2(0.5);
|
||||
vec2 signMidCoordPos = localTexCoord * 2.0 - 1.0;
|
||||
bool noVanillaAO = false, centerShadowBias = false, noGeneratedNormals = false, doTileRandomisation = true;
|
||||
float smoothnessD = 0.0, materialMask = 0.0;
|
||||
float smoothnessG = 0.0, highlightMult = 1.0, noiseFactor = 1.0, snowFactor = 1.0, noPuddles = 0.0;
|
||||
vec2 lmCoord = faceData.lightmap;
|
||||
float IPBRMult = 1.0;
|
||||
|
||||
#define DURING_WORLDSPACE_REF
|
||||
#ifndef IPBR_COMPAT_MODE
|
||||
#define IPBR_COMPAT_MODE
|
||||
#endif
|
||||
#undef DISTANT_LIGHT_BOKEH
|
||||
#include "/lib/materials/materialHandling/terrainIPBR.glsl"
|
||||
#undef DURING_WORLDSPACE_REF
|
||||
#else
|
||||
if (mat == 10007 || mat == 10009 || mat == 10011) { // Leaves
|
||||
#include "/lib/materials/specificMaterials/terrain/leaves.glsl"
|
||||
}
|
||||
#endif
|
||||
|
||||
float NdotL = dot(normal, mat3(gbufferModelViewInverse) * lightVec);
|
||||
#ifdef SIDE_SHADOWING
|
||||
float lightingNdotL = max0(NdotL + 0.4) * 0.714;
|
||||
|
||||
#ifdef END
|
||||
lightingNdotL = sqrt3(lightingNdotL);
|
||||
#endif
|
||||
#else
|
||||
float lightingNdotL = max0(NdotL);
|
||||
#endif
|
||||
|
||||
#ifndef NETHER
|
||||
vec3 shadow = shadowMult;
|
||||
if (lightingNdotL > 0.0001) {
|
||||
float shadowLength = shadowDistance * 0.9166667 - length(playerPos); //consistent08JJ622
|
||||
if (shadowLength > 0.000001) {
|
||||
float distanceBias = 0.12 + 0.0008 * pow(dot(playerPos, playerPos), 0.75);
|
||||
vec3 bias = normal * distanceBias * (2.0 - 0.95 * max0(NdotL));
|
||||
|
||||
#if SHADOW_QUALITY == 0
|
||||
int shadowSamples = 0; // We don't use SampleTAAFilteredShadow on Shadow Quality 0
|
||||
#elif SHADOW_QUALITY == 1
|
||||
int shadowSamples = 1;
|
||||
#else
|
||||
int shadowSamples = 2;
|
||||
#endif
|
||||
shadow = GetShadow(GetShadowPos(playerPos + bias), faceData.lightmap.y, offset, shadowSamples, false);
|
||||
}
|
||||
}
|
||||
shadow *= dot(shadow, vec3(0.33333));
|
||||
#else
|
||||
vec3 shadow = vec3(1.0);
|
||||
#endif
|
||||
|
||||
#ifdef CLOUD_SHADOWS
|
||||
shadow *= GetCloudShadow(playerPos);
|
||||
#endif
|
||||
|
||||
faceData.lightmap = pow2(pow2(faceData.lightmap));
|
||||
float AO = max(0.8, getVoxelSpaceAO(playerPos, ivec3(normal), localTexCoord));
|
||||
float directionalShading = noDirectionalShading ? 1.0 : (NdotU + 1.0) * 0.25 + 0.5;
|
||||
|
||||
vec3 centerPlayerPos = floor(playerPos + cameraPosition + normal * 0.01) - cameraPosition + 0.5;
|
||||
vec3 playerPosM = mix(centerPlayerPos, playerPos, (AO - 0.8) / 0.2);
|
||||
vec3 voxelPosM = SceneToVoxel(playerPosM);
|
||||
voxelPosM = clamp01(voxelPosM / vec3(voxelVolumeSize));
|
||||
vec4 lightVolume = GetLightVolume(voxelPosM);
|
||||
lightVolume = max(lightVolume, vec4(0.000001));
|
||||
vec3 specialLighting = 0.8 * pow(GetLuminance(lightVolume.rgb), 0.25) * DoLuminanceCorrection(pow(lightVolume.rgb, vec3(0.3)));
|
||||
if (noSmoothLighting == true) specialLighting *= 0.6;
|
||||
|
||||
vec3 minLighting = 0.8 * sqrt(GetMinimumLighting(faceData.lightmap.y, playerPos));
|
||||
|
||||
#if HELD_LIGHTING_MODE >= 1
|
||||
vec3 heldLighting = GetHeldLighting(playerPos, color.rgb, emission, geoNormal, normalM, vec3(0));
|
||||
specialLighting = sqrt(pow2(specialLighting) + sqrt(heldLighting));
|
||||
#endif
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
ambientColor = getAuroraAmbientColor(ambientColor, rayDir, 0.035, AURORA_TERRAIN_INFLUENCE_INTENSITY, 0.9);
|
||||
#endif
|
||||
|
||||
#ifdef OVERWORLD
|
||||
float ambientMult = 0.9 * faceData.lightmap.y;
|
||||
float lightMult = (1.1 + 0.25 * subsurfaceMode) * lightingNdotL * shadowTime;
|
||||
lightMult *= 1.0 + abs(NdotE) * 0.25;
|
||||
specialLighting *= 1.0 - faceData.lightmap.y * sunFactor;
|
||||
#else
|
||||
float ambientMult = 1.0;
|
||||
float lightMult = 1.0 * lightingNdotL * shadowTime;
|
||||
#endif
|
||||
|
||||
vec3 sceneLighting = ambientMult * ambientColor + lightMult * lightColor * shadow;
|
||||
#ifdef LIGHT_COLOR_MULTS
|
||||
lightColorMult = GetLightColorMult();
|
||||
sceneLighting *= lightColorMult;
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_LIGHT
|
||||
sceneLighting *= moonPhaseInfluence;
|
||||
#endif
|
||||
|
||||
vec3 lighting = sceneLighting + specialLighting * XLIGHT_I + minLighting;
|
||||
lighting = lighting * AO * directionalShading + emission * 0.8;
|
||||
|
||||
vec3 fadeout = smoothstep(0.0, 32.0, 0.5 * sceneVoxelVolumeSize - abs(playerPos));
|
||||
fadeout = sqrt3(fadeout) * 0.9 + 0.1;
|
||||
float alphaFade = min(fadeout.x, min(fadeout.y, fadeout.z));
|
||||
|
||||
return vec4(color.rgb * lighting + maRecolor, alphaFade);
|
||||
}
|
||||
|
||||
vec3 wsrHitPos = vec3(-100000);
|
||||
|
||||
vec4 traceHighLOD(vec3 rayDir, vec3 stepDir, vec3 stepSizes, vec3 oldPlayerPos, vec3 newPlayerPos, vec3 voxelPos, float RVdotU, float RVdotS, float dither) {
|
||||
vec3 nextDist = (stepDir * 0.5 + 0.5 - fract(voxelPos)) / rayDir;
|
||||
float closestDist = 0.0;
|
||||
|
||||
const float maxSteps = 14;
|
||||
for (int i = 0; i < maxSteps; i++) {
|
||||
closestDist = min(nextDist.x, min(nextDist.y, nextDist.z));
|
||||
vec3 stepAxis = vec3(lessThanEqual(nextDist, vec3(closestDist)));
|
||||
voxelPos += stepAxis * stepDir;
|
||||
nextDist += stepAxis * stepSizes;
|
||||
|
||||
if (!CheckInsideSceneVoxelVolume(voxelPos)) return vec4(0.0);
|
||||
|
||||
if (checkVoxelAt(ivec3(voxelPos))) {
|
||||
vec3 normal = -stepAxis * stepDir;
|
||||
vec3 intersection = newPlayerPos + rayDir * closestDist;
|
||||
vec4 reflection = getShadedReflection(ivec3(voxelPos), oldPlayerPos, intersection, rayDir, normal, dither);
|
||||
if (reflection.a < -0.5) continue;
|
||||
|
||||
wsrHitPos = intersection;
|
||||
|
||||
vec3 fadeout = smoothstep(0.0, 32.0, 0.5 * sceneVoxelVolumeSize - abs(oldPlayerPos));
|
||||
fadeout = sqrt3(fadeout) * 0.9 + 0.1;
|
||||
reflection *= min(fadeout.x, min(fadeout.y, fadeout.z));
|
||||
|
||||
float skyFade = 0.0;
|
||||
float reflectionPrevAlpha = reflection.a;
|
||||
|
||||
DoFog(reflection, skyFade, length(intersection), intersection, RVdotU, RVdotS, dither, true, length(oldPlayerPos));
|
||||
|
||||
reflection.a = reflectionPrevAlpha * (1.0 - skyFade);
|
||||
|
||||
return reflection;
|
||||
}
|
||||
}
|
||||
|
||||
return vec4(-1.0);
|
||||
}
|
||||
|
||||
vec4 traceLowLOD(vec3 rayDir ,vec3 stepDir, vec3 stepSizes, vec3 playerPos, vec3 voxelPos, vec3 normalOffset, float RVdotU, float RVdotS, float dither) {
|
||||
float lodScale = 4.0;
|
||||
vec3 lodVoxelPos = voxelPos / lodScale;
|
||||
|
||||
vec3 nextDist = (stepDir * 0.5 + 0.5 - fract(lodVoxelPos)) / rayDir;
|
||||
float closestDistPrevious = 0.0;
|
||||
float closestDist = 0.0;
|
||||
|
||||
float maxSteps = length(vec3(sceneVoxelVolumeSize)) / lodScale;
|
||||
for (int i = 0; i < maxSteps; i++) {
|
||||
if (any(greaterThan(lodVoxelPos, vec3(sceneVoxelVolumeSize) / lodScale)) || any(lessThan(lodVoxelPos, vec3(0.0))))
|
||||
return vec4(0.0);
|
||||
|
||||
if (checkLodVoxelAt(ivec3(lodVoxelPos))) {
|
||||
vec3 newPlayerPos = playerPos + rayDir * closestDistPrevious * lodScale;
|
||||
|
||||
// Fixes surfaces reflecting themselves at a distance with lower resolutions, but it can cause some rare artifacts
|
||||
if (i <= 2) newPlayerPos += normalOffset * 0.06;
|
||||
|
||||
vec3 newVoxelPos = playerToSceneVoxel(newPlayerPos);
|
||||
vec4 try = traceHighLOD(rayDir, stepDir, stepSizes, playerPos, newPlayerPos, newVoxelPos, RVdotU, RVdotS, dither);
|
||||
if (try.a > -0.5) return try;
|
||||
}
|
||||
|
||||
closestDistPrevious = closestDist;
|
||||
closestDist = min(nextDist.x, min(nextDist.y, nextDist.z));
|
||||
vec3 stepAxis = vec3(lessThanEqual(nextDist, vec3(closestDist)));
|
||||
lodVoxelPos += stepAxis * stepDir;
|
||||
nextDist += stepAxis * stepSizes;
|
||||
}
|
||||
|
||||
return vec4(0.0);
|
||||
}
|
||||
|
||||
vec4 getWSR(vec3 playerPos, vec3 normalMR, vec3 nViewPosR, float RVdotU, float RVdotS, float z0, float dither) {
|
||||
vec3 normalOffset = normalize(mat3(gbufferModelViewInverse) * normalMR);
|
||||
vec3 voxelPos = playerToSceneVoxel(playerPos);
|
||||
|
||||
// Fixes slabs, stairs, dirt paths, and farmlands reflecting themselves
|
||||
if (z0 == z1 && z0 > 0.56) {
|
||||
vec3 playerPosFractAdded = playerPos + cameraPositionBestFract + 256.0;
|
||||
vec3 normalOffsetM = normalOffset * (0.04 - 0.01 * dither);
|
||||
ivec3 voxelPosCheck1 = ivec3(playerPosFractAdded - normalOffsetM);
|
||||
ivec3 voxelPosCheck2 = ivec3(playerPosFractAdded + normalOffsetM);
|
||||
if (voxelPosCheck1 == voxelPosCheck2) playerPos += normalOffset * 0.5;
|
||||
}
|
||||
|
||||
vec3 rayDir = mat3(gbufferModelViewInverse) * nViewPosR;
|
||||
|
||||
if (CheckInsideSceneVoxelVolume(voxelPos)) {
|
||||
vec3 stepDir = sign(rayDir);
|
||||
vec3 stepSizes = 1.0 / abs(rayDir);
|
||||
vec4 wsrResult = traceLowLOD(rayDir, stepDir, stepSizes, playerPos, voxelPos, normalOffset, RVdotU, RVdotS, dither);
|
||||
|
||||
#if WORLD_SPACE_PLAYER_REF == 1
|
||||
if (!is_invisible && z0 > 0.56) {
|
||||
float wsrTraceLength = length(wsrHitPos - playerPos);
|
||||
vec3 albedo;
|
||||
vec3 normal;
|
||||
float emission;
|
||||
|
||||
#ifdef SPACEAGLE17
|
||||
if (isSneaking < 0.5 || !(heldItemId == 45014 || heldItemId2 == 45014))
|
||||
#endif
|
||||
if (rayTracePlayer(playerPos - 0.01 * rayDir, rayDir, wsrTraceLength, albedo, normal, emission)) {
|
||||
vec2 lmCoord = eyeBrightness / 240.0;
|
||||
|
||||
#ifdef OVERWORLD
|
||||
float ambientMult = 1.5 * lmCoord.y;
|
||||
float lightMult = 0.2 * pow2(pow2(lmCoord.y));
|
||||
#else
|
||||
float ambientMult = 1.5;
|
||||
float lightMult = 0.0;
|
||||
#endif
|
||||
|
||||
vec3 voxelPosM = SceneToVoxel(vec3(0.0));
|
||||
voxelPosM = clamp01(voxelPosM / vec3(voxelVolumeSize));
|
||||
vec4 lightVolume = GetLightVolume(voxelPosM);
|
||||
lightVolume = max(lightVolume, vec4(0.000001));
|
||||
vec3 specialLighting = pow(GetLuminance(lightVolume.rgb), 0.25) * DoLuminanceCorrection(pow(lightVolume.rgb, vec3(0.25)));
|
||||
|
||||
#if HELD_LIGHTING_MODE >= 1
|
||||
float tempEmission;
|
||||
vec3 heldLighting = GetHeldLighting(playerPos, vec3(999999.0), tempEmission, vec3(0), vec3(0), vec3(0));
|
||||
specialLighting = sqrt(pow2(specialLighting) + sqrt(heldLighting));
|
||||
#endif
|
||||
|
||||
vec3 minLighting = 0.8 * sqrt(GetMinimumLighting(lmCoord.y, playerPos));
|
||||
|
||||
vec3 sceneLighting = ambientMult * ambientColor + lightMult * lightColor;
|
||||
#ifdef LIGHT_COLOR_MULTS
|
||||
lightColorMult = GetLightColorMult();
|
||||
sceneLighting *= lightColorMult;
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_LIGHT
|
||||
sceneLighting *= moonPhaseInfluence;
|
||||
#endif
|
||||
|
||||
vec3 lighting = sceneLighting + specialLighting * (1.0 - lmCoord.y * sunFactor) * XLIGHT_I + minLighting + emission;
|
||||
|
||||
vec3 fadeout = smoothstep(0.0, 32.0, 0.5 * sceneVoxelVolumeSize - abs(playerPos));
|
||||
fadeout = sqrt3(fadeout) * 0.9 + 0.1;
|
||||
float alphaFade = min(fadeout.x, min(fadeout.y, fadeout.z));
|
||||
|
||||
return vec4(albedo * lighting, alphaFade);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return wsrResult;
|
||||
}
|
||||
|
||||
return vec4(0.0);
|
||||
}
|
||||
Reference in New Issue
Block a user