Compreendendo Coordenadas UV
Coordenadas UV permitem mapear pixels de texturas para vértices 3D. Como texturas são imagens 2D, utilizamos UV (em vez de XY) para evitar conflitos com coordenadas espaciais. Considere um quadrado com quatro vértices:
Vértices:
(0,0) (1,0)
(0,1) (1,1)
O quadrado é diviiddo em dois triângulos (T1 e T2). Cada vértice possui coordenadas UV correspondentes:
Vértice (0,0) → UV (0,1)
Vértice (1,0) → UV (1,1)
Vértice (1,1) → UV (1,0)
Vértice (0,1) → UV (0,0)
Implementação de Vértices
Esturtura de dados contnedo posição (XY) e UV:
const geometria:Vector.<Number> = new Vector.<Number>([
// X, Y, U, V
0, 0, 0, 1,
1, 0, 1, 1,
1, 1, 1, 0,
0, 1, 0, 0
]);
Índices para renderização dos triângulos:
const indices:Vector.<uint> = new Vector.<uint>([
0, 3, 1, // Triângulo 1
1, 2, 3 // Triângulo 2
]);
Carregamento de Textura
Requisitos: Dimensões devem ser potências de 2 (ex: 128x128). Carregamento via BitmapData:
textura = contexto.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
const imagem:Bitmap = new ImagemFonte();
textura.uploadFromBitmapData(imagem.bitmapData, 0);
Programação de Shaders AGAL
Vertex Shader (processa posições e UVs):
const vs:String = `
mov op, va0
mov v0, va1
`;
const vertexShader:AGALMiniAssembler = new AGALMiniAssembler();
vertexShader.assemble(Context3DProgramType.VERTEX, vs);
Fragment Shader (aplica textura):
const fs:String = `
tex ft0, v0, fs0 <2d,repeat,linear,nomip>
mov oc, ft0
`;
const pixelShader:AGALMiniAssembler = new AGALMiniAssembler();
pixelShader.assemble(Context3DProgramType.FRAGMENT, fs);
Parâmetros do sampler:
- 2d: Textura bidimensional
- repeat: Modo de repetição
- linear: Filtragem linear
- nomip: Sem mipmaps
Configuração de Renderização
contexto.setTextureAt(0, textura);
contexto.setProgram(programaCompilado);
contexto.setVertexBufferAt(0, bufferVertices, 0, Context3DVertexBufferFormat.FLOAT_2);
contexto.setVertexBufferAt(1, bufferVertices, 2, Context3DVertexBufferFormat.FLOAT_2);
Exemplo Completo
package {
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.*;
import com.adobe.utils.AGALMiniAssembler;
public class ExemploTextura extends Sprite {
private var contextoGPU:Context3D;
private var programa:Program3D;
public function ExemploTextura() {
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, init);
stage.stage3Ds[0].requestContext3D();
}
private function init(e:Event):void {
contextoGPU = stage.stage3Ds[0].context3D;
contextoGPU.configureBackBuffer(300, 300, 16, true);
// Configuração de geometria e textura
const dadosVertices:Vector.<Number> = Vector.<Number>([...]);
const dadosIndices:Vector.<uint> = Vector.<uint>([...]);
// Compilação de shaders
const vsCode:String = "mov op, va0\nmov v0, va1";
const fsCode:String = "tex ft0, v0, fs0 <2d,repeat,linear,nomip>\nmov oc, ft0";
// Configuração de renderização
contextoGPU.setProgram(programa);
contextoGPU.drawTriangles(bufferIndices);
}
}
}