We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, friends!
I am new on forum, and really a beginner on shaders. I am trying to port a fresnel+cubemap shader for a glass material. But as result my shape ever disappear, instead... :-(
Some friend have a hint about what I am doing wrong? I am rendering it on Android mode, on emulator.
That is my minimal sketch:
import java.nio.IntBuffer;
PShader shader;
PShape sphere;
PShape box;
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));
box = createShape(BOX, 100);
box.setFill(color(255, 50, 50));
}
void draw() {
background(0);
// Some lights...
directionalLight(102, 102, 102, 0, 0, -1);
lightSpecular(204, 204, 204);
directionalLight(102, 102, 102, 0, 1, -1);
specular(100, 150, 150);
pushMatrix();
translate(width / 2, height / 2);
rotateY(90);
rotateX(45);
shape(box);
popMatrix();
translate(mouseX, mouseY);
shader(shader);
shape(sphere);
resetShader();
}
I use this method to load the textures (from data dir) on cubemap:
void openCubeMap(String posX, String negX, String posY, String negY, String posZ, String negZ) {
PGL pgl = beginPGL();
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 };
PImage[] textures = new PImage[textureNames.length];
for (int i=0; i < textures.length; i++) {
textures[i] = loadImage(textureNames[i]);
if (textures[i] == null) {
throw new IllegalArgumentException("Fail to load " + textureNames[i]);
}
}
// put the textures in the cubeMap
int envMapSize = 0;
for (int i=0; i < textures.length; i++) {
int w = textures[i].width;
int h = textures[i].height;
envMapSize = Math.max(Math.max(w, h), envMapSize);
textures[i].loadPixels();
int[] pix = textures[i].pixels;
pgl.texImage2D(PGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, PGL.RGBA, w, h, 0, PGL.RGBA, PGL.UNSIGNED_BYTE, java.nio.IntBuffer.wrap(pix));
}
endPGL();
}
This is my vertex shader:
#version 120
// Indices of refraction
const float Air = 1.0;
const float Glass = 1.51714;
// Air to glass ratio of the indices of refraction (Eta)
const float Eta = Air / Glass;
// see http://en.wikipedia.org/wiki/Refractive_index Reflectivity
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)
{
// We calculate in world space.
vec4 t_vertex = modelview * vertex;
vec3 incident = normalize(vec3(t_vertex));
// Assume incoming normal is normalized.
vec3 t_normal = normalMatrix * normal;
v_refraction = refract(incident, t_normal, Eta);
v_reflection = reflect(incident, t_normal);
// see http://en.wikipedia.org/wiki/Schlick's_approximation
v_fresnel = R0 + (1.0 - R0) * pow((1.0 - dot(-incident, t_normal)), 5.0);
gl_Position = transform * t_vertex;
}
And, finally, my fragment shader:
#version 120
#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);
}
How I can make this work?
Answers
the glsl shaders tutorial here: https://processing.org/tutorials/pshader/ suggests that you need a #define somewhere to tell the renderer what type of shader you need.
try changing line 36 to
we can't run your code without the textures so this is little more than a guess...
Thanks, @koogs!
You are right, I put a #define PROCESSING_LIGHT_SHADER on my vertex shader to keep it right (but not seems to be a TEXLIGHT, because it isn't receiving any texture attribute from pipeline, so technically is just a light shader).
But this is not the problem... :(
About the textures, so sorry about that, I forget to provide it. here it is that I'm using, (but I think any cubemap can be used): https://drive.google.com/open?id=0B-KFG7c6SvVZVmY2MEFuZDBRa2s
processing version?
(the PGL code differs depending on version)
Hi @koogs.
Processing version is on topic title: 3.0. And as tagged on shader, I am using GLSL 1.20 (to be compatible on Android, the mode I am using to test).
actually, i'm not sure that's true for PGL, it is for GL, ie...
but that's irrelevant...
your code runs, but i see no sphere. i wonder if there's a way to check that the skybox has loaded correctly?
and now i've broken the box too. 8(