sombras do estêncil - mecanismo doom 3 - erros de precisão - trincas nas sombras - por que?

8

Estou testando os limites do mecanismo Doom 3 - em relação ao tamanho máximo do mapa.

Notei alguns erros de precisão da sombra do estêncil que se tornam mais pronunciados quando os objetos se afastam cada vez mais da origem do mapa.

na posição: -10901 -18214 -11204 Exemplo 1

na posição: -10802 -26483 -19383 exemplo2

na posição: -10802 -34683 -27540 exemplo3

Acredito que esses erros tenham sido referidos como "trincas nas sombras", mas não tenho certeza de como esses artefatos foram chamados anteriormente.

Quase todos os artefatos aparecem ao longo dos limites das luzes / sombras - que podem ser vistos aqui: insira a descrição da imagem aqui

Alguém já viu esse tipo de artefato gráfico antes com sombras de estêncil? O que eles chamaram? Qual é a causa?

Mais exemplos: misc1 misc2

Este é o mecanismo Doom 3 de baunilha, conforme encontrado aqui: https://github.com/TTimo/doom3.gpl

Notei ao testar o cvar r_useOptimizedShadows (que lida com os volumes de sombra da geometria do worldspawn) que o artefato desapareceu. Então eu trabalhei meu caminho para esta função:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, true /* FIXME? */ );

que eu mudei para isso:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, false /* FIXME? */ );

Isso elimina os artefatos - mas agora assume que nunca estamos dentro dos volumes sombrios da geometria do mundo. Portanto, sempre que entramos em um volume de sombra, esse volume de sombra não é renderizado corretamente.

Stepan1010
fonte
11
Não tenho certeza sobre essa implementação específica, mas o ponto flutuante perde a precisão quanto mais você vai do zero.
concept3d
2
Acordado. 7 dígitos é quase a quantidade máxima de precisão que você pode esperar de números de ponto flutuante de 32 bits (também conhecido como C / C ++ float). Você gastou facilmente 5 deles.en.wikipedia.org/wiki/…
snake5
@ concept3d - Suponho que converter os carros alegóricos relevantes em duplos ajudaria? Se alguém tivesse o conhecimento técnico para fazer isso. Mesmo se isso resultasse em tempos de renderização mais longos.
precisa saber é o seguinte
11
@glampert Atualizei a pergunta. É o motor de baunilha Doom 3.
precisa saber é o seguinte
11
O que acontece quando você altera os cálculos do volume de sombra? (Por exemplo, apenas dimensione todos os volumes de sombra por um pequeno valor) Os artefatos ainda aparecem / mudam / desaparecem?
Roy T.

Respostas:

3

Finalmente descobri uma solução - na verdade, algumas soluções diferentes. Eu não descobri a causa real do artefato de uma perspectiva de programação gráfica - mas encontrei algumas soluções.

Como afirmei anteriormente na minha pergunta, parecia que o artefato estava ocorrendo apenas nos volumes de sombra pré-calculados da geometria estática do mundo do peão (que é basicamente a geometria que o mecanismo sabe que nunca se moverá, portanto, calcula antecipadamente) - os volumes de sombra e outras coisas com um comando digitado no console chamado "dmap"). Não descobri por que isso estava apenas nas sombras da geometria estática do mundo dos peões e não em nenhum dos modelos ASE ou LWO.

Agora, o que notei foi que, na verdade, há uma infinidade de parâmetros que podem ser usados ​​com o comando dmap - um desses parâmetros é chamado "shadowOpt" - que deve representar o nível de otimização de sombra. Este parâmetro define uma enumeração - parece haver alguns níveis diferentes de otimização de sombra:

typedef enum {
    SO_NONE,            // 0 // NOTE: I haven't tried this one yet - should test this one.
    SO_MERGE_SURFACES,  // 1 // NOTE: this was the original default one - it causes some artifacts - the ones I have been trying to fix.
    SO_CULL_OCCLUDED,   // 2 // NOTE: this one works the best - takes a bit longer - but it has alot of unnecessary print statements that could probably be removed.
    SO_CLIP_OCCLUDERS,  // 3 // NOTE: I haven't tried this one yet - but it is not used anywhere.
    SO_CLIP_SILS,       // 4 // NOTE: I haven't tried this one yet - should test this one.
    SO_SIL_OPTIMIZE     // 5 // NOTE: this one doesn't seem to work well at all - and it takes an extrememly long amount of time - was probably an expirimental version.
} shadowOptLevel_t;

