2016-04-06 127 views
9

CURACercando di porto uno shader vetro GLSL al trattamento 3.0

Sono principiante sul linguaggio Processing e shaders GLSL. Sto cercando di portare uno shader di fresnel + cubemap per un materiale di vetro. Ma, come risultato la mia forma mai sparire, invece ... :-(

mio vertex shader è:

const float Air = 1.0; 
const float Glass = 1.51714; 

const float Eta = Air/Glass; 

const float R0 = ((Air - Glass) * (Air - Glass))/((Air + Glass) * (Air + Glass)); 

uniform mat4 transform; 
uniform mat4 modelview; 
uniform mat3 normalMatrix; 

attribute vec4 vertex; 
attribute vec3 normal; 

varying vec3 v_reflection; 
varying vec3 v_refraction; 
varying float v_fresnel; 

void main(void){ 

    vec4 t_vertex = modelview * vertex; 

    vec3 incident = normalize(vec3(t_vertex)); 

    vec3 t_normal = normalMatrix * normal; 

    v_refraction = refract(incident, t_normal, Eta); 
    v_reflection = reflect(incident, t_normal); 

    v_fresnel = R0 + (1.0 - R0) * pow((1.0 - dot(-incident, t_normal)), 5.0); 

    gl_Position = transform * t_vertex; 
} 

E lo shader frammento:

#ifdef GL_ES 
precision mediump float; 
precision mediump int; 
#endif 

uniform samplerCube cubemap; 

varying vec3 v_refraction; 
varying vec3 v_reflection; 
varying float v_fresnel; 

void main(void){ 
    vec4 refractionColor = textureCube(cubemap, normalize(v_refraction)); 
    vec4 reflectionColor = textureCube(cubemap, normalize(v_reflection)); 

    gl_FragColor = mix(refractionColor, reflectionColor, v_fresnel); 
} 

sto testando questo shader con la Trasformazione 3.0 soffietto schizzo (editati), la modalità Android:

PShader shader; 
PShape sphere; 

void setup() { 
    fullScreen(P3D); 
    noStroke(); 

    shader = loadShader("glass.frag.glsl", "glass.vert.glsl"); 
    openCubeMap("posx.png", "negx.png", "posy.png", "negy.png", "posz.png", "negz.png"); 
    shader.set("cubemap", 1); 

    sphere = createShape(SPHERE, 120); 
    sphere.setFill(color(-1, 50)); 
} 

void draw() { 
    background(0);  

    directionalLight(102, 102, 102, 0, 0, -1); 
    lightSpecular(204, 204, 204); 
    directionalLight(102, 102, 102, 0, 1, -1); 
    specular(100, 150, 150); 

    translate(width/2, height/2); 
    shader(shader); 
    shape(sphere); 
} 

void openCubeMap(String posX, String negX, String posY, String negY, String posZ, String negZ) { 

    PGL pgl = beginPGL(); 
    // create the OpenGL-based cubeMap 
    IntBuffer envMapTextureID = IntBuffer.allocate(1); 
    pgl.genTextures(1, envMapTextureID); 
    pgl.activeTexture(PGL.TEXTURE1); 
    pgl.enable(PGL.TEXTURE_CUBE_MAP); 
    pgl.bindTexture(PGL.TEXTURE_CUBE_MAP, envMapTextureID.get(0)); 
    pgl.texParameteri(PGL.TEXTURE_CUBE_MAP, PGL.TEXTURE_WRAP_S, PGL.CLAMP_TO_EDGE); 
    pgl.texParameteri(PGL.TEXTURE_CUBE_MAP, PGL.TEXTURE_WRAP_T, PGL.CLAMP_TO_EDGE); 
    pgl.texParameteri(PGL.TEXTURE_CUBE_MAP, PGL.TEXTURE_WRAP_R, PGL.CLAMP_TO_EDGE); 
    pgl.texParameteri(PGL.TEXTURE_CUBE_MAP, PGL.TEXTURE_MIN_FILTER, PGL.LINEAR); 
    pgl.texParameteri(PGL.TEXTURE_CUBE_MAP, PGL.TEXTURE_MAG_FILTER, PGL.LINEAR); 

    //Load in textures 
    String[] textureNames = { posX, negX, posY, negY, posZ, negZ }; 
    for (int i=0; i<textureNames.length; i++) {  
    PImage texture = loadImage(textureNames[i]); 
    int w = texture.width; 
    int h = texture.height; 
    texture.loadPixels(); 
    pgl.texImage2D(PGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, PGL.RGBA, w, h, 0, PGL.RGBA, PGL.UNSIGNED_BYTE, IntBuffer.wrap(texture.pixels)); 
    } 

    endPGL(); 
} 

E sto usando le immagini this per costruire la cubemap.

Qualcuno sa come posso farlo funzionare?

+3

Questo è un sacco di codice a chiederci di passare attraverso. Probabilmente avrai miglior fortuna se pubblichi un [mcve] restringendolo in meno linee possibili. –

+0

Hai perfettamente ragione, mi dispiace. Il post precedente era un po 'confuso. Si prega di controllare la mia domanda modificata. Le parti rilevanti sono il codice vertice e il codice frag. Ma ho aggiunto il codice dello schizzo per aiutare e ripulire. Scusate se c'è ancora così tante battute, ma ho paura di sacrificare un po 'di chiarezza se lo riduco di più. Grazie per l'aiuto e la consulenza, @Kevin Workman. – Renascienza

+0

Hai mai capito? –

risposta

1

Il problema non è nel codice ma nei dati.

OpenGL richiede che tutte le texture utilizzate dal cubemap hanno le stesse dimensioni , e che le trame essere quadrato altrimenti si rifiuterà di caricarlo.

Ho controllato i PNG e questo non è il caso, hanno tutti la stessa dimensione ma non sono quadrati (255x230).

anche per Android può essere richiesto che le dimensioni trama essere una potenza di 2 (128, 256, 512 ...)

Così ho provato il ridimensionamento tutte le texture a 256x256 pixel e ora il tuo campione funziona:

it works !