Como eu configuraria o fog para seguir as coordenadas de um jogador?

7

Gostaria de saber se é possível configurar um nevoeiro nas coordenadas de um jogador (onde há nevoeiro ao redor do jogador para torná-lo mais em terceira pessoa) a principal razão pela qual pergunto isso é porque eu tenho meu jogador mais no canto superior direito da tela. a tela

Aqui está um código que pode lhe dar um guia sobre o que estou fazendo:

glEnable(GL_FOG) GLfloat FogColor[] = {0.8,0.8,0.8,1.0};
glFogfv(GL_FOG_COLOR,FogColor);
glFogi(GL_FOG_MODE,GL_LINEAR);
glFogf(GL_FOG_START,30);
glFogf(GL_FOG_END,);
glHint(GL_FOG_HINT,GL_NICEST);

e eu quero que o nevoeiro siga um jogador com uma posição como dito em

posX,posY,posZ

Se alguém puder transformar isso em algum código de exemplo que seria muito útil, obrigado

Se isso não for possível, como eu configuraria o nevoeiro para ficar em torno de uma determinada posição da câmera, como mostrar no canto superior direito da câmera em vez do centro?

Aqui está uma imagem da tela do jogo para que você possa ver do que estou falando:

insira a descrição da imagem aqui

Molmasepic
fonte

Respostas:

1

Eu acho que isso seria mais facilmente realizado usando shaders. Se você ainda não tem a capacidade de usar shaders, recomendo que eles sejam descobertos, independentemente de serem super úteis para muitas coisas como essa. Operando sob a suposição de que você pode usá-los, aqui está um sombreador de vértice e fragmento que criará um raio de névoa cinza em torno da localização do seu personagem (com texturas simples).

Vertex Shader (fog.vert):

uniform vec3 playerPos;
uniform sampler2D colorMap;

varying vec3 vertexToPlayer;

void main(void)
{
    vec3 vertexPos = vec3(gl_Vertex[0], gl_Vertex[1], gl_Vertex[2]);

    vertexToPlayer = playerPos - vertexPos;

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Shader de fragmento (fog.frag):

uniform vec3 playerPos;
uniform sampler2D colorMap;

varying vec3 vertexToPlayer;

void main(void)
{
    const float radius = 1024.0;

    float dist = length(vertexToPlayer);
    float attenuation = clamp((radius - dist) / radius, 0.0, 1.0);

    vec4 diffuseTexel = texture2D(colorMap, gl_TexCoord[0].st);
    vec4 diffuseTerm  = diffuseTexel * attenuation + (.8 * (1.0-attenuation));
    diffuseTerm.a = diffuseTexel.a; /* preserve alpha */

    gl_FragColor = diffuseTerm;
}

Em seguida, em algum lugar do seu código, passe seus valores para a posição do jogador com:

GLint playerPos = glGetUniformLocation(prog, "playerPos");
glUniform3f(playerPos, xPos, yPos, zPos);

Espero que isso seja útil!

user_123abc
fonte
+1. Essa é a melhor maneira de fazer isso. Regra dos shaders! (Aaand eles são tudo o que você pode esperar no futuro, e em dispositivos móveis ...)
Macke
0

Use coordenadas de nevoeiro. http://www.opengl.org/registry/doc/fog_coord.txt

Normalmente, o valor do nevoeiro é calculado usando um fator de distância do olho ao pixel 'c'. Com efeito, a densidade do nevoeiro é uma função da distância.

f = exp (-d * c) - GL_EXP2
f = exp (- (d * c) ^ 2) - GL_EXP
f = (ec) / (es) - GL_LINEAR

As coordenadas de neblina permitem definir o valor 'c' da equação e especificar valores diretamente para isso. Se você deseja configurar o embaçamento para que 0 -> sem embaçamento, 1,0 -> mais embaçamento, faça:

glFogi (GL_FOG_MODE, GL_LINEAR);
glFogf (GL_FOG_START, 0,0f);
glFogf (GL_FOG_END, 1.0f);

// Isso realmente habilita o modo "coordenada de neblina"
glFogi (FOG_COORDINATE_SOURCE_EXT, FOG_COORDINATE_EXT);

Então, quando você renderizar sua pessoa, use glFogCoordfEXT ()

// Mostrar neblina (algum valor entre 0,0 - 1,0f)
glFogCoordfEXT (1.0f);

renderPerson ();

// Sem neblina
glFogCoordfEXT (0,0f);

Editar: Uma alternativa sem extensão é desativar o nevoeiro ao renderizar tudo e, em seguida, ativar o nevoeiro com distâncias de início / fim apropriadas ao renderizar seu personagem.

PatrickB
fonte