Eu tive sucesso com a opção 2 - "SO_CULL_OCCLUDED". Ele corrige todos os artefatos - demora um pouco mais para ser executado - mas acredito que muito desse tempo é gasto imprimindo grandes quantidades de informações no console - essas impressões provavelmente poderiam ser reduzidas ou eliminadas.

Um dos lugares que me deu algumas pistas foi o comentário aqui em tr_stencilshadow.cpp:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer ) {

Agora, o problema de realizar apenas essa otimização de sombra "extra" durante o "dmap" é que, se alguma dessas luzes for movida (o que sempre é possível, dependendo do tipo de projeto que você está fazendo) - ela retornará ao padrão processo de criação de volume de sombra em tempo real "não otimizado" (para a luz movida) e os artefatos reaparecerão para essa luz. Portanto, a única maneira de garantir que esses artefatos não apareçam é sempre executar o processo de otimização muito caro para essas sombras estáticas de worldspawn. Na verdade, é muito caro, portanto este seria um último recurso absoluto se você não conseguir encontrar uma solução gráfica adequada. (se o fizer, certifique-se de postar sua solução aqui.)

Eu recomendaria para quem criar mapas grandes para o mecanismo Doom 3 de baunilha - e usar a geometria worldspawn - que eles criem um cvar que eles possam mudar dependendo de suas necessidades para a criação em tempo real dos volumes de sombra otimizados. Liguei para minhas cvar r_useExpensiveShadowOptimizations - que parece ser um oxímoro. Por exemplo:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer || r_useExpensiveShadowOptimizations.GetBool() ) {

Também recomendo que, dependendo do tamanho dos seus mapas (e supondo que as luzes não se movam), você aumente o nível de otimização do volume de sombra estática com o parâmetro "shadowOpt" do dmap.

Então, basicamente, todas as coisas que você precisa para ter um mapa grande e não possuir artefatos de sombra estão lá para você, basta decidir quais você precisará usar. Fazer isso em tempo real é extremamente caro e só deve ser feito como último recurso se você não encontrar uma solução gráfica adequada. Fazê-lo no DMAP faz todo o sentido, pois resolve o problema e leva apenas mais alguns segundos para que o mapa seja compilado.

Stepan1010
fonte
2

Pode muito bem ser um erro de precisão de ponteiro flutuante, já que o Doom usou floats para a renderização (principalmente uma limitação do OpenGL). No entanto, brincando tr_stencilshadow.cpp, notei este comentário que pode estar relacionado ao problema ( PointsOrdered()função interna ):

// vectors that wind up getting an equal hash value will
// potentially cause a misorder, which can show as a couple
// crack pixels in a shadow

....

// in the very rare case that these might be equal, all that would
// happen is an oportunity for a tiny rasterization shadow crack

Então aí está. Também pode ser uma limitação conhecida da maneira como a renderização de sombra foi implementada. Francamente, o código é muito confuso e difícil de ler, por isso não posso lhe dizer com certeza. Você pode enviar um e-mail aos desenvolvedores para obter mais informações.

glampert
fonte
11
Eu também vi esse comentário. No entanto, quando eu comentei o código dessa função e apenas retornei verdadeiro (ou falso - não importa) - ele não parece fazer nenhuma diferença visual em nada. Você acha que algum dos desenvolvedores responderia se eu os enviasse um email? Eu sinto que eles provavelmente não responderiam. Eu acho que eu poderia tentar isso se tudo mais falhar.
precisa saber é o seguinte
@ Stepan1010 Bem, não sei, Carmack é um cara legal, uma vez mandei um e-mail sobre algo não relacionado à programação e ele respondeu. Eu acho que não fará mal tentar ... Mas talvez você deva enviar um email para o mantenedor do repositório, pois Carmack não é mais um membro da idSoftware. Se você mostrar um problema legítimo e o trabalho que você fez, eles podem estar interessados.
glampert