Animação para Roblox

Como fazer reflexo parecido com o do Blender no Roblox Studio

Você sobe o Reflectance para 1 esperando ver a parede refletida na esfera e só aparece nuvem, porque o Roblox reflete o skybox e mais nada. Dá para chegar perto do Blender empilhando três camadas: Reflectance, SurfaceAppearance com os mapas exportados do Blender e um cenário espelhado embaixo do piso.

por Gustavo Cantino10 min de leituraIniciante

Rascunho assistido por IA, revisado, testado e editado por um humano antes de publicar. Ver Política Editorial. · Revisado por Gustavo Cantino, 15/09/2026 Política Editorial

Placa tipográfica com a categoria Animação para Roblox em destaque, o nível iniciante abaixo, e um campo de barras verticais verde-limão sobre fundo escuro.

Reflexo igual ao do Blender não existe no Roblox, e não é opção escondida em menu nenhum: é diferença de motor. No Blender, o Cycles traça o caminho da luz raio por raio e o EEVEE usa screen space reflection — os dois calculam de verdade o que está em volta do objeto. O renderizador do Roblox precisa rodar em celular Android de entrada, então ele não faz nem uma coisa nem outra: o que ele chama de reflexo é, na maior parte dos casos, uma consulta ao skybox (a caixa de céu que envolve o mapa inteiro).

O Roblox não tem ray tracing — e o que ele tem no lugar

A consequência prática é onde você perde a tarde. Você clica numa esfera, acha a propriedade Reflectance, arrasta de 0 para 1 esperando ver o chão e a parede aparecerem nela — e vê nuvem. Fecha a esfera dentro de uma sala sem janela: continua nuvem. Ela não sabe que existe parede ao lado, só sabe que existe céu. Aí começa a tentativa de compensar: troca o material para Neon, troca para Glass, sobe Reflectance de tudo para 1, e o mapa inteiro fica com aquela cara de plástico cromado.

Antes de qualquer coisa, dois painéis. O Explorer é o painel da direita que lista todos os objetos do jogo em árvore; o Properties fica logo abaixo dele e mostra as propriedades do objeto que você selecionou. Se algum dos dois não estiver aparecendo, abra a aba View na faixa de cima do Studio e clique em Explorer e em Properties. Todo o resto deste texto depende desses dois painéis abertos.

Outra coisa que economiza meia hora: a qualidade do sistema de iluminação fica em Lighting, um objeto que já vem dentro do jogo e aparece no Explorer. Selecione ele e, no Properties, procure a propriedade Technology. Ela tem um menu com Voxel, ShadowMap e Future. Reflexo decente só acontece em Future. E ela só muda por esse menu — script não muda:

Script em ServerScriptService — NÃO faça isso
-- Não funciona. Technology é alterado só pelo painel Properties, no Studio.
game:GetService("Lighting").Technology = Enum.Technology.Future

Com o Lighting ainda selecionado, procure também EnvironmentSpecularScale e EnvironmentDiffuseScale. São dois números de 0 a 1. Se o Specular estiver em 0, o céu não ilumina nem reflete em nada, e você pode mexer em Reflectance o dia inteiro sem ver diferença. Coloque os dois em 1 para testar.

As três camadas de reflexo, da mais barata para a mais cara

Camada 1 — Reflectance (leva 2 minutos e custa nada de performance). Clique numa Part no Explorer, vá no Properties e ache Reflectance. É um número de 0 a 1: 0 é fosco, 1 é espelho de céu. Para metal escovado, 0,15 a 0,3 já dá o brilho certo. Acima de 0,5 o objeto vira bola de discoteca. Essa camada só reflete o skybox, então ela depende de existir um Sky dentro do Lighting. Confira no Explorer: se não houver um objeto chamado Sky ali, passe o mouse sobre Lighting, clique no sinal de mais que aparece do lado e insira um Sky. Um skybox com nuvem, montanha e horizonte dá um reflexo muito mais convincente do que o céu azul liso padrão — e é literalmente a imagem que vai aparecer no seu "metal".

Regra que vale ouro para ambiente interno: quanto mais fechado o cenário, mais baixo o Reflectance. Uma sala sem janela com Reflectance 0,4 fica errada porque o Roblox vai refletir céu atravessando o teto. Em ambiente interno, fique entre 0,05 e 0,12.

Camada 2 — SurfaceAppearance, que é onde o seu material do Blender entra. Essa é a ponte real entre os dois programas. No Blender, o seu material provavelmente é um Principled BSDF com entradas Base Color, Metallic, Roughness e Normal. O Roblox tem um objeto que aceita exatamente esses quatro mapas: o SurfaceAppearance, que só funciona dentro de um MeshPart (a Part que veio de um modelo importado, não a caixa comum).

O caminho é este. No Blender, exporte ou baixe as quatro texturas em PNG. O Roblox aceita imagem de até 1024x1024 — mande maior e ela é reduzida, então já exporte nesse tamanho para você ver o resultado final e não uma surpresa. No Studio, abra View > Asset Manager, clique em Images, depois em Add Images, e selecione os arquivos. Eles entram na fila de moderação e só aparecem depois de aprovados; enquanto isso a textura fica em branco, e isso não é bug.

