Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
// Minimal Mandelbulb fractal shader - test version #define MARCH_MAX_STEPS 200 #define MARCH_MAX_DISTANCE 500.0 #define DE_MAX_ITER 25 #define DE_BAILOUT 10.0 #define HIT_STATUS_HIT 1 #define HIT_STATUS_MISS_DISTANCE 2 #define HIT_STATUS_MISS_STEPS 3 struct MarchResult { float distance; int steps; int hitStatus; int totalDEIterations; }; struct FractalFunctions { // Computes the world-space radius that a sphere must have to appear 1 pixel tall on screen at a given distance. static float GetPixelWorldRadius(float distance) { return distance * ResolvedView.ClipToView._22 / ResolvedView.ViewSizeAndInvSize.y; } // Mandelbulb distance estimator static float MandelbulbDE(float3 pos, float power, out int iterations) { float3 z = pos; float dr = 1.0; float r = 0.0; for (iterations = 0; iterations < DE_MAX_ITER; iterations++) { r = length(z); if (r > DE_BAILOUT) break; // Convert to spherical coordinates float theta = acos(z.z / r); float phi = atan2(z.y, z.x); dr = pow(r, power - 1.0) * power * dr + 1.0; // Scale and rotate the point float zr = pow(r, power); theta = theta * power; phi = phi * power; // Convert back to Cartesian coordinates float sinTheta = sin(theta); z = zr * float3(sinTheta * cos(phi), sinTheta * sin(phi), cos(theta)); z += pos; } return 0.5 * log(r) * r / dr; } // Ray marching static MarchResult MarchFractal(float3 rayOrigin, float3 rayDir, float power) { float totalDist = 0.0; int steps = 0; int totalDEIterations = 0; while (totalDist < MARCH_MAX_DISTANCE && steps < MARCH_MAX_STEPS) { steps++; float3 pos = rayOrigin + rayDir * totalDist; int deIterations; float distance = MandelbulbDE(pos, power, deIterations); totalDEIterations += deIterations; float pixelSize = GetPixelWorldRadius(totalDist); if (distance <= pixelSize) { MarchResult result; result.distance = totalDist; result.steps = steps; result.hitStatus = HIT_STATUS_HIT; result.totalDEIterations = totalDEIterations; return result; } float stepSize = max(distance, pixelSize * 0.5); totalDist += stepSize; } MarchResult result; result.distance = totalDist; result.steps = steps; result.hitStatus = (totalDist >= MARCH_MAX_DISTANCE) ? HIT_STATUS_MISS_DISTANCE : HIT_STATUS_MISS_STEPS; result.totalDEIterations = totalDEIterations; return result; } static float3 RenderFractal(float2 screenUV, float3 sceneColor, float power) { // Get camera parameters float3 cameraOrigin = LWCHackToFloat(ResolvedView.WorldCameraOrigin); // Convert screen UV to clip space float2 clipXY = screenUV * 2.0 - 1.0; clipXY.y = -clipXY.y; float4 clipPos = float4(clipXY, 1.0, 1.0); float4 viewPos = mul(clipPos, ResolvedView.ClipToView); viewPos.xyz /= viewPos.w; // Transform view direction to world space float3 worldDir = normalize(mul(viewPos.xyz, (float3x3)ResolvedView.ViewToTranslatedWorld)); // Scale down the camera origin for better framing float3 rayOrigin = cameraOrigin * 0.001; float3 rayDir = worldDir; // Ray march MarchResult finalResult = MarchFractal(rayOrigin, rayDir, power); // Calculate color based on total steps taken float stepFactor = saturate(finalResult.steps / float(MARCH_MAX_STEPS)); float t = sqrt(stepFactor); // Gradient color stops float3 almostBlack = float3(0.0, 0.0, 0.05); float3 deepBlue = float3(0.05, 0.15, 0.3); float3 vibrantBlue = float3(0.2, 0.4, 0.8); float3 brightBlue = float3(0.6, 0.8, 1.0); // Blend through gradient float range1 = saturate(t / 0.15); float range2 = saturate((t - 0.15) / 0.25); float range3 = saturate((t - 0.4) / 0.6); float3 fractalColor = lerp(lerp(lerp(almostBlack, deepBlue, range1), vibrantBlue, range2), brightBlue, range3); // Add green tint based on total DE iterations float iterFactor = saturate(finalResult.totalDEIterations / float(DE_MAX_ITER * finalResult.steps)); if (iterFactor > 0.1) { float greenAmount = (iterFactor - 0.1) / 0.9; greenAmount = pow(greenAmount, 2.0); fractalColor = lerp(fractalColor, float3(0.3, 0.5, 0.6), greenAmount); } if (iterFactor > 0.9) { float greenAmount = (iterFactor - 0.9) / 0.1; greenAmount = pow(greenAmount, 5.0); fractalColor = lerp(fractalColor, float3(0.3, 0.9, 0.7), greenAmount); } if (finalResult.hitStatus == HIT_STATUS_HIT) { return fractalColor; } else if (finalResult.hitStatus == HIT_STATUS_MISS_DISTANCE) { float fogAmount = pow(stepFactor, 0.1); return lerp(sceneColor, fractalColor, fogAmount); } else { return fractalColor; } } }; // Usage in material custom node: // #include "/Project/FractalMaterial.usf" // FractalFunctions FF; // return FF.RenderFractal(ScreenPosition, SceneColor, Power).rgb;
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)