local EnvBackgroundScript = {} local mInputC local mInputT local mInputB local mInputP local mInputR local mInputS local mInputI local mInputZ local OutputT local OutputR function EnvBackgroundScript.onInit(self, graph) graph:updateProperties({name = "Visible Background"}) -- create input linkers local inputs = graph:setInputLinkers { { type = octane.PT_CAMERA, label = "Camera-in", fromNodeType = octane.NT_OUT_CAMERA, fromPinId = octane.P_INPUT }, { type = octane.PT_TEXTURE, label = "Background Image", fromNodeType = octane.NT_OUT_TEXTURE, fromPinId = octane.P_INPUT }, { type = octane.PT_ENUM, label = "Border mode", defaultNodeType = octane.NT_ENUM, enum = {"Wrap around", "Black color", "White color", "Clamp value", "Mirror"}, defaultValue = 1, }, { type = octane.PT_BOOL, label = "Backplate", defaultNodeType = octane.NT_BOOL, defaultValue = true, }, { type = octane.PT_BOOL, label = "Reflections", defaultNodeType = octane.NT_BOOL, defaultValue = true, }, { type = octane.PT_BOOL, label = "Refractions", defaultNodeType = octane.NT_BOOL, defaultValue = true, }, { type = octane.PT_BOOL, label = "Importance sampling", defaultNodeType = octane.NT_BOOL, defaultValue = true, }, { type = octane.PT_INT, label = "Zoom factor %", defaultNodeType = octane.NT_INT, defaultValue = 10, sliderBounds = {0, 1000}, steps = 25, logarithmic = true, } } mInputC = inputs[1] mInputT = inputs[2] mInputB = inputs[3] mInputP = inputs[4] mInputR = inputs[5] mInputS = inputs[6] mInputI = inputs[7] mInputZ = inputs[8] -- create output linkers local outputs = graph:setOutputLinkers { { type = octane.PT_ENVIRONMENT, label = "VisibleBackground-out", defaultNodeType=octane.NT_OUT_ENVIRONMENT, }, { type = octane.PT_FILM_SETTINGS, label = "Resolution-out", defaultNodeType=octane.NT_OUT_FILM_SETTINGS, } } OutputT = outputs[1] OutputR = outputs[2] -- create nodes Tex = octane.node.create { type = octane.NT_TEX_IMAGE, name = "Background", graphOwner = graph } Prj = octane.node.create { type = octane.NT_PROJ_PERSPECTIVE, name = "Perspective", graphOwner = graph } env = octane.node.create { type = octane.NT_ENV_TEXTURE, name = "Visible Environment", graphOwner = graph } Res = octane.node.create { type = octane.NT_FILM_SETTINGS, name = "Film settings", graphOwner = graph } end function EnvBackgroundScript.onEvaluate(self, graph) infoC = mInputC:getInputNode(octane.P_INPUT) infoT = mInputT:getInputNode(octane.P_INPUT) bord = mInputB:getInputNode(octane.P_INPUT) plate = mInputP:getInputNode(octane.P_INPUT) refl = mInputR:getInputNode(octane.P_INPUT) spec = mInputS:getInputNode(octane.P_INPUT) imps = mInputI:getInputNode(octane.P_INPUT) zoom = mInputZ:getInputNode(octane.P_INPUT) if infoC ~= nil and infoT ~= nil then local inCam = infoC local inTex = infoT local pos = inCam:getPinValue(octane.P_POSITION) local target = inCam:getPinValue(octane.P_TARGET) local up = octane.vec.normalized(inCam:getPinValue(octane.P_UP)) Z = octane.vec.normalized(octane.vec.sub(target, pos)) X = octane.vec.normalized(octane.vec.cross(up, Z)) Y = octane.vec.normalized(octane.vec.cross(Z, X)) matrix = { {X[1], Y[1], Z[1], pos[1]}, {X[2], Y[2], Z[2], pos[2]}, {X[3], Y[3], Z[3], pos[3]}, } Tex:connectTo(octane.P_PROJECTION, Prj) Tex:setAttribute(octane.A_FILENAME, inTex:getAttribute(octane.A_FILENAME), true) Tex:setPinValue(octane.P_BORDER_MODE, bord:getAttribute(octane.A_VALUE), true) env:setPinValue(octane.P_VISIBLE_ENVIRONMENT_BACKPLATE, plate:getAttribute(octane.A_VALUE), true) env:setPinValue(octane.P_VISIBLE_ENVIRONMENT_REFLECTIONS, refl:getAttribute(octane.A_VALUE), true) env:setPinValue(octane.P_VISIBLE_ENVIRONMENT_REFRACTIONS, spec:getAttribute(octane.A_VALUE), true) env:setPinValue(octane.P_IMPORTANCE_SAMPLING, imps:getAttribute(octane.A_VALUE), true) resolution = Tex:getAttribute(octane.A_SIZE) zoomF = zoom:getAttribute(octane.A_VALUE) local fov = inCam:getPinValue(octane.P_FOV) w = math.tan(math.rad(fov / 2)) local shift = inCam:getPinValue(octane.P_LENS_SHIFT) local h = w * resolution[2] / resolution[1] matrix = octane.matrix.mul(matrix, octane.matrix.makeScale{w, h, 1}) --matrix = octane.matrix.mul(matrix, octane.matrix.makeTranslation{0, 0, 0}) matrix = octane.matrix.transpose(matrix) matrix = octane.matrix.transpose(matrix) uvmatrix = octane.matrix.makeTranslation{shift[1], shift[2], 0} Tex:setPinValue(octane.P_TRANSFORM, uvmatrix) Prj:setPinValue(octane.P_TRANSFORM, matrix) env:connectTo(octane.P_TEXTURE, Tex) local res = Res:setPinValue(octane.P_RESOLUTION, {resolution[1]*zoomF[1]/100, resolution[2]*zoomF[1]/100}, true) OutputT:connectTo(octane.P_INPUT, env) OutputR:connectTo(octane.P_INPUT, Res) EnvBackgroundScript:setEvaluateTimeChanges(true) end end return EnvBackgroundScript