Com o MeshPart selecionado no Explorer, insira um SurfaceAppearance dentro dele (sinal de mais ao lado do nome do MeshPart). No Properties do SurfaceAppearance você vai ver ColorMap, MetalnessMap, RoughnessMap e NormalMap. Cole o ID de cada imagem no campo correspondente: Base Color vira ColorMap, Metallic vira MetalnessMap, Roughness vira RoughnessMap, Normal vira NormalMap. Campo deixado vazio é tratado como valor neutro (não metálico, bem rugoso). O RoughnessMap é uma imagem em tons de cinza onde preto é espelho e branco é fosco — e é ele que faz o chão de metal molhado parecer molhado. O MetalnessMap é o contrário do que parece: branco é metal, preto não é metal. Meio-termo cinza nos dois costuma ficar mais crível do que extremo.

Camada 3 — duplicar geometria, que é como se faz espelho e chão reflexivo de verdade. Nenhuma das duas camadas anteriores reflete objeto nenhum do seu mapa. Se você quer ver o personagem refletido no piso, ou uma poça refletindo o prédio, o jeito que funciona desde sempre é fazer uma cópia do cenário de cabeça para baixo, embaixo do piso, e deixar o piso translúcido por cima. O olho aceita na hora. Manualmente dá para fazer duplicando o modelo, girando 180 graus e descendo — mas errar o eixo em meio stud já estraga o efeito, e é por isso que existe o script abaixo.

O script que monta o reflexo de chão

O artefato faz a camada 3 inteira em um clique. Ele procura um Model no Workspace com o nome que você escolher, clona, espelha cada Part em torno de uma altura Y que você informa, tira tudo que não é visual (script, som, luz, ProximityPrompt), deixa as peças translúcidas e desliga colisão, sombra e raycast na cópia.

Para usar: no Explorer, selecione as peças do cenário que você quer ver refletidas, clique com o botão direito e escolha Group para virarem um Model; renomeie esse Model para Cenario. Depois, passe o mouse sobre ServerScriptService no Explorer (é uma pasta que já existe na árvore), clique no sinal de mais e insira um Script. Apague o conteúdo dele e cole o artefato.

Falta um número só: ALTURA_DO_PISO. É o Y da face de cima do piso, não o centro da Part. Selecione o piso, olhe Position e Size no Properties: se a Position em Y é 0,5 e o Size em Y é 1, a face de cima está em 1. Coloque 1 ali.

Aperte Play (F5). O script cria um Model chamado ReflexoFalso no Workspace. Ajuste TRANSPARENCIA_MINIMA — 0,55 é um começo razoável; mais perto de 0,7 fica reflexo discreto de piso polido. Falta o piso por cima: uma Part fina cobrindo tudo, Transparency por volta de 0,5, Reflectance 0,1 e cor escura. Sem essa Part por cima, o efeito parece um mapa duplicado bugado, não um reflexo.

Para deixar o reflexo salvo no lugar de gerar toda vez: com o jogo rodando, clique em ReflexoFalso no Explorer, Ctrl+C, aperte Stop e Ctrl+V. A área de transferência sobrevive ao Stop e a cópia fica permanente no seu mapa.

O erro que dobra o mapa e mata o FPS no celular

O erro caro é apontar o script para o mapa inteiro. Um cenário de 2.000 parts espelhado vira 4.000 parts para a GPU desenhar, e como a cópia é translúcida, cada uma delas custa mais caro do que uma peça opaca — transparência obriga o renderizador a desenhar em ordem, uma por uma. Em PC você talvez nem perceba; no celular o jogo engasga e o jogador sai. Por isso o artefato tem LIMITE_DE_PARTS em 400 e simplesmente se recusa a rodar acima disso, imprimindo o aviso no Output (abra em View > Output).

A saída não é aumentar o limite: é espelhar menos. Coloque dentro do Model Cenario só o que fica realmente visível no reflexo — as paredes e objetos próximos daquele piso, não o mapa inteiro nem o telhado. Reflexo de chão só mostra os primeiros metros ao redor mesmo.

O segundo erro, mais chato de descobrir: esquecer de desligar CanCollide e CanQuery na cópia. Se você duplicar na mão com Ctrl+D em vez de usar o script, a cópia espelhada continua sólida, e o jogador cai no chão e bate numa parede invisível embaixo do piso; pior, raycast de arma e de ferramenta acerta o reflexo e o tiro morre no nada. O script já força CanCollide = false, CanQuery = false, CanTouch = false e CastShadow = false em toda peça clonada.

Terceiro: modelo com texto ou detalhe assimétrico. O espelhamento inverte posição e rotação, mas não inverte a malha em si — uma placa escrita "LOJA" vai aparecer no reflexo virada, e um mesh com detalhe só de um lado vai aparecer no lado trocado. Para placa e letreiro, tire do Model Cenario e aceite que aquele pedaço não reflete.

