You can also add "complex logic" to your computed columns via CASE expressions. This might offer performance benefits over a UDF.
Just as a really simple example:
CREATE TABLE test (
i INT NOT NULL PRIMARY KEY,
j INT NULL,
k AS (CASE
WHEN j < 0 THEN i
WHEN j IS NULL THEN 0
ELSE (i * j)
END)
)
GO
INSERT INTO test (i, j)
SELECT 0, 1
UNION SELECT 1, 1
UNION SELECT 2, 3
UNION SELECT 4, NULL
UNION SELECT 10, -1
GO
SELECT *
FROM test
In the sample, k is computed based on the value of j. If j is negative then k = i, if j is NULL then k = 0, otherwise k = i * j. Really simple and not really all that useful of an example, but it's a pretty powerful concept.
You can also add an index to a computed column with a CASE expression:
CREATE INDEX IX_test ON test(k)
GO