--[[--/* Oddish.fuse Based on https://www.shadertoy.com/view/NXX3RB a WebGL shader created by noztol. 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 BodyColor[4]; float EyeColor[4]; float Mat25Color[4]; float Mat3Color[4]; float FloorColor[4]; float Hair1Color[4]; float Hair2Color[4]; float Hair3Color[4]; float Sky1Color[4]; float Sky2Color[4]; float ViewDXY[2]; float ViewDZ; float ViewXY[2]; float ViewZ; 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 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 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 pow_f3(a,b) to_float3(_powf((a).x,(b).x),_powf((a).y,(b).y),_powf((a).z,(b).z)) #endif #endif ]] -- /* -- // ------------------------------------------------------------------------ -- DCTL kernel implementation -- // ------------------------------------------------------------------------ -- */ ShaderKernelCode = [[ // ---------------------------------------------------------------------------------- // - Image - // ---------------------------------------------------------------------------------- // Oddish Shader // By Noztol #define PI 3.141593f #define MAX_STEPS 200 #define MAX_DIST 50.0f #define SURFACE_DIST 0.001f __DEVICE__ mat2 Rot(float a) { float s = _sinf(a), c = _cosf(a); return to_mat2(c, -s, s, c); } __DEVICE__ float smin(float a, float b, float k) { float h = clamp(0.5f + 0.5f*(b - a)/k, 0.0f, 1.0f); return _mix(b, a, h) - k*h*(1.0f-h); } __DEVICE__ float smax(float a, float b, float k) { float h = clamp(0.5f - 0.5f*(b-a)/k, 0.0f, 1.0f); return _mix(b, a, h) + k*h*(1.0f-h); } __DEVICE__ float sdSpherePrim(float3 p, float s) { return length(p) - s; } __DEVICE__ float sdEllipsoid(float3 p, float3 r) { float k0 = length(p/r); float k1 = length(p/(r*r)); return k0*(k0-1.0f)/k1; } __DEVICE__ float sdCapsule(float3 p, float3 a, float3 b, float r) { float3 pa = p - a, ba = b - a; float h = clamp(dot(pa, ba)/dot(ba, ba), 0.0f, 1.0f); return length(pa - ba*h) - r; } __DEVICE__ float sdLeaf(float3 p) { p.y -= 0.6f; p.z += _fabs(p.x) * 0.15f; return sdEllipsoid(p, to_float3(0.35f, 0.85f, 0.03f)); } __DEVICE__ float3 GetSky(float3 rd, float3 Sky1Color, float3 Sky2Color) { float t = clamp(rd.y * 0.5f + 0.5f, 0.0f, 1.0f); //return _mix(to_float3(0.8f, 0.85f, 0.9f), to_float3(0.5f, 0.65f, 0.8f), t); return _mix(Sky1Color, Sky2Color, t); } __DEVICE__ float2 map(float3 p, float iTime) { // jump animation float bouncePhase = iTime * 4.5f; float bounce = _powf(_fabs(_sinf(bouncePhase)), 1.5f) * 0.8f; float baseHeight = 1.15f; float3 pModel = p; pModel.y -= (baseHeight + bounce); // Root Body Base float body = sdEllipsoid(pModel, to_float3(0.95f, 0.85f, 0.95f)); // blinking animation float blink = smoothstep(0.7f, 0.95f, _sinf(iTime * 1.5f)); float lidHeight = _mix(0.18f, -0.18f, blink); float3 pLeft = pModel; pLeft.x = _fabs(pLeft.x); float3 pEyeSpace = pLeft - to_float3(0.35f, 0.15f, -0.88f); swi2S(pEyeSpace,x,z, mul_f2_mat2(swi2(pEyeSpace,x,z) , Rot(-0.25f))); float eyeHole = sdEllipsoid(pEyeSpace, to_float3(0.12f, 0.18f, 0.15f)); body = _fmaxf(body, -eyeHole); float eyelidBase = sdEllipsoid(pModel, to_float3(0.94f, 0.84f, 0.94f)); float eyelid = _fmaxf(eyelidBase, eyeHole - 0.02f); eyelid = _fmaxf(eyelid, -(pEyeSpace.y - lidHeight)); body = _fminf(body, eyelid); // smile animation float3 pMouth = pModel - to_float3(0.0f, -0.15f, -0.85f); float mouthAnim = _sinf(iTime * 4.5f) * 0.5f + 0.5f; float openAmt = _mix(0.04f, 0.12f, mouthAnim); float lowerMouth = sdEllipsoid(pMouth, to_float3(0.18f, 0.12f, 0.25f)); float upperLip = sdEllipsoid(pMouth - to_float3(0.0f, openAmt, 0.0f), to_float3(0.25f, 0.15f, 0.3f)); float mouthCavity = _fmaxf(lowerMouth, -upperLip); float bodyWithMouth = smax(body, -mouthCavity, 0.015f); float matID = 1.0f; if (-mouthCavity > body - 0.01f) matID = 3.0f; // legs ankle and feet float3 hip = to_float3(0.25f, -0.65f, 0.0f); float3 ankle = to_float3(0.35f, -1.0f, 0.1f); float leg = sdCapsule(pLeft, hip, ankle, 0.12f); float3 pFoot = pLeft - ankle; float flex = clamp(bounce * 1.5f, 0.0f, 1.0f); swi2S(pFoot,y,z, mul_f2_mat2(swi2(pFoot,y,z) , Rot(-flex * 0.8f))); swi2S(pFoot,x,y, mul_f2_mat2(swi2(pFoot,x,y) , Rot(0.1f))); swi2S(pFoot,x,z, mul_f2_mat2(swi2(pFoot,x,z) , Rot(0.25f))); pFoot.z += 0.15f; pFoot.y += 0.05f; float foot = sdEllipsoid(pFoot, to_float3(0.16f, 0.11f, 0.28f)); float limbs = smin(leg, foot, 0.08f); bodyWithMouth = smin(bodyWithMouth, limbs, 0.05f); float2 res = to_float2(bodyWithMouth, matID); // Leaves float leaves = 1e10; for(int i=0; i<5; i++) { float3 pLeaf = pModel - to_float3(0.0f, 0.75f, 0.0f); float angle = (float)(i) * (2.0f * PI / 5.0f) + iTime * 0.15f; swi2S(pLeaf,x,z, mul_f2_mat2(swi2(pLeaf,x,z) , Rot(angle))); float sway = _sinf(iTime * 4.5f + (float)(i)) * 0.08f; swi2S(pLeaf,y,z, mul_f2_mat2(swi2(pLeaf,y,z) , Rot(-0.45f + sway))); leaves = smin(leaves, sdLeaf(pLeaf), 0.05f); } if (leaves < res.x) res = to_float2(leaves, 5.0f); // Eye Contents float eye = sdEllipsoid(pEyeSpace, to_float3(0.06f, 0.12f, 0.06f)); float highlight = sdSpherePrim(pEyeSpace - to_float3(-0.015f, 0.04f, -0.05f), 0.015f); eye = _fmaxf(eye, pEyeSpace.y - lidHeight); highlight = _fmaxf(highlight, pEyeSpace.y - lidHeight); if (eye < res.x) { res = to_float2(eye, 2.0f); if (highlight < eye) res = to_float2(highlight, 2.5f); } // Floor float floorPlane = p.y; if (floorPlane < res.x) { res = to_float2(floorPlane, 4.0f); } return res; } __DEVICE__ float3 GetNormal(float3 p, float iTime) { float2 e = to_float2(0.001f, 0); return normalize(map(p, iTime).x - to_float3(map(p-swi3(e,x,y,y), iTime).x, map(p-swi3(e,y,x,y), iTime).x, map(p-swi3(e,y,y,x), iTime).x)); } // Shadows __DEVICE__ float getShadow(float3 ro, float3 rd, float iTime) { float res = 1.0f; float t = 0.05f; // Normal offset baseline for(int i = 0; i < 60; i++) { // Plenty of steps to gracefully traverse gradients float h = map(ro + rd * t, iTime).x; res = _fminf(res, 14.0f * _fmaxf(h, 0.0f) / t); // Soft shadow calculation if(res < 0.001f || t > 15.0f) break; t += h; // Trust the math, step exactly the distance to the nearest surface } return clamp(res, 0.0f, 1.0f); } __DEVICE__ float3 GetColor(float3 p, float3 n, float matID, float3 rd, float3 Colors[8], inout float *Alpha, float Floorw) { float3 l = normalize(to_float3(4.0f, 6.0f, -5.0f)); float dif = clamp(dot(n, l), 0.0f, 1.0f); float3 ref = reflect(-l, n); float spec = 0.0f; float3 col = to_float3_s(0); if(matID == 1.0f) { col = Colors[0];//to_float3(0.35f, 0.48f, 0.62f); spec = _powf(clamp(dot(ref, -rd), 0.0f, 1.0f), 16.0f) * 0.15f; col = col * (dif * 0.8f + 0.2f) + spec; *Alpha = 1.0f; } else if(matID == 3.0f) { col = Colors[1];//to_float3(0.08f, 0.15f, 0.25f); col *= (dif * 0.2f + 0.1f); *Alpha = 1.0f; } else if(matID == 5.0f) { float grad = smoothstep(0.5f, 2.5f, p.y); //col = _mix(to_float3(0.4f, 0.6f, 0.2f), to_float3(0.6f, 0.8f, 0.3f), grad); col = _mix(Colors[2], Colors[3], grad); float sss = _powf(clamp(dot(-l, rd), 0.0f, 1.0f), 3.0f) * 0.5f; col += Colors[4] * sss;//to_float3(0.5f, 0.9f, 0.3f) * sss; spec = _powf(clamp(dot(ref, -rd), 0.0f, 1.0f), 32.0f) * 0.2f; col = col * (dif * 0.8f + 0.2f) + spec; *Alpha = 1.0f; } else if(matID == 2.0f) { col = Colors[5];//to_float3(0.8f, 0.1f, 0.1f); col *= (dif * 0.9f + 0.1f); *Alpha = 1.0f; } else if(matID == 2.5f) { col = Colors[6];//to_float3_s(1.0f); *Alpha = 1.0f; } else if(matID == 4.0f) { // Plain studio floor to match the reference image exactly col = Colors[7];//to_float3_s(0.7f); col *= (dif * 0.6f + 0.4f); *Alpha = Floorw; } return col; } __KERNEL__ void OddishFuse(__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 fragColor = to_float4_s(0.0f); float2 fragCoord = to_float2(fusion_x,fusion_y); float4 BodyColor = to_float4(params->BodyColor[0], params->BodyColor[1], params->BodyColor[2], params->BodyColor[3]); float4 EyeColor = to_float4(params->EyeColor[0], params->EyeColor[1], params->EyeColor[2], params->EyeColor[3]); float4 Mat25Color = to_float4(params->Mat25Color[0], params->Mat25Color[1], params->Mat25Color[2], params->Mat25Color[3]); float4 Mat3Color = to_float4(params->Mat3Color[0], params->Mat3Color[1], params->Mat3Color[2], params->Mat3Color[3]); float4 FloorColor = to_float4(params->FloorColor[0], params->FloorColor[1], params->FloorColor[2], params->FloorColor[3]); float4 Hair1Color = to_float4(params->Hair1Color[0], params->Hair1Color[1], params->Hair1Color[2], params->Hair1Color[3]); float4 Hair2Color = to_float4(params->Hair2Color[0], params->Hair2Color[1], params->Hair2Color[2], params->Hair2Color[3]); float4 Hair3Color = to_float4(params->Hair3Color[0], params->Hair3Color[1], params->Hair3Color[2], params->Hair3Color[3]); float4 Sky1Color = to_float4(params->Sky1Color[0], params->Sky1Color[1], params->Sky1Color[2], params->Sky1Color[3]); float4 Sky2Color = to_float4(params->Sky2Color[0], params->Sky2Color[1], params->Sky2Color[2], params->Sky2Color[3]); 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; // -------- float3 Colors[8] = {swi3(BodyColor,x,y,z), swi3(Mat3Color,x,y,z), swi3(Hair1Color,x,y,z), swi3(Hair2Color,x,y,z), swi3(Hair3Color,x,y,z), swi3(EyeColor,x,y,z), swi3(Mat25Color,x,y,z), swi3(FloorColor,x,y,z)}; float Alpha = Sky1Color.w; float Floorw = FloorColor.w; float2 uv = (fragCoord-0.5f*iResolution)/iResolution.y; float3 ro = to_float3(0.0f, 3.5f, -7.0f); if(iMouse.z > 0.0f) { float2 m = swi2(iMouse,x,y)/iResolution; ro = to_float3(0, 3.5f, -7.0f); swi2S(ro,x,z, mul_f2_mat2(swi2(ro,x,z) , Rot((m.x - 0.5f) * 6.0f))); ro.y = _mix(0.5f, 8.0f, m.y); } float3 lookat = to_float3(0, 1.0f, 0) + to_float3_aw(ViewDXY, ViewDZ); float3 f = normalize(lookat-ro), r = normalize(cross(to_float3(0,1,0), f)), u = cross(f,r); float3 rd = normalize(f + uv.x*r + uv.y*u + to_float3_aw(ViewXY, ViewZ)); float dO = 0.0f, matID = 0.0f; bool hit = false; for(int i=0; i MAX_DIST) break; } float3 col = GetSky(rd, swi3(Sky1Color,x,y,z), swi3(Sky2Color,x,y,z)); if(hit) { float3 p = ro + rd * dO; float3 n = GetNormal(p, iTime); col = GetColor(p, n, matID, rd, Colors, &Alpha, Floorw); float3 l = normalize(to_float3(4.0f, 6.0f, -5.0f)); float shadow = getShadow(p + n * 0.05f, l, iTime); if (matID == 4.0f) { col *= _mix(0.2f, 1.0f, shadow); float distFade = smoothstep(15.0f, MAX_DIST - 5.0f, dO); col = _mix(col, GetSky(rd, swi3(Sky1Color,x,y,z), swi3(Sky2Color,x,y,z)), distFade); Alpha = Sky1Color.w; } else if (matID != 3.0f && matID != 2.5f) { col *= _mix(0.6f, 1.0f, shadow); } float ao = clamp(p.y * 0.5f + 0.3f, 0.0f, 1.0f); if (matID != 4.0f) col *= _mix(0.6f, 1.0f, ao); } col = pow_f3(col, to_float3_s(0.4545f)); fragColor = to_float4_aw(col, Alpha); _tex2DVec4Write(destinationTexture, fusion_x, fusion_y, fragColor); } ]] -- /* -- // ------------------------------------------------------------------------ -- // 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("Colors", "Colors", false, {}) self:BeginControlNest("BodyColor", "BodyColor", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "BodyColor", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InBodyColorColorR = self:AddInput("Red", "BodyColorRed", { INP_Default = 0.35, IC_ControlID = 0, attrs}) InBodyColorColorG = self:AddInput("Green", "BodyColorGreen", { INP_Default = 0.48, IC_ControlID = 1, attrs}) InBodyColorColorB = self:AddInput("Blue", "BodyColorBlue", { INP_Default = 0.62, IC_ControlID = 2, attrs}) InBodyColorColorA = self:AddInput("Alpha", "BodyColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("EyeColor", "EyeColor", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "EyeColor", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InEyeColorColorR = self:AddInput("Red", "EyeColorRed", { INP_Default = 0.8, IC_ControlID = 0, attrs}) InEyeColorColorG = self:AddInput("Green", "EyeColorGreen", { INP_Default = 0.1, IC_ControlID = 1, attrs}) InEyeColorColorB = self:AddInput("Blue", "EyeColorBlue", { INP_Default = 0.1, IC_ControlID = 2, attrs}) InEyeColorColorA = self:AddInput("Alpha", "EyeColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Mat25Color", "Mat25Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Mat25Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InMat25ColorColorR = self:AddInput("Red", "Mat25ColorRed", { INP_Default = 1.0, IC_ControlID = 0, attrs}) InMat25ColorColorG = self:AddInput("Green", "Mat25ColorGreen", { INP_Default = 1.0, IC_ControlID = 1, attrs}) InMat25ColorColorB = self:AddInput("Blue", "Mat25ColorBlue", { INP_Default = 1.0, IC_ControlID = 2, attrs}) InMat25ColorColorA = self:AddInput("Alpha", "Mat25ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Mat3Color", "Mat3Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Mat3Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InMat3ColorColorR = self:AddInput("Red", "Mat3ColorRed", { INP_Default = 0.08, IC_ControlID = 0, attrs}) InMat3ColorColorG = self:AddInput("Green", "Mat3ColorGreen", { INP_Default = 0.15, IC_ControlID = 1, attrs}) InMat3ColorColorB = self:AddInput("Blue", "Mat3ColorBlue", { INP_Default = 0.25, IC_ControlID = 2, attrs}) InMat3ColorColorA = self:AddInput("Alpha", "Mat3ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("FloorColor", "FloorColor", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "FloorColor", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InFloorColorColorR = self:AddInput("Red", "FloorColorRed", { INP_Default = 0.7, IC_ControlID = 0, attrs}) InFloorColorColorG = self:AddInput("Green", "FloorColorGreen", { INP_Default = 0.7, IC_ControlID = 1, attrs}) InFloorColorColorB = self:AddInput("Blue", "FloorColorBlue", { INP_Default = 0.7, IC_ControlID = 2, attrs}) InFloorColorColorA = self:AddInput("Alpha", "FloorColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Hair1Color", "Hair1Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Hair1Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InHair1ColorColorR = self:AddInput("Red", "Hair1ColorRed", { INP_Default = 0.4, IC_ControlID = 0, attrs}) InHair1ColorColorG = self:AddInput("Green", "Hair1ColorGreen", { INP_Default = 0.6, IC_ControlID = 1, attrs}) InHair1ColorColorB = self:AddInput("Blue", "Hair1ColorBlue", { INP_Default = 0.2, IC_ControlID = 2, attrs}) InHair1ColorColorA = self:AddInput("Alpha", "Hair1ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Hair2Color", "Hair2Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Hair2Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InHair2ColorColorR = self:AddInput("Red", "Hair2ColorRed", { INP_Default = 0.6, IC_ControlID = 0, attrs}) InHair2ColorColorG = self:AddInput("Green", "Hair2ColorGreen", { INP_Default = 0.8, IC_ControlID = 1, attrs}) InHair2ColorColorB = self:AddInput("Blue", "Hair2ColorBlue", { INP_Default = 0.3, IC_ControlID = 2, attrs}) InHair2ColorColorA = self:AddInput("Alpha", "Hair2ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Hair3Color", "Hair3Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Hair3Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InHair3ColorColorR = self:AddInput("Red", "Hair3ColorRed", { INP_Default = 0.5, IC_ControlID = 0, attrs}) InHair3ColorColorG = self:AddInput("Green", "Hair3ColorGreen", { INP_Default = 0.9, IC_ControlID = 1, attrs}) InHair3ColorColorB = self:AddInput("Blue", "Hair3ColorBlue", { INP_Default = 0.3, IC_ControlID = 2, attrs}) InHair3ColorColorA = self:AddInput("Alpha", "Hair3ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Sky1Color", "Sky1Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Sky1Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InSky1ColorColorR = self:AddInput("Red", "Sky1ColorRed", { INP_Default = 0.8, IC_ControlID = 0, attrs}) InSky1ColorColorG = self:AddInput("Green", "Sky1ColorGreen", { INP_Default = 0.85, IC_ControlID = 1, attrs}) InSky1ColorColorB = self:AddInput("Blue", "Sky1ColorBlue", { INP_Default = 0.9, IC_ControlID = 2, attrs}) InSky1ColorColorA = self:AddInput("Alpha", "Sky1ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() self:BeginControlNest("Sky2Color", "Sky2Color", true, {}) ctrl_grp_cnt = (ctrl_grp_cnt==nil) and 1 or (ctrl_grp_cnt+1) attrs = { ICS_Name = "Sky2Color", LINKID_DataType = "Number", INPID_InputControl = "ColorControl", INP_MinScale = 0.0, INP_MaxScale = 1.0, IC_ControlGroup = ctrl_grp_cnt, } InSky2ColorColorR = self:AddInput("Red", "Sky2ColorRed", { INP_Default = 0.5, IC_ControlID = 0, attrs}) InSky2ColorColorG = self:AddInput("Green", "Sky2ColorGreen", { INP_Default = 0.65, IC_ControlID = 1, attrs}) InSky2ColorColorB = self:AddInput("Blue", "Sky2ColorBlue", { INP_Default = 0.8, IC_ControlID = 2, attrs}) InSky2ColorColorA = self:AddInput("Alpha", "Sky2ColorAlpha", { INP_Default = 1.0, IC_ControlID = 3, attrs}) self:EndControlNest() 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, }) InViewXYPoint = self:AddInput("ViewXY", "ViewXY", { LINKID_DataType = "Point", INPID_InputControl = "OffsetControl", INPID_PreviewControl = "CrosshairControl", INP_DefaultX = 0.0, INP_DefaultY = 0.0, }) InViewZSlider = self:AddInput("ViewZ", "ViewZ", { LINKID_DataType = "Number", INPID_InputControl = "SliderControl", INP_MinScale = -10.0, INP_MaxScale = 10.0, INP_Default = 0.0, }) 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, "OddishFuse", 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.BodyColor = { InBodyColorColorR:GetValue(req).Value, InBodyColorColorG:GetValue(req).Value, InBodyColorColorB:GetValue(req).Value,InBodyColorColorA:GetValue(req).Value } params.EyeColor = { InEyeColorColorR:GetValue(req).Value, InEyeColorColorG:GetValue(req).Value, InEyeColorColorB:GetValue(req).Value,InEyeColorColorA:GetValue(req).Value } params.Mat25Color = { InMat25ColorColorR:GetValue(req).Value, InMat25ColorColorG:GetValue(req).Value, InMat25ColorColorB:GetValue(req).Value,InMat25ColorColorA:GetValue(req).Value } params.Mat3Color = { InMat3ColorColorR:GetValue(req).Value, InMat3ColorColorG:GetValue(req).Value, InMat3ColorColorB:GetValue(req).Value,InMat3ColorColorA:GetValue(req).Value } params.FloorColor = { InFloorColorColorR:GetValue(req).Value, InFloorColorColorG:GetValue(req).Value, InFloorColorColorB:GetValue(req).Value,InFloorColorColorA:GetValue(req).Value } params.Hair1Color = { InHair1ColorColorR:GetValue(req).Value, InHair1ColorColorG:GetValue(req).Value, InHair1ColorColorB:GetValue(req).Value,InHair1ColorColorA:GetValue(req).Value } params.Hair2Color = { InHair2ColorColorR:GetValue(req).Value, InHair2ColorColorG:GetValue(req).Value, InHair2ColorColorB:GetValue(req).Value,InHair2ColorColorA:GetValue(req).Value } params.Hair3Color = { InHair3ColorColorR:GetValue(req).Value, InHair3ColorColorG:GetValue(req).Value, InHair3ColorColorB:GetValue(req).Value,InHair3ColorColorA:GetValue(req).Value } params.Sky1Color = { InSky1ColorColorR:GetValue(req).Value, InSky1ColorColorG:GetValue(req).Value, InSky1ColorColorB:GetValue(req).Value,InSky1ColorColorA:GetValue(req).Value } params.Sky2Color = { InSky2ColorColorR:GetValue(req).Value, InSky2ColorColorG:GetValue(req).Value, InSky2ColorColorB:GetValue(req).Value,InSky2ColorColorA: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 -- 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 -- */