O que medir depois

Meça a contagem de peças antes e depois. Abra View > Command Bar (a barrinha de digitar comando, geralmente na parte de baixo) e rode:

Command Bar (View > Command Bar)
print(#workspace:GetDescendants())

Anote o número antes de gerar o reflexo e depois. Se a diferença passou de umas poucas centenas, você espelhou cenário demais e é hora de tirar coisa do Model Cenario.

Depois, teste onde dói: na aba Test existe o emulador de dispositivo (Device). Escolha um celular, aperte Play e ande pelo piso reflexivo. Se a câmera arrastar quando você olha para baixo, o culpado é a transparência somada — suba TRANSPARENCIA_MINIMA para 0,7 ou corte metade das peças espelhadas.

Por último, compare com a referência do Blender lado a lado, uma imagem em cada tela. Quase sempre o que falta não é reflexo: é o RoughnessMap. Objeto com rugosidade uniforme parece brinquedo de plástico em qualquer motor, inclusive no Blender. Variar a rugosidade na textura resolve mais do que subir Reflectance.

Artefato pronto pra usar

Script em ServerScriptService
lua
--!strict
-- Reflexo falso de chao: duplica um Model, espelha embaixo do piso e deixa translucido.
-- Onde mora: Script (RunContext Legacy) dentro de ServerScriptService.

local Workspace = game:GetService("Workspace")

-- ========= CONFIGURACAO =========
local NOME_DO_MODELO: string = "Cenario"    -- nome exato do Model no Workspace
local ALTURA_DO_PISO: number = 0            -- Y da FACE DE CIMA do piso
local TRANSPARENCIA_MINIMA: number = 0.55   -- 0 = opaco, 1 = invisivel
local LIMITE_DE_PARTS: number = 400         -- acima disso o script avisa e nao duplica
-- ================================

-- Espelha um CFrame em torno de um plano horizontal (Y = planoY).
-- Inverte a posicao em Y e reflete a rotacao (M * R * M), que continua sendo
-- uma rotacao valida: o Roblox nao aceita escala negativa dentro de um CFrame.
local function espelharCFrame(cf: CFrame, planoY: number): CFrame
	local x, y, z, r00, r01, r02, r10, r11, r12, r20, r21, r22 = cf:GetComponents()
	return CFrame.new(
		x, (2 * planoY) - y, z,
		 r00, -r01,  r02,
		-r10,  r11, -r12,
		 r20, -r21,  r22
	)
end

-- Tira da copia tudo que nao e visual: script, som, luz, prompt, humanoide.
local function limparCopia(raiz: Instance): ()
	for _, obj in ipairs(raiz:GetDescendants()) do
		if obj:IsA("LuaSourceContainer")
			or obj:IsA("Sound")
			or obj:IsA("ParticleEmitter")
			or obj:IsA("Light")
			or obj:IsA("Humanoid")
			or obj:IsA("ClickDetector")
			or obj:IsA("ProximityPrompt") then
			obj:Destroy()
		end
	end
end

local function contarParts(raiz: Instance): number
	local total = 0
	for _, obj in ipairs(raiz:GetDescendants()) do
		if obj:IsA("BasePart") then
			total += 1
		end
	end
	return total
end

local original = Workspace:FindFirstChild(NOME_DO_MODELO)
if not original or not original:IsA("Model") then
	warn(("[Reflexo] Nao achei um Model chamado '%s' dentro do Workspace."):format(NOME_DO_MODELO))
	return
end

local quantidade = contarParts(original)
if quantidade > LIMITE_DE_PARTS then
	warn(("[Reflexo] '%s' tem %d parts; o mapa iria para %d. Reduza o Model ou suba LIMITE_DE_PARTS.")
		:format(NOME_DO_MODELO, quantidade, quantidade * 2))
	return
end

local antigo = Workspace:FindFirstChild("ReflexoFalso")
if antigo then
	antigo:Destroy()
end

local reflexo = original:Clone()
reflexo.Name = "ReflexoFalso"
limparCopia(reflexo)

for _, obj in ipairs(reflexo:GetDescendants()) do
	if obj:IsA("BasePart") then
		obj.Anchored = true      -- nao cai nem e empurrado
		obj.CanCollide = false   -- jogador nao bate na copia
		obj.CanQuery = false     -- raycast de ferramenta ignora
		obj.CanTouch = false
		obj.CastShadow = false   -- sombra embaixo do piso so custa GPU
		obj.Transparency = math.max(obj.Transparency, TRANSPARENCIA_MINIMA)
		obj.CFrame = espelharCFrame(obj.CFrame, ALTURA_DO_PISO)
	end
end

reflexo.Parent = Workspace
print(("[Reflexo] 'ReflexoFalso' criado com %d parts espelhadas em Y = %.2f.")
	:format(quantidade, ALTURA_DO_PISO))
Neste artigo

Continue por aqui