Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
- **ziviDomeLive** works across multiple operating systems, including macOS, Windows, and Linux, making it highly versatile and accessible to a wide range of users. This ensures that your visual creations can be deployed on various platforms without compatibility issues.

**Customizable Rendering Pipelines**:
- **OpenGL Cubemap Renderer**: Efficiently captures scenes into a single cubemap texture for downstream shaders.
- **Skybox Shader Preview**: Use `skybox.vert` and `skybox.frag` to visualize the cubemap in the preview window.
- Define and customize rendering pipelines to meet the needs of your project. Whether you are rendering for fulldome projection or interactive experiences, the library allows you to adjust the rendering resolution, projection mode, and other parameters to optimize performance and visual quality.

## Known Issues
Expand Down
7 changes: 0 additions & 7 deletions shaders/README

This file was deleted.

44 changes: 0 additions & 44 deletions shaders/domemaster.frag

This file was deleted.

22 changes: 0 additions & 22 deletions shaders/domemaster.vert

This file was deleted.

159 changes: 34 additions & 125 deletions shaders/equirectangular.frag
Original file line number Diff line number Diff line change
@@ -1,142 +1,51 @@
#version 410 core
#define PROCESSING_COLOR_SHADER

uniform sampler2D posX, negX, posY, negY, posZ, negZ;
uniform sampler2D heightMap; // Mapa de alturas em tons de cinza
uniform vec2 resolution;
// Declaração explícita da precisão
precision highp float;

const float PI = 3.1415926535897932384626433832795;
const float edgeBlendWidth = 0.02; // Controle de largura da transição

// Output variable
out vec4 FragColor;

// Função que aplica a transformação Equi-Angular (EAC) no cubemap
vec3 applyEACMapping(vec3 dir) {
float theta = acos(dir.y); // Ângulo polar (latitude)
float phi = atan(dir.z, dir.x); // Ângulo azimutal (longitude)

// Aplica a transformação EAC ao ângulo polar
float eacTheta = 2.0 * atan(tan(theta * 0.5));

// Converte de volta para coordenadas cartesianas
return normalize(vec3(sin(eacTheta) * cos(phi), cos(eacTheta), sin(eacTheta) * sin(phi)));
}

// Função para calcular a normal a partir de um mapa de alturas (grayscale -> Normal Map)
vec3 calculateNormalFromHeightMap(vec2 uv) {
float heightScale = 0.1; // Escala para ajustar o relevo
float hL = texture(heightMap, uv + vec2(-0.001, 0.0)).r * heightScale;
float hR = texture(heightMap, uv + vec2(0.001, 0.0)).r * heightScale;
float hD = texture(heightMap, uv + vec2(0.0, -0.001)).r * heightScale;
float hU = texture(heightMap, uv + vec2(0.0, 0.001)).r * heightScale;

vec3 normal = normalize(vec3(hL - hR, hD - hU, 1.0));
return normal;
}

// Converte coordenadas XYZ para UV e face
void convert_xyz_to_cube_uv(float x, float y, float z, out int index, out vec2 uv) {
float absX = abs(x);
float absY = abs(y);
float absZ = abs(z);

bool isXPositive = x > 0.0;
bool isYPositive = y > 0.0;
bool isZPositive = z > 0.0;
uniform samplerCube cubemap; // Cubemap de entrada
uniform vec2 resolution; // Resolução do retângulo 2:1 (width, height)

float maxAxis, uc, vc;
out vec4 FragColor; // Cor de saída do pixel

if (isXPositive && absX >= absY && absX >= absZ) {
maxAxis = absX;
uc = -z;
vc = y;
index = 0; // +X
} else if (!isXPositive && absX >= absY && absX >= absZ) {
maxAxis = absX;
uc = z;
vc = y;
index = 1; // -X
} else if (isYPositive && absY >= absX && absY >= absZ) {
maxAxis = absY;
uc = x;
vc = -z;
index = 2; // +Y
} else if (!isYPositive && absY >= absX && absY >= absZ) {
maxAxis = absY;
uc = x;
vc = z;
index = 3; // -Y
} else if (isZPositive && absZ >= absX && absZ >= absY) {
maxAxis = absZ;
uc = x;
vc = y;
index = 4; // +Z
} else {
maxAxis = absZ;
uc = -x;
vc = y;
index = 5; // -Z
}

uv = clamp(0.5 * (vec2(uc, vc) / maxAxis + 1.0), 0.0, 1.0);
}

