Ir para conteúdo
Fórum Script Brasil
  • 0

viniBiavatti

Pergunta

Olá Pessoal do Fórum ScriptBrasil!



RayCasting, uma forma de gerar um ambiente 3d a partir de uma matriz 2d. Gostaria de saber se alguém do fórum tem algum tipo de tutorial em português, ou algum mina algoritmo bem BÁSICO sobre o assunto. Estou muito interessado porém tenho certas dúvidas que não acho a resposta na internet. As explicações são um pouco complicadas más estou procurando muito a respeito. Alguns requisitos que estou atrás é o conhecimento da trigonometria que é essencial para o desenvolvimento e lógica de rayCasting. Já estou me adaptando e tive algumas lógicas bem interessantes para um bom início.



O que peço para vocês é que me mandem link de algum tutorial básico, algum exemplo como um programa java com o source disponível. Estou apenas atrás de conhecimento até conseguir desenvolver meu primeiro rayCasting.



Procuro algo básico, pois o assunto trata diversas coisas como por exemplo, o "lighting" ou seja, a luminosidade de diversos pontos deste pseudo-3d. Más isto já vejo como avançado. O que quero é apenas construir uma matriz onde irei utilizar como mapa, criar um ângulo de raios para formar o campo de visão e renderizar os pontos onde estes raios entram em conflito com os pontos da matriz (paredes), e assim, criar o psudo-3d em um canvas (java).



Sobre RayCasting: Posso dizer que é uma forma de tornar um mapa em uma visão 3d, ou melhor, com aparência 3d. digamos que tenhamos uma matriz de inteiros onde servirá como mapa:

int[][] mapa = new int[][]{

{2,2,2,2,2},

{0,0,0,0,0},

{0,0,1,0,0},

{0,0,0,0,0},

{0,0,0,0,0}};



Os pontos 2 definimos como as paredes e o ponto 1, o personagem. O intuito é realizar o lançamento de raios em um certo ângulo de visão do personagem para verificar a distância de colisão da parede (2);

Simple_raycasting_with_fisheye_correctio



Quando o raio entra em colisão com a parede, é calculada a distância entre a posição do personagem com a parede. Podemos utilizar a trigonometria para calcular esta distância com o teorema de pitágoras. (hipotenusa)



Nesta imagem, percebe-se que existe algum efeito de luminosidade onde seria mais um complemento pro aprendizado. O que quero por exemplo é algo simples, como um algoritmo java tendo uma matriz, alguns métodos de calculo da distancia e etc e a renderização da matriz em um canvas. Algo básico como:

raycaster101.png



Pode ver que é bem simples para um bom começo smile.png. Veja que não tem efeitos de luminosidade e textura, apenas o chateado raycasting.

Não possui uma grid sendo "floor", teto ou chão, apenas as paredes. No caso, o cháo é apenas uma pintura verde até o centro da tela e o azul é mesma coisa.

Após o conhecimento, irei aprimorar futuramente:

raycaster201.png



Esta imagem já contém algumas sombras e etc...



Já procurei muito na internet e achei na maioria tutoriais em inglês. Aprendi algo com eles, más é um tanto complicado de entender pelo volume de código que existe, pois os tutoriais na maioria das vezes ensinam a aplicar texturar e luminosidade e etc... Já outros utilizam outras linguagens como javascript e C++ porém gostaria de tratar isto com java.



Já criei algum software para tentar entender um pouco do assunto e estou disponibilizando os métodos principais dele abaixo, junto com alguns comentários. É bem básico pois não existe algum tipo de angulação para movimentação e nova leitura de pontos para formação pseudo-3d. O algoritmo apenas realiza uma varredura da matriz (mapa) e procura por uma parede (2). Ao encontrar, ele calcula a hipotenusa das cordenadas da parede até com as cordenadas do personagem. Tendo esta hipotenusa, é definido o tamanho de um retângulo no canvas. Se a distancia é grande (longe), o retângulo é pequeno. Se a distancia é pequena (perto), o retângulo é grande.



Aqui defino meus atributos e o mapa:

public class Janela extends Canvas implements Runnable{
   
    int[] pixelsFundo;
    private BufferedImage img;
    private int[][] mapa = new int[][]{ {0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},    
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    private int jogadorX = 11;
    private int jogadorY = 11;
   
    public Janela()
    {
        this.img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
        this.pixelsFundo = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
    }

Este é o método de renderização no canvas, onde ele irá desenhas os retângulos no componente:

Os parâmetros são a largura, altura e posição x, y do retângulo gerado no método calcular:


public void render(int x, int y, int xPos, int yPos)
    {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null)
        {
            this.createBufferStrategy(2);
            bs = this.getBufferStrategy();
        }
       
        Graphics g = bs.getDrawGraphics();
        g.drawRect(xPos,yPos,x, y);
        g.dispose();
        bs.show();
    }

Este é o método de calculo. Ele que defini a distância da parede na matriz e gera um tamanho e posição para renderização dos retângulos:

public void calcular()
    {
        int poxX = 0;
        for (int i = 0; i < mapa.length; i++)
        {
            poxX = 0;
            for(int j = 0; j < mapa.length; j++)
            {
                if(mapa[i][j] == 2)
                {
                    double catetoAdj = this.jogadorX - i;
                    double catetoOp = this.jogadorY - j;
                    double hipotenusa = catetoOp / catetoAdj;
                   
                    if(hipotenusa < 0)
                    {
                        hipotenusa = hipotenusa * -1;
                    }
                    System.out.println(hipotenusa);
                    render(37, (int)(200-(hipotenusa*50)),poxX, (int)(180+((hipotenusa*50)/2)));
                }
                poxX += 37;
            }
        }
    }

Este é um exemplo de saida do programa:

2mh5v0l.jpg



Isto é básico e programei para dar início.

Pois bem gente um breve resumo:

Gostaria de um bom tutorial ou algo que possa ensinar a programar o raycasting como por exemplo, um algoritmo pronto, básico onde so tenha a renderização das paredes e a lógica do raycasting, sem essas frescuras de luminosidade, sombra, texturas, chão, teto e etc... Como mencionei, BÁSICO. Sei que o assunto é um pouco avançado mais nem tanto quanto parece, aliás, estamos lidando com pseudo-3d, um 3d de mentira wink.png. Pessoal, espero que me ajudem, sou novo aqui no fórum e desculpe se publiquei algo incorretamente. Obrigado por tudo!



Linguagem que utilizo: JAVA

Cursando: Ciências da Computação.



Curiosidades: O Ray casting foi utilizado no primeiro jogo em pseudo-3d da história, o Wolfstein 3d.

shot1.jpg

Editado por viniBiavatti
Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...