├── Ls_Advect.blink ├── Ls_Cross.blink ├── Ls_Dot.blink ├── Ls_DotDir.blink ├── Ls_GlueP.blink ├── Ls_GlueP.gizmo ├── Ls_Length.blink ├── Ls_Normalize.blink ├── Ls_PtoDepth.blink ├── Ls_Reflect.blink ├── Ls_Rotate.blink ├── Ls_Splineblur.blink └── Ls_Vignette.blink /Ls_Advect.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Advect : ImageComputationKernel { 2 | Image src; 3 | Image map; 4 | Image dst; 5 | 6 | param: 7 | float steplen; 8 | int stepss; 9 | 10 | local: 11 | float realsteplen; 12 | 13 | void define() { 14 | defineParam(steplen, "Step length", 1.0f); 15 | defineParam(stepss, "Steps", 32); 16 | } 17 | 18 | void init() { 19 | realsteplen = steplen * 100.0; 20 | } 21 | 22 | void process(int2 pos) { 23 | float2 where; 24 | where.x = float(pos.x); 25 | where.y = float(pos.y); 26 | for(int i = 0; i < stepss; i++) { 27 | SampleType(map) mapdir = bilinear(map, where.x, where.y); 28 | where.x += mapdir.x * realsteplen; 29 | where.y += mapdir.y * realsteplen; 30 | } 31 | dst() = bilinear(src, where.x, where.y); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Ls_Cross.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Cross : ImageComputationKernel 2 | { 3 | Image src1; 4 | Image src2; 5 | Image dst; 6 | 7 | void process() { 8 | float3 s1 = float3(src1(0), src1(1), src1(2)); 9 | float3 s2 = float3(src2(0), src2(1), src2(2)); 10 | float3 c = cross(s1, s2); 11 | dst() = float4(c.x, c.y, c.z, 0.0); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /Ls_Dot.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Dot : ImageComputationKernel 2 | { 3 | Image src1; 4 | Image src2; 5 | Image dst; 6 | 7 | void process() { 8 | dst(0) = dot(src1(), src2()); 9 | dst(1) = 0.0; 10 | dst(2) = 0.0; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /Ls_DotDir.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_DotDir : ImageComputationKernel 2 | { 3 | Image src; 4 | Image dst; 5 | 6 | param: 7 | float2 dir; 8 | 9 | void define() { 10 | defineParam(dir, "Direction", float2(0.0, 1.0)); 11 | } 12 | 13 | void process() { 14 | dst(0) = dot(float2(src(0), src(1)), dir); 15 | dst(1) = 0.0; 16 | dst(2) = 0.0; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /Ls_GlueP.blink: -------------------------------------------------------------------------------- 1 | // GlueP: project onto a position pass 2 | // lewis@lewissaunders.com 3 | // TODO: 4 | // o rearrange the output selection logic, translating 5 | // the return statements into setting a flag was stupid 6 | // o I wonder what happens when inputs are different sizes 7 | 8 | kernel Ls_GlueP : ImageComputationKernel { 9 | Image src; 10 | Image position; 11 | Image normals; 12 | Image dst; 13 | 14 | param: 15 | bool convertp, convertn, outputp, outputn; 16 | float3 worldcam_position, worldcam_rotation; 17 | float3 projector_position, projector_rotation; 18 | float projector_focal, projector_haperture; 19 | bool frontface, backface, zclip; 20 | float znear, zfar; 21 | bool outputviewspace, outputclipspace, outputndc, outputuv, outputfacingratio; 22 | int srcwidth, srcheight; 23 | 24 | local: 25 | float aspect, vaperture, fovy, fovx; 26 | 27 | void define() { 28 | defineParam(convertp, "ConvertPpassfromcameraspace", false); 29 | defineParam(convertn, "ConvertNpassfromcameraspace", false); 30 | defineParam(outputp, "OutputconvertedP", false); 31 | defineParam(outputn, "OutputconvertedN", false); 32 | defineParam(worldcam_position, "OriginalCGcameraposition", float3(0.0, 0.0, 0.0)); 33 | defineParam(worldcam_rotation, "OriginalCGcamerarotation", float3(0.0, 0.0, 0.0)); 34 | defineParam(projector_position, "Projectorposition", float3(0.0, 0.0, -100.0)); 35 | defineParam(projector_rotation, "Projectorrotation", float3(0.0, 0.0, 0.0)); 36 | defineParam(projector_focal, "Projectorfocallength", 50.0f); 37 | defineParam(projector_haperture, "Projectorhorizontalaperture", 23.76f); 38 | defineParam(zclip, "Depthclip", false); 39 | defineParam(frontface, "Projectonfrontfaces", true); 40 | defineParam(backface, "Projectonbackfaces", true); 41 | defineParam(znear, "Depthclipnear", 0.0f); 42 | defineParam(zfar, "Depthclipfar", 999999.0f); 43 | defineParam(outputviewspace, "Outputviewspace", false); 44 | defineParam(outputclipspace, "Outputclipspace", false); 45 | defineParam(outputndc, "OutputNDCspace", false); 46 | defineParam(outputuv, "OutputUVs", false); 47 | defineParam(outputfacingratio, "OutputFacingRatio", false); 48 | defineParam(srcwidth, "Srcwidth", 1920); 49 | defineParam(srcheight, "Srcheight", 1080); 50 | } 51 | 52 | void init() { 53 | aspect = max(float(srcwidth), 1.0f) / max(float(srcheight), 1.0f); 54 | vaperture = projector_haperture / aspect; 55 | fovy = 2.0f * atan(vaperture / (2.0f * projector_focal)); 56 | fovx = 2.0f * atan(projector_haperture / (2.0f * projector_focal)); 57 | } 58 | 59 | float deg2rad(float angle) { 60 | return(angle/(180.0f/PI)); 61 | } 62 | 63 | // Rotates about the origin in ZXY order 64 | float3 rotate(float3 p, float3 angles) { 65 | float x = deg2rad(angles.x); 66 | float y = deg2rad(angles.y); 67 | float z = deg2rad(angles.z); 68 | 69 | float3x3 rx, ry, rz; 70 | float rxd[] = {1.0, 0.0, 0.0, 0.0, cos(x), -sin(x), 0.0, sin(x), cos(x)}; 71 | float ryd[] = {cos(y), 0.0, sin(y), 0.0, 1.0, 0.0, -sin(y), 0.0, cos(y)}; 72 | float rzd[] = {cos(z), -sin(z), 0.0, sin(z), cos(z), 0.0, 0.0, 0.0, 1.0}; 73 | rx.setArray(rxd); 74 | ry.setArray(ryd); 75 | rz.setArray(rzd); 76 | 77 | float3x3 r = rz * rx * ry; 78 | return(r * p); 79 | } 80 | 81 | // Un-rotates about the origin in ZXY order 82 | float3 unrotate(float3 p, float3 angles) { 83 | float x = deg2rad(angles.x); 84 | float y = deg2rad(angles.y); 85 | float z = deg2rad(angles.z); 86 | 87 | float3x3 rx, ry, rz; 88 | float rxd[] = {1.0f, 0.0f, 0.0f, 0.0f, cos(x), sin(x), 0.0f, -sin(x), cos(x)}; 89 | float ryd[] = {cos(y), 0.0f, -sin(y), 0.0f, 1.0f, 0.0f, sin(y), 0.0f, cos(y)}; 90 | float rzd[] = {cos(z), sin(z), 0.0f, -sin(z), cos(z), 0.0f, 0.0f, 0.0f, 1.0f}; 91 | rx.setArray(rxd); 92 | ry.setArray(ryd); 93 | rz.setArray(rzd); 94 | 95 | float3x3 r = ry * rx * rz; 96 | return(r * p); 97 | } 98 | 99 | void process(int2 pos) { 100 | SampleType(position) prgba = position(); 101 | float3 p = float3(prgba.x, prgba.y, prgba.z); 102 | 103 | SampleType(normals) nrgba = normals(); 104 | float3 n = float3(nrgba.x, nrgba.y, nrgba.z); 105 | 106 | bool outputready = false; 107 | float3 o; 108 | 109 | // Optionally, convert P and N passes from camera space to world space 110 | if(convertp) { 111 | p.z *= -1.0f; 112 | p = unrotate(p, -worldcam_rotation); 113 | p += worldcam_position; 114 | } 115 | if(convertn) { 116 | n.z *= -1.0f; 117 | n = unrotate(n, -worldcam_rotation); 118 | } 119 | if(outputp && !outputready) { 120 | o = p; 121 | outputready = true; 122 | } 123 | if(outputn && !outputready) { 124 | o = n; 125 | outputready = true; 126 | } 127 | 128 | // Keep world space p for later, we need it for facing calc 129 | float3 worldp = p; 130 | 131 | // World space to view space 132 | p -= projector_position; 133 | p = rotate(p, -projector_rotation); 134 | if(outputviewspace && !outputready) { 135 | o = p; 136 | outputready = true; 137 | } 138 | 139 | // Optional clipping 140 | if(zclip) { 141 | if(-p.z < znear || -p.z > zfar) { 142 | o = float3(0.0f); 143 | outputready = true; 144 | } 145 | } 146 | 147 | // Clip behind projector 148 | if(p.z > 0.0f) { 149 | o = float3(0.0f); 150 | outputready = true; 151 | } 152 | 153 | // Facing 154 | float3 v = normalize(projector_position - worldp); 155 | float facingratio = dot(n, v); 156 | if(outputfacingratio && !outputready) { 157 | o = float3(facingratio); 158 | outputready = true; 159 | } 160 | if((facingratio > 0.0f && !frontface) || (facingratio < 0.0f && !backface)) { 161 | o = float3(0.0f); 162 | outputready = true; 163 | } 164 | 165 | // View space to clip space 166 | float4x4 projection_matrix; 167 | float pmd[] = {1.0f/tan(fovx/2.0f), 0.0f, 0.0f, 0.0f, 168 | 0.0f, 1.0f/tan(fovy/2.0f), 0.0f, 0.0f, 169 | 0.0f, 0.0f, 1.0f, 1.0f, 170 | 0.0f, 0.0f, 1.0f, 0.0f}; 171 | projection_matrix.setArray(pmd); 172 | float4 p4 = float4(p.x, p.y, p.z, 0.0f); 173 | p4 = projection_matrix * p4; 174 | if(outputclipspace && !outputready) { 175 | o.x = p4.x; 176 | o.y = p4.y; 177 | o.z = p4.z; 178 | outputready = true; 179 | } 180 | 181 | // Clip space to NDC 182 | p4 /= p4.w; 183 | if(outputndc && !outputready) { 184 | o.x = p4.x; 185 | o.y = p4.y; 186 | o.z = p4.z; 187 | outputready = true; 188 | } 189 | 190 | // NDC to window 191 | p4 /= -2.0f; 192 | p4 += 0.5f; 193 | if(outputuv && !outputready) { 194 | o.x = p4.x; 195 | o.y = p4.y; 196 | o.z = 0.0f; 197 | outputready = true; 198 | } 199 | 200 | // Sample 201 | if(!outputready) { 202 | SampleType(src) s = bilinear(src, p4.x*srcwidth, p4.y*srcheight); 203 | o.x = s.x; 204 | o.y = s.y; 205 | o.z = s.z; 206 | } 207 | 208 | // Output 209 | SampleType(dst) d; 210 | d.x = o.x; 211 | d.y = o.y; 212 | d.z = o.z; 213 | dst() = d; 214 | } 215 | }; 216 | -------------------------------------------------------------------------------- /Ls_GlueP.gizmo: -------------------------------------------------------------------------------- 1 | Group { 2 | name Ls_GlueP 3 | help "GlueP - glues an image to a position pass, by projecting on it.\n\nInputs:\n Image to project\n P, the position pass\n N, an optional normals pass for front/back facing selection\n Projector, the Camera to project from\n CGCamera, optionally the original camera from the CG render\n\nThe second camera input can be used to convert P and N from camera space to world space - many renderers output camera space P and N by default, but we need world space to do this. Even better is a \"world position at frame 1\" or \"P0\" or \"Rest position\" pass, which sticks properly to the surface of animated meshes.\n\nA good way to check that a position pass is suitable to project on is to plug it into a PositionToPoints node along with the beauty pass and check in the 3D view that the points lie within the camera frustrum and are laid out in space like the 3D scene was. For gory details on how to make a good P pass, see the second half of this video about the Flame version: https://www.youtube.com/watch?v=YkgHAMwtmpw\n\nIt works best with 32-bit float P and N passes, rather than 16-bit half." 4 | addUserKnob {20 Ls_GlueP} 5 | addUserKnob {41 useGPUIfAvailable l "Use GPU if available" t "There's not much point turning this on, it's just as fast on the CPU" T BlinkScript1.useGPUIfAvailable} 6 | addUserKnob {26 gap l "" +STARTLINE} 7 | addUserKnob {3 freezeat l "Freeze projector at frame" t "This takes the projector values from a particular frame, to avoid having to hit No Animation on the Camera node"} 8 | freezeat 1 9 | addUserKnob {22 freezehere l Current -STARTLINE T "nuke.thisNode().knob('freezeat').setValue(nuke.frame());"} 10 | addUserKnob {26 gap3 l "" -STARTLINE T "\n\n"} 11 | addUserKnob {41 Ls_GlueP_ConvertPpassfromcameraspace l "Convert P from camera space" T BlinkScript1.Ls_GlueP_ConvertPpassfromcameraspace} 12 | addUserKnob {41 Ls_GlueP_ConvertNpassfromcameraspace l "Convert N from camera space" -STARTLINE T BlinkScript1.Ls_GlueP_ConvertNpassfromcameraspace} 13 | addUserKnob {4 outputselect l Output M {"Glued projection" "Glued ST map" "NDC coords" "Clip space coords" "View space coords" "P converted from camera space" "N converted from camera space" "Facing ratio" ""}} 14 | addUserKnob {26 gap2 l "" -STARTLINE T "\n\n"} 15 | addUserKnob {41 filter l Filter -STARTLINE T STMap1.filter} 16 | addUserKnob {41 Ls_GlueP_Projectonfrontfaces l "Front faces" t "Project on faces which face the projector position. This requires the N input connected." T BlinkScript1.Ls_GlueP_Projectonfrontfaces} 17 | addUserKnob {41 Ls_GlueP_Projectonbackfaces l "Back faces" t "Project on faces which face away from the projector position. This requires the N input connected." -STARTLINE T BlinkScript1.Ls_GlueP_Projectonbackfaces} 18 | addUserKnob {41 Ls_GlueP_Depthclip l "Clip to projector's near/far" t "Adjust the near/far knobs on the Camera node attached to the Projector input to clip the result in depth" T BlinkScript1.Ls_GlueP_Depthclip} 19 | addUserKnob {26 credit l "" +STARTLINE T "\n\nlewis@lewissaunders.com"} 20 | } 21 | Input { 22 | inputs 0 23 | name InputCgCamera 24 | xpos 180 25 | ypos 159 26 | number 4 27 | } 28 | Input { 29 | inputs 0 30 | name InputProjector 31 | xpos 70 32 | ypos 159 33 | number 3 34 | } 35 | Input { 36 | inputs 0 37 | name InputN 38 | xpos -40 39 | ypos 159 40 | number 2 41 | } 42 | Crop { 43 | box {{Crop1.box.x} {Crop1.box.y} {Crop1.box.r} {Crop1.box.t}} 44 | name Crop2 45 | xpos -40 46 | ypos 221 47 | } 48 | Input { 49 | inputs 0 50 | name InputP 51 | xpos -150 52 | ypos 159 53 | number 1 54 | } 55 | Input { 56 | inputs 0 57 | name InputImage 58 | xpos -260 59 | ypos 159 60 | } 61 | set N2578ab00 [stack 0] 62 | BlinkScript { 63 | inputs 3 64 | kernelSourceFile /works/blinks/blinks/Ls_GlueP.blink 65 | ProgramGroup 1 66 | KernelDescription "2 \"Ls_GlueP\" iterate pixelWise 139beda4c8afdcbfbb8184dd1b6236759be6f3e522fd5ae922fb4788f211299a 4 \"src\" Read Random \"position\" Read Point \"normals\" Read Point \"dst\" Write Point 22 \"ConvertPpassfromcameraspace\" Bool 1 AA== \"ConvertNpassfromcameraspace\" Bool 1 AA== \"OutputconvertedP\" Bool 1 AA== \"OutputconvertedN\" Bool 1 AA== \"OriginalCGcameraposition\" Float 3 AAAAAAAAAAAAAAAAAAAAAA== \"OriginalCGcamerarotation\" Float 3 AAAAAAAAAAAAAAAAAAAAAA== \"Projectorposition\" Float 3 AAAAAAAAAAAAAMjCAAAAAA== \"Projectorrotation\" Float 3 AAAAAAAAAAAAAAAAAAAAAA== \"Projectorfocallength\" Float 1 AABIQg== \"Projectorhorizontalaperture\" Float 1 exS+QQ== \"Projectonfrontfaces\" Bool 1 AQ== \"Projectonbackfaces\" Bool 1 AQ== \"Depthclip\" Bool 1 AA== \"Depthclipnear\" Float 1 AAAAAA== \"Depthclipfar\" Float 1 8CN0SQ== \"Outputviewspace\" Bool 1 AA== \"Outputclipspace\" Bool 1 AA== \"OutputNDCspace\" Bool 1 AA== \"OutputUVs\" Bool 1 AA== \"OutputFacingRatio\" Bool 1 AA== \"Srcwidth\" Int 1 gAcAAA== \"Srcheight\" Int 1 OAQAAA== 22 \"convertp\" 1 1 \"convertn\" 1 1 \"outputp\" 1 1 \"outputn\" 1 1 \"worldcam_position\" 3 1 \"worldcam_rotation\" 3 1 \"projector_position\" 3 1 \"projector_rotation\" 3 1 \"projector_focal\" 1 1 \"projector_haperture\" 1 1 \"frontface\" 1 1 \"backface\" 1 1 \"zclip\" 1 1 \"znear\" 1 1 \"zfar\" 1 1 \"outputviewspace\" 1 1 \"outputclipspace\" 1 1 \"outputndc\" 1 1 \"outputuv\" 1 1 \"outputfacingratio\" 1 1 \"srcwidth\" 1 1 \"srcheight\" 1 1 4 \"aspect\" Float 1 1 AAAAAA== \"vaperture\" Float 1 1 AAAAAA== \"fovy\" Float 1 1 AAAAAA== \"fovx\" Float 1 1 AAAAAA==" 67 | kernelSource "// GlueP: project onto a position pass\n// lewis@lewissaunders.com\n// TODO:\n// o rearrange the output selection logic, translating\n// the return statements into setting a flag was stupid\n// o I wonder what happens when inputs are different sizes\n\nkernel Ls_GlueP : ImageComputationKernel \{\n Image src;\n Image position;\n Image normals;\n Image dst;\n\n param:\n bool convertp, convertn, outputp, outputn;\n float3 worldcam_position, worldcam_rotation;\n float3 projector_position, projector_rotation;\n float projector_focal, projector_haperture;\n bool frontface, backface, zclip;\n float znear, zfar;\n bool outputviewspace, outputclipspace, outputndc, outputuv, outputfacingratio;\n int srcwidth, srcheight;\n\n local:\n float aspect, vaperture, fovy, fovx;\n\n void define() \{\n defineParam(convertp, \"ConvertPpassfromcameraspace\", false);\n defineParam(convertn, \"ConvertNpassfromcameraspace\", false);\n defineParam(outputp, \"OutputconvertedP\", false);\n defineParam(outputn, \"OutputconvertedN\", false);\n defineParam(worldcam_position, \"OriginalCGcameraposition\", float3(0.0, 0.0, 0.0));\n defineParam(worldcam_rotation, \"OriginalCGcamerarotation\", float3(0.0, 0.0, 0.0));\n defineParam(projector_position, \"Projectorposition\", float3(0.0, 0.0, -100.0));\n defineParam(projector_rotation, \"Projectorrotation\", float3(0.0, 0.0, 0.0));\n defineParam(projector_focal, \"Projectorfocallength\", 50.0f);\n defineParam(projector_haperture, \"Projectorhorizontalaperture\", 23.76f);\n defineParam(zclip, \"Depthclip\", false);\n defineParam(frontface, \"Projectonfrontfaces\", true);\n defineParam(backface, \"Projectonbackfaces\", true);\n defineParam(znear, \"Depthclipnear\", 0.0f);\n defineParam(zfar, \"Depthclipfar\", 999999.0f);\n defineParam(outputviewspace, \"Outputviewspace\", false);\n defineParam(outputclipspace, \"Outputclipspace\", false);\n defineParam(outputndc, \"OutputNDCspace\", false);\n defineParam(outputuv, \"OutputUVs\", false);\n defineParam(outputfacingratio, \"OutputFacingRatio\", false);\n defineParam(srcwidth, \"Srcwidth\", 1920);\n defineParam(srcheight, \"Srcheight\", 1080);\n \}\n\n void init() \{\n aspect = max(float(srcwidth), 1.0f) / max(float(srcheight), 1.0f);\n vaperture = projector_haperture / aspect;\n fovy = 2.0f * atan(vaperture / (2.0f * projector_focal));\n fovx = 2.0f * atan(projector_haperture / (2.0f * projector_focal));\n \}\n\n float deg2rad(float angle) \{\n return(angle/(180.0f/PI));\n \}\n\n // Rotates about the origin in ZXY order\n float3 rotate(float3 p, float3 angles) \{\n float x = deg2rad(angles.x);\n float y = deg2rad(angles.y);\n float z = deg2rad(angles.z);\n\n float3x3 rx, ry, rz;\n float rxd\[] = \{1.0, 0.0, 0.0, 0.0, cos(x), -sin(x), 0.0, sin(x), cos(x)\};\n float ryd\[] = \{cos(y), 0.0, sin(y), 0.0, 1.0, 0.0, -sin(y), 0.0, cos(y)\};\n float rzd\[] = \{cos(z), -sin(z), 0.0, sin(z), cos(z), 0.0, 0.0, 0.0, 1.0\};\n rx.setArray(rxd);\n ry.setArray(ryd);\n rz.setArray(rzd);\n\n float3x3 r = rz * rx * ry;\n return(r * p);\n \}\n\n // Un-rotates about the origin in ZXY order\n float3 unrotate(float3 p, float3 angles) \{\n float x = deg2rad(angles.x);\n float y = deg2rad(angles.y);\n float z = deg2rad(angles.z);\n\n float3x3 rx, ry, rz;\n float rxd\[] = \{1.0f, 0.0f, 0.0f, 0.0f, cos(x), sin(x), 0.0f, -sin(x), cos(x)\};\n float ryd\[] = \{cos(y), 0.0f, -sin(y), 0.0f, 1.0f, 0.0f, sin(y), 0.0f, cos(y)\};\n float rzd\[] = \{cos(z), sin(z), 0.0f, -sin(z), cos(z), 0.0f, 0.0f, 0.0f, 1.0f\};\n rx.setArray(rxd);\n ry.setArray(ryd);\n rz.setArray(rzd);\n\n float3x3 r = ry * rx * rz;\n return(r * p);\n \}\n\n void process(int2 pos) \{\n SampleType(position) prgba = position();\n float3 p = float3(prgba.x, prgba.y, prgba.z);\n\n SampleType(normals) nrgba = normals();\n float3 n = float3(nrgba.x, nrgba.y, nrgba.z);\n\n bool outputready = false;\n float3 o;\n\n // Optionally, convert P and N passes from camera space to world space\n if(convertp) \{\n p.z *= -1.0f;\n p = unrotate(p, -worldcam_rotation);\n p += worldcam_position;\n \}\n if(convertn) \{\n n.z *= -1.0f;\n n = unrotate(n, -worldcam_rotation);\n \}\n if(outputp && !outputready) \{\n o = p;\n outputready = true;\t\t\n \}\n if(outputn && !outputready) \{\n o = n;\n outputready = true;\t\t\n \}\n\n // Keep world space p for later, we need it for facing calc\n float3 worldp = p;\n\n // World space to view space\n p -= projector_position;\n p = rotate(p, -projector_rotation);\n if(outputviewspace && !outputready) \{\n o = p;\n outputready = true;\n \}\n\n // Optional clipping\n if(zclip) \{\n if(-p.z < znear || -p.z > zfar) \{\n o = float3(0.0f);\n outputready = true;\n \}\n \}\n\n // Clip behind projector\n if(p.z > 0.0f) \{\n o = float3(0.0f);\n outputready = true;\n \}\n\n // Facing\n float3 v = normalize(projector_position - worldp);\n float facingratio = dot(n, v);\n if(outputfacingratio && !outputready) \{\n o = float3(facingratio);\n outputready = true;\n \}\n if((facingratio > 0.0f && !frontface) || (facingratio < 0.0f && !backface)) \{\n o = float3(0.0f);\n outputready = true;\n \}\n\n // View space to clip space\n float4x4 projection_matrix;\n float pmd\[] = \{1.0f/tan(fovx/2.0f), 0.0f, 0.0f, 0.0f,\n\t\t0.0f, 1.0f/tan(fovy/2.0f), 0.0f, 0.0f,\n\t\t0.0f, 0.0f, 1.0f, 1.0f,\n\t\t0.0f, 0.0f, 1.0f, 0.0f\};\n projection_matrix.setArray(pmd);\n float4 p4 = float4(p.x, p.y, p.z, 0.0f);\n p4 = projection_matrix * p4;\n if(outputclipspace && !outputready) \{\n o.x = p4.x;\n o.y = p4.y;\n o.z = p4.z;\n outputready = true;\n \}\n\n // Clip space to NDC\n p4 /= p4.w;\n if(outputndc && !outputready) \{\n o.x = p4.x;\n o.y = p4.y;\n o.z = p4.z;\n outputready = true;\n \}\n\n // NDC to window\n p4 /= -2.0f;\n p4 += 0.5f;\n if(outputuv && !outputready) \{\n o.x = p4.x;\n o.y = p4.y;\n o.z = 0.0f;\n outputready = true;\n \}\n\n // Sample\n if(!outputready) \{\n SampleType(src) s = bilinear(src, p4.x*srcwidth, p4.y*srcheight);\n o.x = s.x;\n o.y = s.y;\n o.z = s.z;\n \}\n\n // Output\n SampleType(dst) d;\n d.x = o.x;\n d.y = o.y;\n d.z = o.z;\n dst() = d;\n \}\n\};\n" 68 | useGPUIfAvailable false 69 | rebuild "" 70 | Ls_GlueP_OutputconvertedP {{"parent.outputselect == 5"}} 71 | Ls_GlueP_OutputconvertedN {{"parent.outputselect == 6"}} 72 | Ls_GlueP_OriginalCGcameraposition {{"\[exists parent.input4] ? parent.input4.translate.x : 0.0"} {"\[exists parent.input4] ? parent.input4.translate.y : 0.0"} {"\[exists parent.input4] ? parent.input4.translate.z : 0.0"}} 73 | Ls_GlueP_OriginalCGcamerarotation {{"\[exists parent.input4] ? parent.input4.rotate.x : 0.0"} {"\[exists parent.input4] ? parent.input4.rotate.y : 0.0"} {"\[exists parent.input4] ? parent.input4.rotate.z : 0.0"}} 74 | Ls_GlueP_Projectorposition {{parent.input3.translate.x(parent.freezeat)} {parent.input3.translate.y(parent.freezeat)} {parent.input3.translate.z(parent.freezeat)}} 75 | Ls_GlueP_Projectorrotation {{parent.input3.rotate.x(parent.freezeat)} {parent.input3.rotate.y(parent.freezeat)} {parent.input3.rotate.z(parent.freezeat)}} 76 | Ls_GlueP_Projectorfocallength {{parent.input3.focal(parent.freezeat)}} 77 | Ls_GlueP_Projectorhorizontalaperture {{parent.input3.haperture(parent.freezeat)}} 78 | Ls_GlueP_Depthclipnear {{parent.input3.near(parent.freezeat)}} 79 | Ls_GlueP_Depthclipfar {{parent.input3.far(parent.freezeat)}} 80 | Ls_GlueP_Outputviewspace {{"parent.outputselect == 4"}} 81 | Ls_GlueP_Outputclipspace {{"parent.outputselect == 3"}} 82 | Ls_GlueP_OutputNDCspace {{"parent.outputselect == 2"}} 83 | Ls_GlueP_OutputUVs {{"parent.outputselect == 0 | parent.outputselect == 1"}} 84 | Ls_GlueP_OutputFacingRatio {{"parent.outputselect == 7"}} 85 | Ls_GlueP_Srcwidth {{width}} 86 | Ls_GlueP_Srcheight {{height}} 87 | name BlinkScript1 88 | xpos -150 89 | ypos 302 90 | } 91 | Crop { 92 | box {0 0 {width} {height}} 93 | crop false 94 | name Crop1 95 | xpos -150 96 | ypos 334 97 | } 98 | set N257a7700 [stack 0] 99 | push $N2578ab00 100 | STMap { 101 | inputs 2 102 | uv rgb 103 | name STMap1 104 | xpos -260 105 | ypos 371 106 | } 107 | push $N257a7700 108 | Switch { 109 | inputs 2 110 | which {{"parent.outputselect == 0 ? 1 : 0"}} 111 | name Switch1 112 | xpos -150 113 | ypos 452 114 | } 115 | Output { 116 | name Output1 117 | xpos -150 118 | ypos 526 119 | } 120 | StickyNote { 121 | inputs 0 122 | name StickyNote1 123 | label "this crop stops it crashing... idk" 124 | note_font "Verdana Italic Italic Italic Italic" 125 | xpos -52 126 | ypos 332 127 | } 128 | end_group 129 | -------------------------------------------------------------------------------- /Ls_Length.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Length : ImageComputationKernel 2 | { 3 | Image src; 4 | Image dst; 5 | 6 | void process() { 7 | dst() = length(src()); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /Ls_Normalize.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Normalize : ImageComputationKernel 2 | { 3 | Image src; 4 | Image dst; 5 | 6 | void process() { 7 | dst() = normalize(src()); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /Ls_PtoDepth.blink: -------------------------------------------------------------------------------- 1 | kernel PtoDepth : ImageComputationKernel { 2 | Image src; 3 | Image dst; 4 | 5 | param: 6 | float3 campos; 7 | 8 | void define() { 9 | defineParam(campos, "Camera position", float3(0.0, 0.0, 0.0)); 10 | } 11 | 12 | void process() { 13 | SampleType(src) input = src(); 14 | float3 p = float3(input.x, input.y, input.z); 15 | dst() = float4(length(p - campos)); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /Ls_Reflect.blink: -------------------------------------------------------------------------------- 1 | // Reflect: reflect from a normals pass 2 | // lewis@lewissaunders.com 3 | // TODO: 4 | // o obvs get P in here and do equiv of GLSL reflect() 5 | // o fold all the space conversions and gizmo stuff from 6 | // GlueP into this 7 | 8 | kernel Ls_Reflect : ImageComputationKernel { 9 | Image normals; 10 | Image dst; 11 | 12 | param: 13 | float3 env_rotate; 14 | 15 | void define() { 16 | defineParam(env_rotate, "rotate", float3(0.0, 0.0, 0.0)); 17 | } 18 | 19 | float deg2rad(float angle) { 20 | return(angle/(180.0f/PI)); 21 | } 22 | 23 | // Rotates about the origin in ZXY order 24 | float3 rotate(float3 p, float3 angles) { 25 | float x = deg2rad(angles.x); 26 | float y = deg2rad(angles.y); 27 | float z = deg2rad(angles.z); 28 | 29 | float3x3 rx, ry, rz; 30 | float rxd[] = {1.0, 0.0, 0.0, 0.0, cos(x), -sin(x), 0.0, sin(x), cos(x)}; 31 | float ryd[] = {cos(y), 0.0, sin(y), 0.0, 1.0, 0.0, -sin(y), 0.0, cos(y)}; 32 | float rzd[] = {cos(z), -sin(z), 0.0, sin(z), cos(z), 0.0, 0.0, 0.0, 1.0}; 33 | rx.setArray(rxd); 34 | ry.setArray(ryd); 35 | rz.setArray(rzd); 36 | 37 | float3x3 r = rz * rx * ry; 38 | return(r * p); 39 | } 40 | 41 | void process(int2 pos) { 42 | SampleType(normals) nrgba = normals(); 43 | float3 n = float3(nrgba.x, nrgba.y, nrgba.z); 44 | 45 | // Optionally rotate the normal 46 | n = rotate(n, env_rotate); 47 | 48 | // Convert n to latlong spherical coordinates 49 | float lat = (asin(n.y) / (1.0 * PI)) + 0.5; 50 | float lon = (atan2(n.z, n.x) / (2.0 * PI)) + 0.75; 51 | 52 | lat -= floor(lat); 53 | lon -= floor(lon); 54 | 55 | SampleType(dst) d; 56 | d.x = lon; 57 | d.y = lat; 58 | d.z = 0.0f; 59 | dst() = d; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /Ls_Rotate.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Rotate : ImageComputationKernel 2 | { 3 | Image src; 4 | Image dst; 5 | 6 | param: 7 | float3 angles; 8 | 9 | void define() { 10 | defineParam(angles, "angles", float3(0.0, 0.0, 0.0)); 11 | } 12 | 13 | float deg2rad(float angle) { 14 | return(angle/(180.0f/PI)); 15 | } 16 | 17 | // Rotates about the origin in ZXY order 18 | float3 rotate(float3 p, float3 angles) { 19 | float x = deg2rad(angles.x); 20 | float y = deg2rad(angles.y); 21 | float z = deg2rad(angles.z); 22 | 23 | float3x3 rx, ry, rz; 24 | float rxd[] = {1.0, 0.0, 0.0, 0.0, cos(x), -sin(x), 0.0, sin(x), cos(x)}; 25 | float ryd[] = {cos(y), 0.0, sin(y), 0.0, 1.0, 0.0, -sin(y), 0.0, cos(y)}; 26 | float rzd[] = {cos(z), -sin(z), 0.0, sin(z), cos(z), 0.0, 0.0, 0.0, 1.0}; 27 | rx.setArray(rxd); 28 | ry.setArray(ryd); 29 | rz.setArray(rzd); 30 | 31 | float3x3 r = rz * rx * ry; 32 | return(r * p); 33 | } 34 | 35 | void process() { 36 | SampleType(src) s = src(); 37 | float3 s3; 38 | s3.x = s.x; 39 | s3.y = s.y; 40 | s3.z = s.z; 41 | 42 | float3 rotated = rotate(s3, angles); 43 | 44 | SampleType(dst) d; 45 | d.x = rotated.x; 46 | d.y = rotated.y; 47 | d.z = rotated.z; 48 | dst() = d; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Ls_Splineblur.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Splineblur : ImageComputationKernel { 2 | Image src; 3 | Image map; 4 | Image dst; 5 | 6 | param: 7 | float steplen; 8 | int stepss; 9 | 10 | local: 11 | float realsteplen; 12 | 13 | void define() { 14 | defineParam(steplen, "Step length", 1.0f); 15 | defineParam(stepss, "Steps", 32); 16 | } 17 | 18 | void init() { 19 | realsteplen = steplen * 100.0; 20 | } 21 | 22 | void process(int2 pos) { 23 | float2 where; 24 | where.x = float(pos.x); 25 | where.y = float(pos.y); 26 | 27 | SampleType(src) accum(0); 28 | 29 | for(int i = 0; i < stepss; i++) { 30 | SampleType(map) mapdir = bilinear(map, where.x, where.y); 31 | where.x += mapdir.x * realsteplen; 32 | where.y += mapdir.y * realsteplen; 33 | accum += bilinear(src, where.x, where.y); 34 | } 35 | dst() = accum/float(stepss); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /Ls_Vignette.blink: -------------------------------------------------------------------------------- 1 | kernel Ls_Vignette : ImageComputationKernel { 2 | Image src; 3 | Image dst; 4 | 5 | param: 6 | float2 centre; 7 | float aspect, size, mixx; 8 | 9 | void define() { 10 | defineParam(centre, "Centre", float2(960.0f, 540.0f)); 11 | defineParam(aspect, "Aspect", 1.0f); 12 | defineParam(size, "Size", 1280.0f); 13 | defineParam(mixx, "Mix", 1.0f); 14 | } 15 | 16 | float mixxx(float from, float to, float factorr) { 17 | return factorr * to + (1.0 - factorr) * from; 18 | } 19 | 20 | void process(int2 pos) { 21 | float2 where; 22 | where.x = float(pos.x); 23 | where.y = float(pos.y); 24 | 25 | float2 fromcentre = where - centre; 26 | fromcentre.y *= aspect; 27 | float dist = length(fromcentre); 28 | float x = dist / size; 29 | x = min(x, 3.1415926535f); 30 | float vignette = pow(cos(x), 4.0f); 31 | float mixedvignette = mixxx(1.0, vignette, mixx); 32 | 33 | SampleType(src) s = src(); 34 | s *= mixedvignette; 35 | dst() = s; 36 | } 37 | }; 38 | --------------------------------------------------------------------------------