--[[--/* Unimagined.fuse Based on https://www.shadertoy.com/view/NflSD8 a WebGL shader created by OldEclipse. 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]; float Color1[4]; float ViewDXY[2]; float ViewDZ; float Travel; float Repetition; float Density; 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)) #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; } #endif // end of mat2 implementation #if defined(USE_NATIVE_METAL_IMPL) #define mod_f3(value,divisor) fmod(value,divisor) #define sin_f4(i) sin(i) #define cos_f4(i) cos(i) #define tanh_f4(i) tanh(i) #define exp_f4(a) _expf((a)) #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 mod_f3(value,divisor) _fmod(value,divisor) #define mod_f(a,b) ((a)-(b)*_floor((a)/(b))) #define mod_f3(value,divisor) to_float3(mod_f((value).x, (divisor)),mod_f((value).y, (divisor)),mod_f((value).z, (divisor))) #define sin_f4(i) sin(i) #define cos_f4(i) cos(i) #define tanh_f4(i) tanh(i) #define exp_f4(a) _expf((a)) #else // Generic #define fract(a) ((a)-_floor(a)) #define mod_f3(value,divisor) to_float3(mod_f((value).x, (divisor)),mod_f((value).y, (divisor)),mod_f((value).z, (divisor))) #define sin_f4(i) to_float4( _sinf((i).x), _sinf((i).y), _sinf((i).z), _sinf((i).w)) #define cos_f4(i) to_float4( _cosf((i).x), _cosf((i).y), _cosf((i).z), _cosf((i).w)) #define tanh_f4(i) to_float4(_tanhf((i).x), _tanhf((i).y), _tanhf((i).z), _tanhf((i).w)) #define exp_f4(a) to_float4(_expf((a).x), _expf((a).y),_expf((a).z),_expf((a).w)) #endif #endif ]] -- /* -- // ------------------------------------------------------------------------ -- DCTL kernel implementation -- // ------------------------------------------------------------------------ -- */ ShaderKernelCode = [[ // ---------------------------------------------------------------------------------- // - Common - // ---------------------------------------------------------------------------------- #define PI 3.1415926535897f __DEVICE__ mat2 rot(float a){ return to_mat2(_cosf(a),_sinf(a),-_sinf(a),_cosf(a)); } __DEVICE__ inline mat2 to_mat2_f4 (float4 a) { mat2 t; t.r0.x = a.x; t.r0.y = a.y; t.r1.x = a.z; t.r1.y = a.w; return t; } // ---------------------------------------------------------------------------------- // - Image - // ---------------------------------------------------------------------------------- __KERNEL__ void UnimaginedFuse(__CONSTANTREF__ Params* params, __TEXTURE2D_WRITE__ destinationTexture) { DEFINE_KERNEL_ITERATORS_XY(fusion_x, fusion_y); if (fusion_x >= 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 O = to_float4_s(0.0f); float2 I = to_float2(fusion_x,fusion_y); float4 Color1 = to_float4(params->Color1[0], params->Color1[1], params->Color1[2], params->Color1[3]); float2 ViewDXY = to_float2(params->ViewDXY[0], params->ViewDXY[1]); float ViewDZ = params->ViewDZ; float Travel = params->Travel; float Repetition = params->Repetition; float Density = params->Density; // -------- // Iterator, distance travelled, density float i=0.0f, t=0.0f, v=0.0f; // Raymarching loop for (O*=i; i++<50.0f;){ float3 p = t*normalize(to_float3_aw(I+I,1)-swi3(iResolution,x,y,y) + to_float3_aw(ViewDXY*iResolution, ViewDZ*iResolution.y)); // Rotation of xy coordinates based on distance travelled swi2S(p,x,y, mul_f2_mat2(swi2(p,x,y) , to_mat2_f4(cos_f4(t*0.15f+to_float4(0,11,33,0))))); //############################################################# float x = iMouse.x == 0.0f && iMouse.y == 0.0f ? -0.005f : -(iMouse.y/iResolution.y * 0.25f - 0.125f) * PI; float y = iMouse.x == 0.0f && iMouse.y == 0.0f ? 0.015f : -(iMouse.x/iResolution.x * 0.25f - 0.125f) * PI; mat2 rx = rot(x); mat2 ry = rot(y); swi2S(p,y,z, mul_f2_mat2(swi2(p,y,z) , rx)); swi2S(p,x,z, mul_f2_mat2(swi2(p,x,z) , ry)); //############################################################### // Move forward p.z -= iTime; // Coordinate repetition p = mod_f3(p,Repetition)-2.0f; //4.0f // Density from mix between sphere and line sdf based on distance travelled v = _mix(_fabs(length(p)-1.0f),length(swi2(p,x,z)),Density-Density*_cosf(t))+0.01f;// 0.5f-0.5f*_cosf(t))+0.01f; // Travel forwards based on density t += v*Travel;//0.3f; // Color accumulation based on density and distance travelled O += exp_f4(sin_f4(t+Color1))/v; //to_float4(0,2,4,0) } // Tone mapping O = tanh_f4(O/2e2f); O.w = Color1.w; _tex2DVec4Write(destinationTexture, fusion_x, fusion_y, O); } ]] -- /* -- // ------------------------------------------------------------------------ -- // Create -- // ------------------------------------------------------------------------ function Create() ShaderFuse.begin_create() ----- Inspector Panel Controls -- Speed Slider InFrequency = self:AddInput("Speedup", "speed", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_Default = 1.0, INP_MinScale = 0.0, INP_MaxScale = 5.0, SLCS_LowName = "stop", SLCS_HighName = "5x", }) -- iMouse Controls InMouseXY = self:AddInput("iMouse.xy", "iMouseXY", { LINKID_DataType = "Point", INPID_InputControl = "OffsetControl", INP_DoNotifyChanged = false, --INP_Passive = true, INPID_PreviewControl = "CrosshairControl", }) InMouseZW = self:AddInput("iMouse.zw", "iMouseZW", { LINKID_DataType = "Point", INPID_InputControl = "OffsetControl", INP_DoNotifyChanged = false, --INP_Passive = true, INPID_PreviewControl = "CrosshairControl", INP_Disabled = true, }) InMouseDrag = self:AddInput("Mouse Button Pressed", "iMouseClick", { LINKID_DataType = "Number", INPID_InputControl = "CheckboxControl", INP_DoNotifyChanged = false, --INP_Passive = true, INP_MinScale = 0, INP_MaxScale = 1, INP_Default = 0, }) self:BeginControlNest("Color1", "Color1", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Color1", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InColor1ColorR = self:AddInput("Red", "Color1Red", { INP_Default = 0.0, IC_ControlID = 0, attrs}) InColor1ColorG = self:AddInput("Green", "Color1Green", { INP_Default = 2.0, IC_ControlID = 1, attrs}) InColor1ColorB = self:AddInput("Blue", "Color1Blue", { INP_Default = 4.0, IC_ControlID = 2, attrs}) InColor1ColorA = self:AddInput("Alpha", "Color1Alpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() InViewDXYPoint = self:AddInput("ViewDXY", "ViewDXY", { LINKID_DataType = "Point", INPID_InputControl = "OffsetControl", INPID_PreviewControl = "CrosshairControl", INP_DefaultX = 0.0, INP_DefaultY = 0.0, }) InViewDZSlider = self:AddInput("ViewDZ", "ViewDZ", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_MinScale = -10.0, INP_MaxScale = 10.0, INP_Default = 0.0, }) InTravelSlider = self:AddInput("Travel", "Travel", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_MinScale = -1.0, INP_MaxScale = 1.0, INP_Default = 0.3, }) InRepetitionSlider = self:AddInput("Repetition", "Repetition", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_MinScale = -1.0, INP_MaxScale = 10.0, INP_Default = 4.0, }) InDensitySlider = self:AddInput("Density", "Density", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_MinScale = -1.0, INP_MaxScale = 3.0, INP_Default = 0.5, }) Sep3 = self:AddInput(string.rep("_", 152), "Separator3", { LINKID_DataType = "Text", INPID_InputControl = "LabelControl", INP_External = false, INP_Passive = true, IC_Visible = true, INP_DoNotifyChanged = true, IC_NoLabel = true, }) ----- Size & Depth InSize = self:AddInput("Size", "Size_Fuse", { LINKID_DataType = "Number", INPID_InputControl = "ComboControl", INP_DoNotifyChanged = true, INP_Default = 0, INP_Integer = true, ICD_Width = 1, { CCS_AddString = "Default", }, { CCS_AddString = "Manually", }, { CCS_AddString = "Image0", }, { CCS_AddString = "1920x1080", }, { CCS_AddString = "1200x675", }, { CCS_AddString = "800x450", }, { CCS_AddString = "640x360", }, CC_LabelPosition = "Horizontal", ICS_ControlPage = "Image", }) InWidth = self:AddInput("Width", "_Width", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_Default = 1920, INP_Integer = true, INP_MinScale = 0, INP_MaxScale = 4096, }) InHeight = self:AddInput("Height", "_Height", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_Default = 1080, INP_Integer = true, INP_MinScale = 0, INP_MaxScale = 4096, }) InDepth = self:AddInput("Depth_Fuse", "Depth_Fuse", { LINKID_DataType = "Number", INPID_InputControl = "ComboControl", INP_DoNotifyChanged = true, INP_Default = 0, INP_Integer = true, ICD_Width = 1, { CCS_AddString = "Default", }, { CCS_AddString = "int8", }, { CCS_AddString = "int16", }, { CCS_AddString = "float16", }, { CCS_AddString = "float32", }, CC_LabelPosition = "Horizontal", ICS_ControlPage = "Image", }) InMyWidth = self:FindInput("Width") InMyWidth:SetAttrs({ IC_Visible = false }) InMyHeight = self:FindInput("Height") InMyHeight:SetAttrs({ IC_Visible = false }) InMyDepth = self:FindInput("Depth") InMyDepth:SetAttrs({ IC_Visible = false }) ----- In/Out OutImage = self:AddOutput("Output", "Output", { LINKID_DataType = "Image", LINK_Main = 1, }) ShaderFuse.end_create() end -- // ------------------------------------------------------------------------ -- // Process -- // ------------------------------------------------------------------------ function Process(req) -- Imagesize and Depth if (InSize:GetValue(req).Value >= 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, "UnimaginedFuse", ShaderCompatibilityCode..ShaderKernelCode, "Params", ShaderParameters ) -- Extern texture or create a new one -- 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.Color1 = { InColor1ColorR:GetValue(req).Value, InColor1ColorG:GetValue(req).Value, InColor1ColorB:GetValue(req).Value,InColor1ColorA:GetValue(req).Value } params.ViewDXY = {InViewDXYPoint:GetValue(req).X,InViewDXYPoint:GetValue(req).Y} params.ViewDZ = InViewDZSlider:GetValue(req).Value params.Travel = InTravelSlider:GetValue(req).Value params.Repetition = InRepetitionSlider:GetValue(req).Value params.Density = InDensitySlider:GetValue(req).Value -- Resolution params.width = dst.Width params.height = dst.Height -- Per channel time and resolution node:SetParamBlock(params) node:AddSampler("RowSampler", TEX_FILTER_MODE_LINEAR,TEX_ADDRESS_MODE_MIRROR, TEX_NORMALIZED_COORDS_TRUE) 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 -- */