Compilando e executando shaders dinamicamente a partir de arquivo no XNA
-
26-09-2019 - |
Pergunta
Estou me perguntando se é possível compilar dinamicamente um pixel shader de um arquivo e aplicá-lo a uma malha.
Primeiro, começarei com algumas informações básicas.Eu tenho um sistema que cria pixel shaders HLSL com base em uma série de dados que não são realmente importantes para a questão.O importante é que esses shaders não utilizem técnicas ou passes.Como eles não devem ser usados como arquivos .fx.
O ShaderCompiler.CompileFromFile()
método é capaz de compilar com sucesso o arquivo em um CompiledShader
.
É possível aplicar esse shader em uma malha?
Como não quero localizar o ponto de entrada de cada arquivo para envolvê-lo em uma técnica que permita que ele seja compilado como um Effect
.
Solução
Primeiro de tudo - se o seu shader não tiver um ponto de entrada, você não estará compilando nada!As funções HLSL (parece que é com isso que você está trabalhando) estão embutidas começando pelo ponto de entrada.Se você não tem um ponto de entrada, então o que você tem é um shader vazio.
(Você pode confirmar isso desmontando o shader resultante depois de compilá-lo. Verifique esta pergunta e resposta para obter instruções.)
Então, antes de tudo - você são teremos que escrever código para gerar wrappers de técnica.Não deveria ser que difícil analisar aproximadamente sua fonte e descobrir o nome da função.Você poderia carregar a fonte em um buffer e anexar uma declaração de técnica gerada.Então use a versão de ShaderCompiler.CompileFromFile
isso leva um Stream
que você cria a partir desse buffer.
Para definir este shader na placa gráfica, no XNA 3.1, você pode usar:
CompiledShader cs = ShaderCompiler.CompileFromFile(...);
PixelShader ps = new PixelShader(graphicsDevice, cs.GetShaderCode());
graphicsDevice.PixelShader = ps;
Ao usar o material mesh integrado do XNA, você deseja usar ModelMeshPart.Draw
para desenhar suas malhas.Isso ignora todos Model
material de efeito integrado.
Vale ressaltar que todo ShaderCompiler
, CompiledShader
, PixelShader
sistema foi removido do XNA no XNA 4.0.Isso é explicado aqui.A maneira de compilar efeitos dinamicamente no XNA 4.0 é descrito aqui.
(Dado que você deve usar o Effect no XNA 4.0, e que não há muita diferença no XNA 3.1 entre o Effect e o PixelShader, eu recomendo que você use o Effect, compilando com Effect.CompileEffectFromSource
, se você optar por permanecer no XNA 3.1, em vez de usar ShaderCompiler
)