--[[--/* MoreFractalRopes.fuse Based on https://www.shadertoy.com/view/7sscW4 a WebGL shader created by SnoopethDuckDuck. Converted to DCTL and embeddet into a Lua Fuse by JiPi (https://www.youtube.com/c/JiPi_YT). Place this file in your Fusion's and/or DaVinci Resolve's 'Fuses/' folder to use it. */--]]-- -- /* local ShaderFuse = require("Shaderfuse/ShaderFuse") ShaderFuse.init() -- // ------------------------------------------------------------------------ -- // Registry declaration -- // ------------------------------------------------------------------------ FuRegisterClass(ShaderFuse.FuRegister.Name, CT_SourceTool, { ShaderFuse.FuRegister.Attributes, REG_NoObjMatCtrls = true, REG_NoMotionBlurCtrls = true, REG_Source_GlobalCtrls = false, REG_Source_SizeCtrls = true, REG_Source_AspectCtrls = true, REG_Source_DepthCtrls = true, REG_OpNoMask = true, REG_TimeVariant = true, }) -- // ------------------------------------------------------------------------ -- // DCTL kernel parameters -- // ------------------------------------------------------------------------ -- */ ShaderParameters = [[ float iResolution[2]; float iTime; float iMouse[4]; bool Option1; bool MouseRotVar; float Color1[4]; float Color2[4]; float Variants; float ViewDXY[2]; float ViewDZ; float ViewXY[2]; float ViewZ; float ambient; float difPower; float r; int width,height; int compOrder; ]] -- /* -- // ------------------------------------------------------------------------ -- DCTL kernel compatibility code -- // ------------------------------------------------------------------------ -- */ ShaderCompatibilityCode = [[ #if defined(DEVICE_IS_METAL) #define in #define out thread #define inout thread #else #define in #define out #define inout #endif #undef USE_NATIVE_METAL_IMPL #undef USE_NATIVE_CUDA_IMPL #undef USE_NATIVE_OPENCL_IMPL // 0 to use the generic implementations; 1 for Metal, OpenCL, Cuda specific code if existing #if 1 #if defined(DEVICE_IS_METAL) #define USE_NATIVE_METAL_IMPL 1 #elif defined(DEVICE_IS_CUDA) #define USE_NATIVE_CUDA_IMPL 1 #elif defined(DEVICE_IS_OPENCL) #define USE_NATIVE_OPENCL_IMPL 1 #endif #endif #if defined(USE_NATIVE_METAL_IMPL) #define swi2(A,a,b) (A).a##b #define swi3(A,a,b,c) (A).a##b##c #define swi2S(a,b,c,d) a.b##c = d #else #define swi2(A,a,b) to_float2((A).a,(A).b) #define swi3(A,a,b,c) to_float3((A).a,(A).b,(A).c) #define swi2S(a,b,c,d) {float2 tmp = d; (a).b = tmp.x; (a).c = tmp.y;} #endif // ---------------------------------------------------------------------------------------------------------- // mat2 implementation // ---------------------------------------------------------------------------------------------------------- #if defined(USE_NATIVE_METAL_IMPL) typedef float2x2 mat2; #define to_mat2(A,B,C,D) mat2((A),(B),(C),(D)) #define mul_f2_mat2(A,B) ((A)*(B)) #define mul_mat2_f2(A,B) ((A)*(B)) #else typedef struct { float2 r0; float2 r1; } mat2; __DEVICE__ inline mat2 to_mat2 ( float a, float b, float c, float d) { mat2 t; t.r0.x = a; t.r0.y = b; t.r1.x = c; t.r1.y = d; return t; } __DEVICE__ inline float2 mul_f2_mat2( float2 v, mat2 m ) { float2 t; t.x = v.x*m.r0.x + v.y*m.r0.y; t.y = v.x*m.r1.x + v.y*m.r1.y; return t; } __DEVICE__ inline float2 mul_mat2_f2( mat2 m, float2 v ) { float2 t; t.x = v.x*m.r0.x + v.y*m.r1.x; t.y = v.x*m.r0.y + v.y*m.r1.y; return t; } #endif // end of mat2 implementation // ---------------------------------------------------------------------------------------------------------- // mat3 implementation // ---------------------------------------------------------------------------------------------------------- #if defined(USE_NATIVE_METAL_IMPL) typedef float3x3 mat3; __DEVICE__ inline mat3 to_mat3( float a, float b, float c, float d, float e, float f, float g, float h, float i) { return mat3(a,b,c,d,e,f,g,h,i); } __DEVICE__ inline float3 mul_mat3_f3( mat3 B, float3 A) { return (B*A); } __DEVICE__ inline mat3 mul_mat3_mat3( mat3 A, mat3 B) { return (A*B); } #else typedef struct { float3 r0; float3 r1; float3 r2; } mat3; __DEVICE__ inline mat3 to_mat3( float a, float b, float c, float d, float e, float f, float g, float h, float i) { mat3 t; t.r0.x = a; t.r0.y = b; t.r0.z = c; t.r1.x = d; t.r1.y = e; t.r1.z = f; t.r2.x = g; t.r2.y = h; t.r2.z = i; return t; } __DEVICE__ inline float3 mul_mat3_f3( mat3 B, float3 A) { float3 C; C.x = A.x * B.r0.x + A.y * B.r1.x + A.z * B.r2.x; C.y = A.x * B.r0.y + A.y * B.r1.y + A.z * B.r2.y; C.z = A.x * B.r0.z + A.y * B.r1.z + A.z * B.r2.z; return C; } __DEVICE__ mat3 mul_mat3_mat3( mat3 B, mat3 A) { float r[3][3]; float a[3][3] = {{A.r0.x, A.r0.y, A.r0.z}, {A.r1.x, A.r1.y, A.r1.z}, {A.r2.x, A.r2.y, A.r2.z}}; float b[3][3] = {{B.r0.x, B.r0.y, B.r0.z}, {B.r1.x, B.r1.y, B.r1.z}, {B.r2.x, B.r2.y, B.r2.z}}; for( int i = 0; i < 3; ++i) { for( int j = 0; j < 3; ++j) { r[i][j] = 0.0f; for( int k = 0; k < 3; ++k) { r[i][j] = r[i][j] + a[i][k] * b[k][j]; } } } mat3 R = to_mat3(r[0][0], r[0][1], r[0][2], r[1][0], r[1][1], r[1][2], r[2][0], r[2][1], r[2][2]); return R; } #endif // end of mat3 implementation #if defined(USE_NATIVE_METAL_IMPL) #define sin_f2(i) sin(i) #define cos_f2(i) cos(i) #define cos_f3(i) cos(i) #define pow_f3(a,b) pow(a,b) #else #if defined(USE_NATIVE_OPENCL_IMPL) #define reflect(I,N) (I-2.0f*dot(N,I)*N) #define fract(a) ((a)-_floor(a)) // oder Pointer bauen: gentype fract(gentype x, gentype *itpr) #define sin_f2(i) sin(i) #define cos_f2(i) cos(i) #define cos_f3(i) cos(i) #define pow_f3(a,b) pow(a,b) #else // Generic #if defined(DEVICE_IS_OPENCL) __DEVICE__ float3 reflect(float3 I, float3 N) {return I - 2.0f * dot(N, I) * N;} #endif #define fract(a) ((a)-_floor(a)) #define sin_f2(i) to_float2( _sinf((i).x), _sinf((i).y)) #define cos_f2(i) to_float2( _cosf((i).x), _cosf((i).y)) #define cos_f3(i) to_float3( _cosf((i).x), _cosf((i).y), _cosf((i).z)) #define pow_f3(a,b) to_float3(_powf((a).x,(b).x),_powf((a).y,(b).y),_powf((a).z,(b).z)) #endif #endif __DEVICE__ float4 decube_f3(__TEXTURE2D__ t, float3 xyz) { float ax=_fabs(xyz.x); float ay=_fabs(xyz.y); float az=_fabs(xyz.z); if (xyz.x>0.0f && ax>=ay && ax>=az) // +X, Face 0, right return _tex2DVecN(t,(-xyz.z/ax+1.0f)/8.0f + 0.5f,(xyz.y/ax+1.0f)/6.0f + (1.0f/3.0f),15); if (xyz.y>0.0f && ay>=ax && ay>=az) // +Y, Face 2, top return _tex2DVecN(t,(xyz.x/ay+1.0f)/8.0f + 0.25f,(-xyz.z/ay+1.0f)/6.0f + (2.0f/3.0f),15); if (xyz.z>0.0f && az>=ax && az>=ay) // +Z, Face 4, front return _tex2DVecN(t,(xyz.x/az+1.0f)/8.0f + 0.25f,(xyz.y/az+1.0f)/6.0f + (1.0f/3.0f),15); if (xyz.x<0.0f && ax>=ay && ax>=az) // -X, Face 1, left return _tex2DVecN(t,(xyz.z/ax+1.0f)/8.0f,(xyz.y/ax+1.0f)/6.0f + (1.0f/3.0f),15); if (xyz.y<0.0f && ay>=ax && ay>=az) // -Y, Face 3, bottom return _tex2DVecN(t,(xyz.x/ay+1.0f)/8.0f + 0.25f,(xyz.z/ay+1.0f)/6.0f,15); if (xyz.z<0.0f && az>=ax && az>=ay) // -Z, Face 5, back return _tex2DVecN(t,(-xyz.x/az+1.0f)/8.0f + 0.75f,(xyz.y/az+1.0f)/6.0f + (1.0f/3.0f),15); return to_float4(1.0f,0.0f,0.0f,1.0f); // error } ]] -- /* -- // ------------------------------------------------------------------------ -- DCTL kernel implementation -- // ------------------------------------------------------------------------ -- */ ShaderKernelCode = [[ // ---------------------------------------------------------------------------------- // - Common - // ---------------------------------------------------------------------------------- #define tanh_f2(i) to_float2(_tanhf((i).x), _tanhf((i).y)) #define pi 3.1415926535897f __DEVICE__ float thc(float a, float b) { return _tanhf(a * _cosf(b)) / _tanhf(a); } __DEVICE__ float ths(float a, float b) { return _tanhf(a * _sinf(b)) / _tanhf(a); } __DEVICE__ float2 thc_f2(float a, float2 b) { return tanh_f2(a * cos_f2(b)) / _tanhf(a); } __DEVICE__ float2 ths_f2(float a, float2 b) { return tanh_f2(a * sin_f2(b)) / _tanhf(a); } __DEVICE__ float3 pal( in float t, in float3 a, in float3 b, in float3 c, in float3 d ) { return a + b*cos_f3( 6.28318f*(c*t+d) ); } __DEVICE__ float h21 (float2 a) { return fract(_sinf(dot(swi2(a,x,y), to_float2(12.9898f, 78.233f))) * 43758.5453123f); } __DEVICE__ float mlength(float2 uv) { return _fmaxf(_fabs(uv.x), _fabs(uv.y)); } // ---------------------------------------------------------------------------------- // - Image - // ---------------------------------------------------------------------------------- // Connect Image 'Cubemap: Uffizi Gallery Blurred_0' to iChannel0 // "RayMarching starting point" // by Martijn Steinrucken aka The Art of Code/BigWings - 2020 // The MIT License // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // Email: countfrolic@gmail.com // Twitter: @The_ArtOfCode // YouTube: youtube.com/TheArtOfCodeIsCool // Facebook: https://www.facebook.com/groups/theartofcode/ // // You can use this shader as a template for ray marching shaders #define MAX_STEPS 400 #define MAX_DIST 10.0f #define SURF_DIST 0.001f #define S smoothstep #define T iTime __DEVICE__ mat2 Rot(float a) { float s=_sinf(a), c=_cosf(a); return to_mat2(c, -s, s, c); } __DEVICE__ float GetDist(float3 p, float iTime, float Variants) { float2 uv = swi2(p,x,z); uv.x = _fabs(uv.x); float time = 12.0f + iTime; // 0.3f * h21(_floor(10.0f * uv)) //<-very cool extremely laggy if ((int)Variants&2) time += 0.3f * h21(_floor(10.0f * uv)); //<-very cool extremely laggy float2 q = to_float2(1,0); float th = 0.4f * p.y - 0.6f * time; float n = 9.0f; float m = -0.0f * length(uv) + 1.8f; for (float i = 0.0f; i < n; i++) { uv -= m * q; th += 0.5f * p.y + 0.05f * time; uv = mul_mat2_f2(Rot(th) , uv); uv.x = _fabs(uv.x); if ((int)Variants&4 == 0) m *= 0.05f * _cosf(8.0f * length(uv)) + 0.55f;// + ((int)Variants&4) ? 0.05f * _cosf(0.4f * p.y - 0.6f * iTime) : 0.0f; // + 0.05f * _cosf(0.4f * p.y - 0.6f * iTime); else m *= 0.05f * _cosf(8.0f * length(uv)) + 0.55f + 0.05f * _cosf(0.14f * p.y - 0.16f * iTime); // + 0.05f * _cosf(0.4f * p.y - 0.6f * iTime); if ((int)Variants&8) m += m * _cosf(iTime); } float d = length(uv) - 2.0f * m; if ((int)Variants&16) d = length(uv)- 0.5f; return 0.5f * d; // was 0.35 } __DEVICE__ float RayMarch(float3 ro, float3 rd, float iTime, float Variants) { float dO=0.0f; for(int i=0; iMAX_DIST || _fabs(dS)= params->width || fusion_y >= params->height) return; float2 iResolution = to_float2(params->iResolution[0], params->iResolution[1]); float iTime = params->iTime; float4 iMouse = to_float4(params->iMouse[0],params->iMouse[1],params->iMouse[2],params->iMouse[3]); float4 fragColor = to_float4_s(0.0f); float2 fragCoord = to_float2(fusion_x,fusion_y); bool Option1 = params->Option1; bool MouseRotVar = params->MouseRotVar; float4 Color1 = to_float4(params->Color1[0], params->Color1[1], params->Color1[2], params->Color1[3]); float4 Color2 = to_float4(params->Color2[0], params->Color2[1], params->Color2[2], params->Color2[3]); float Variants = params->Variants; float2 ViewDXY = to_float2(params->ViewDXY[0], params->ViewDXY[1]); float ViewDZ = params->ViewDZ; float2 ViewXY = to_float2(params->ViewXY[0], params->ViewXY[1]); float ViewZ = params->ViewZ; float ambient = params->ambient; float difPower = params->difPower; float r = params->r; // -------- Variants *= 2; // for Fusination float2 uv = (fragCoord-0.5f*iResolution)/iResolution.y; float2 m = swi2(iMouse,x,y)/iResolution; //float r = 5.5f; float time = 0.0f * iTime; float3 ro = to_float3(r * _cosf(time), 0.1f * iTime, r * _sinf(time)) + to_float3_aw(ViewXY, ViewZ); if(MouseRotVar == false) { swi2S(ro,y,z, mul_f2_mat2(swi2(ro,y,z) , Rot(-m.y*3.14f+1.0f))); swi2S(ro,x,z, mul_f2_mat2(swi2(ro,x,z) , Rot(-m.x*6.2831f))); } float3 rd = GetRayDir(uv, ro, to_float3(0,0.1f * iTime,0), 2.0f) + to_float3_aw(ViewDXY, ViewDZ); if(MouseRotVar) { //############### 3D Mouse-Rotation des Objektes ############## float crz = (iMouse.x - iResolution.x / 2.0f) / iResolution.x * pi; float crx = (iMouse.y - iResolution.y / 2.0f) / iResolution.y * pi; mat3 m = mul_mat3_mat3(to_mat3(_cosf(crz), 0.0f, _sinf(crz), 0.0f, 1.0f, 0.0f, -_sinf(crz), 0.0f, _cosf(crz)) , to_mat3(1.0f, 0.0f, 0.0f, 0.0f, _cosf(crx), _sinf(crx), 0.0f, -_sinf(crx), _cosf(crx))); if(iMouse.z > 0.0f) { ro = mul_mat3_f3(m , ro); rd = mul_mat3_f3(m , rd); } //############################################################# } float3 col = to_float3_s(0); float d = RayMarch(ro, rd, iTime, Variants); if(d= 1) then if (InSize:GetValue(req).Value == 2) then if (InChannel0:GetValue(req) ~= nil) then Width = InChannel0:GetValue(req).Width Height = InChannel0:GetValue(req).Height end else Width = InWidth:GetValue(req).Value Height = InHeight:GetValue(req).Value end end -- Alle ( int und float ) if (InDepth:GetValue(req).Value > 0) then if InDepth:GetValue(req).Value == 1 then SourceDepth = 5 else if InDepth:GetValue(req).Value == 2 then SourceDepth = 6 else if InDepth:GetValue(req).Value == 3 then SourceDepth = 7 else SourceDepth = 8 end end end end local imgattrs = { IMG_Document = self.Comp, { IMG_Channel = "Red", }, { IMG_Channel = "Green", }, { IMG_Channel = "Blue", }, { IMG_Channel = "Alpha", }, IMG_Width = Width, IMG_Height = Height, IMG_XScale = XAspect, IMG_YScale = YAspect, IMAT_OriginalWidth = realwidth, -- nil !?! IMAT_OriginalHeight = realheight, -- nil !?! IMG_Quality = not req:IsQuick(), IMG_MotionBlurQuality = not req:IsNoMotionBlur(), IMG_DeferAlloc = true, IMG_ProxyScale = ( (not req:IsStampOnly()) and 1 or nil), IMG_Depth = ( (SourceDepth~=0) and SourceDepth or nil ) } local dst = Image(imgattrs) local black = Pixel({R=0,G=0,B=0,A=0}) dst:Fill(black) if req:IsPreCalc() then local out = Image({IMG_Like = dst, IMG_NoData = true}) OutImage:Set(req, out) return end node = DVIPComputeNode(req, "MoreFractalRopesFuse", ShaderCompatibilityCode..ShaderKernelCode, "Params", ShaderParameters ) -- Extern texture or create a new one iChannel0 = InChannel0:GetValue(req) if iChannel0==nil then iChannel0 = Image(imgattrs) iChannel0:Fill(black) end -- DCTL parameters local framerate = self.Comp:GetPrefs("Comp.FrameFormat.Rate") local params = {} params = node:GetParamBlock(ShaderParameters) params.iResolution[0] = dst.Width params.iResolution[1] = dst.Height params.iTime = (req.Time / framerate) * InFrequency:GetValue(req).Value -- iMouse local mouse_xy = InMouseXY:GetValue(req) local mouse_zw = InMouseZW:GetValue(req) params.iMouse[0] = mouse_xy.X params.iMouse[1] = mouse_xy.Y params.iMouse[2] = mouse_zw.X params.iMouse[3] = mouse_zw.Y if InMouseDrag:GetValue(req).Value ~= 0 then if params.iMouse[2]==-1 and params.iMouse[3]==-1 then params.iMouse[2]=params.iMouse[0] params.iMouse[3]=params.iMouse[1] end else params.iMouse[2] = -1 params.iMouse[3] = -1 end if mouse_zw.X ~= params.iMouse[2] or mouse_zw.Y ~= params.iMouse[3] then InMouseZW:SetAttrs({INP_Disabled=false}) InMouseZW:SetSource(Point(params.iMouse[2],params.iMouse[3]),0,0) InMouseZW:SetAttrs({INP_Disabled=true}) end params.iMouse[0] = params.iMouse[0] * Width params.iMouse[1] = params.iMouse[1] * Height if params.iMouse[2] == -1 and params.iMouse[3] == -1 then params.iMouse[2] = 0 params.iMouse[3] = 0 else params.iMouse[2] = params.iMouse[2] * Width params.iMouse[3] = params.iMouse[3] * Height end params.Option1 = InOption1Checkbox:GetValue(req).Value params.MouseRotVar = InMouseRotVarCheckbox:GetValue(req).Value params.Color1 = { InColor1ColorR:GetValue(req).Value, InColor1ColorG:GetValue(req).Value, InColor1ColorB:GetValue(req).Value,InColor1ColorA:GetValue(req).Value } params.Color2 = { InColor2ColorR:GetValue(req).Value, InColor2ColorG:GetValue(req).Value, InColor2ColorB:GetValue(req).Value,InColor2ColorA:GetValue(req).Value } params.Variants = InVariantsButton:GetValue(req).Value params.ViewDXY = {InViewDXYPoint:GetValue(req).X,InViewDXYPoint:GetValue(req).Y} params.ViewDZ = InViewDZSlider:GetValue(req).Value params.ViewXY = {InViewXYPoint:GetValue(req).X,InViewXYPoint:GetValue(req).Y} params.ViewZ = InViewZSlider:GetValue(req).Value params.ambient = InambientSlider:GetValue(req).Value params.difPower = IndifPowerSlider:GetValue(req).Value params.r = InrSlider:GetValue(req).Value -- Resolution params.width = dst.Width params.height = dst.Height -- Per channel time and resolution local edges = InEdges:GetValue(req).Value -- Set parameters and add I/O node:SetParamBlock(params) --node:AddSampler("RowSampler", TEX_FILTER_MODE_LINEAR,TEX_ADDRESS_MODE_MIRROR, TEX_NORMALIZED_COORDS_TRUE) DefineEdges(edges, node) node:AddInput("iChannel0",iChannel0) -- TODO: add a better channel name node:AddOutput("dst", dst) local ok = node:RunSession(req) if (not ok) then dst = nil dump(node:GetErrorLog()) end OutImage:Set(req,dst) collectgarbage(); end -- // ------------------------------------------------------------------------ -- // Callback -- // ------------------------------------------------------------------------ function NotifyChanged(inp, param, time) if (param ~= nil) then if inp == InSize then if param.Value == 1 then InWidth:SetAttrs({ IC_Visible = true }) InHeight:SetAttrs({ IC_Visible = true }) else InWidth:SetAttrs({ IC_Visible = false }) InHeight:SetAttrs({ IC_Visible = false }) end if param.Value == 3 then --1920x1080 InWidth:SetSource(Number(1920),0,0) InHeight:SetSource(Number(1080),0,0) end if param.Value == 4 then --1200x675 InWidth:SetSource(Number(1200),0,0) InHeight:SetSource(Number(675),0,0) end if param.Value == 5 then --800x450 InWidth:SetSource(Number(800),0,0) InHeight:SetSource(Number(450),0,0) end if param.Value == 6 then --640x360 InWidth:SetSource(Number(640),0,0) InHeight:SetSource(Number(360),0,0) end end end end -- */