// Função de interpolação bilinear
vec4 bilinearInterpolate(sampler2D tex, vec2 uv) {
vec2 texSize = vec2(textureSize(tex, 0));
vec2 f = fract(uv * texSize);
uv -= f / texSize;

vec4 p00 = texture(tex, uv);
vec4 p10 = texture(tex, uv + vec2(1.0, 0.0) / texSize);
vec4 p01 = texture(tex, uv + vec2(0.0, 1.0) / texSize);
vec4 p11 = texture(tex, uv + vec2(1.0, 1.0) / texSize);

vec4 col0 = mix(p00, p10, f.x);
vec4 col1 = mix(p01, p11, f.x);

return mix(col0, col1, f.y);
}

vec4 sampleCubemapFace(vec3 dir) {
vec2 uvCube;
int index;

// Aplica mapeamento EAC na direção
vec3 adjustedDir = applyEACMapping(dir);
const float PI = 3.1415926535897932384626433832795;

// Converte direção ajustada para face do cubemap e coordenadas UV
convert_xyz_to_cube_uv(adjustedDir.x, adjustedDir.y, adjustedDir.z, index, uvCube);
// Função para aplicar transformação EAC (Equi-Angular Cubemap)
vec3 applyEAC(vec3 dir) {
// Calcula as componentes absolutas
vec3 absDir = abs(dir);

// Usa interpolação bilinear na face correspondente
vec4 color;
if (index == 0) color = bilinearInterpolate(posX, uvCube);
else if (index == 1) color = bilinearInterpolate(negX, uvCube);
else if (index == 2) color = bilinearInterpolate(posY, uvCube);
else if (index == 3) color = bilinearInterpolate(negY, uvCube);
else if (index == 4) color = bilinearInterpolate(posZ, uvCube);
else if (index == 5) color = bilinearInterpolate(negZ, uvCube);
// Determina o fator de escala para minimizar distorções nas bordas
float scaleFactor = 1.0 / max(max(absDir.x, absDir.y), absDir.z);

return color;
// Retorna o vetor ajustado
return dir * scaleFactor;
}

void main() {
// Calcula a direção com base nas coordenadas da tela
// Coordenadas normalizadas da tela (0 a 1)
vec2 uv = gl_FragCoord.xy / resolution;
float theta = uv.x * 2.0 * PI;
float phi = uv.y * PI;

// Garante que os valores de 'dir' estejam corretos para o cubemap
vec3 dir = vec3(sin(phi) * sin(theta), cos(phi), sin(phi) * cos(theta));
// Converte UV para longitude (theta) e latitude (phi)
float theta = -(uv.x * 2.0 * PI - PI); // Longitude invertida para alinhar as direções
float phi = uv.y * PI - PI / 2.0; // Latitude alinhada para +Y e -Y

// Pré-calcula os valores trigonométricos para eficiência
float sinPhi = sin(phi);
float cosPhi = cos(phi);
float sinTheta = sin(theta);
float cosTheta = cos(theta);

// Rotaciona 180 graus ao redor do eixo vertical (verifique se isso é realmente necessário)
dir.x = -dir.x;
dir.z = -dir.z;
// Constrói o vetor de direção 3D no sistema do cubemap
vec3 dir = vec3(
-cosPhi * sinTheta, // X invertido devido ao scale(-1, 1, -1)
sinPhi, // Y consistente com o sistema de coordenadas
-cosPhi * cosTheta // Z invertido devido ao scale(-1, 1, -1)
);

// Amostra a cor diretamente do cubemap usando o mapeamento calculado
vec4 color = sampleCubemapFace(dir);
// Aplica a transformação EAC ao vetor de direção
dir = applyEAC(dir);

// Verifica se a cor do cubemap está sendo aplicada corretamente
FragColor = color;
// Amostra o cubemap usando o vetor direcional transformado
FragColor = texture(cubemap, dir);
}
26 changes: 12 additions & 14 deletions shaders/equirectangular.vert
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
#version 410 core

uniform mat4 transform;
uniform mat4 modelview;
uniform mat3 normalMatrix;
layout(location = 0) in vec4 vertex; // Posição do vértice
layout(location = 1) in vec3 normal; // Normal do vértice

in vec4 vertex;
in vec3 normal;
uniform mat4 transform; // Matriz de transformação final
uniform mat4 modelview; // Matriz modelo-visão
uniform mat3 normalMatrix; // Matriz para transformar as normais

out vec3 vNormal;
out vec3 vPosition;
out vec3 reflectDir; // Direção refletida para o fragment shader

void main() {
// Calcula a posição do vértice em espaço de tela
gl_Position = transform * vertex;
gl_Position = transform * vertex; // Calcula a posição final no espaço de tela

// Calcula a posição do vértice em coordenadas do olho (câmera)
vPosition = vec3(modelview * vertex);

// Calcula a normal do vértice em coordenadas do olho (câmera)
vNormal = normalize(normalMatrix * normal);
// Calcula o vetor normal e direção refletida no espaço do olho
vec3 ecNormal = normalize(normalMatrix * normal); // Normal transformada
vec3 ecVertex = vec3(modelview * vertex); // Posição do vértice no espaço da câmera
vec3 eyeDir = ecVertex; // Direção do olho (origem da câmera)
reflectDir = reflect(eyeDir, ecNormal); // Direção refletida
}
54 changes: 54 additions & 0 deletions shaders/fisheye.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#version 410 core

precision highp float;

uniform samplerCube cubemap; // Cubemap de entrada
uniform vec2 resolution; // Resolução do domemaster
uniform float fov; // Campo de visão em graus (até 360 graus)

out vec4 FragColor; // Cor de saída do pixel

const float PI = 3.1415926535897932384626433832795;

// Função para aplicar Equi-Angular Cubemap (EAC)
vec3 applyEAC(vec3 dir) {
vec3 absDir = abs(dir);
float scaleFactor = 1.0 / max(max(absDir.x, absDir.y), absDir.z);
return dir * scaleFactor;
}

void main() {
// Coordenadas normalizadas da tela [-1, 1]
vec2 uv = (gl_FragCoord.xy / resolution) * 2.0 - 1.0;
uv.y *= resolution.y / resolution.x; // Corrige a proporção para resolução não quadrada

// Calcula o raio polar e ângulo azimutal
float r = length(uv); // Distância radial do centro
float phi = atan(uv.y, uv.x); // Ângulo azimutal [-PI, PI]

// Limita o raio ao círculo da projeção
if (r > 1.0) {
FragColor = vec4(0.0); // Fora do círculo, cor preta
return;
}

// Calcula o ângulo polar (theta) baseado no FOV
float maxTheta = radians(fov); // Ângulo máximo permitido pelo FOV (em radianos)
float theta = r * (maxTheta / 2.0); // Mapeia o raio para o campo de visão total

// Converte para vetor direcional 3D (projeção esférica)
vec3 dir = vec3(
sin(theta) * cos(phi), // X
sin(theta) * sin(phi), // Y
cos(theta) // Z
);

// Ajuste para o sistema do cubemap (invertendo Z para scale(-1, 1, -1))
dir.z = -dir.z;

// Aplica EAC ao vetor de direção
dir = applyEAC(normalize(dir));

// Amostra o cubemap com o vetor direcional ajustado
FragColor = texture(cubemap, dir);
}
20 changes: 20 additions & 0 deletions shaders/fisheye.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#version 410 core

layout(location = 0) in vec4 vertex; // Posição do vértice
layout(location = 1) in vec3 normal; // Normal do vértice

uniform mat4 transform; // Matriz de transformação final
uniform mat4 modelview; // Matriz modelo-visão
uniform mat3 normalMatrix; // Matriz para transformar as normais

out vec3 reflectDir; // Direção refletida para o fragment shader

void main() {
gl_Position = transform * vertex; // Calcula a posição final no espaço de tela

// Calcula o vetor normal e direção refletida no espaço do olho
vec3 ecNormal = normalize(normalMatrix * normal); // Normal transformada
vec3 ecVertex = vec3(modelview * vertex); // Posição do vértice no espaço da câmera
vec3 eyeDir = ecVertex; // Direção do olho (origem da câmera)
reflectDir = reflect(eyeDir, ecNormal); // Direção refletida
}
14 changes: 14 additions & 0 deletions shaders/skybox.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#version 410 core
#define PROCESSING_COLOR_SHADER

uniform samplerCube cubemap;
uniform vec2 resolution;

out vec4 FragColor;

void main() {
vec2 uv = (gl_FragCoord.xy / resolution) * 2.0 - 1.0;
vec3 dir = normalize(vec3(uv, 1.0));
dir.x = -dir.x;
FragColor = texture(cubemap, dir);
}
9 changes: 9 additions & 0 deletions shaders/skybox.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 410 core

uniform mat4 transform;

in vec4 vertex;

void main() {
gl_Position = transform * vertex;
}
Loading
Loading