The problem
I'm trying to make a basic specular material shader in pyglet, but it does not work as intended. It does not render the part behind the transparent cube, and just gives this wierd output instead. I want it to render the red cube behind the transparent cube with the shaders.
The code
main.py
from pyshaders import from_files_names, ShaderCompilationError
try:
shader = from_files_names("main.vert", "main.frag")
except ShaderCompilationError as e:
print(e.logs)
exit()
import pyglet, math
from pyglet.gl import *
from pyglet.window import key
window = pyglet.window.Window(caption = 'specular materials', resizable = True)
key_ = pyglet.window.key.KeyStateHandler()
window.push_handlers(key_)
rot = [0, 0, 0]
campos = [0, 0, 0]
camrot = [0, 0, 0]
glEnable(GL_DEPTH_TEST)
glClearColor(0.5, 1, 1, 1)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
def drawScene():
# ground
glBegin(GL_QUADS)
glColor4f(0.5, 0.5, 0.5, 1)
glVertex3f(-100, -9.9, -100)
glVertex3f(-100, -9.9, 100)
glVertex3f(100, -9.9, 100)
glVertex3f(100, -9.9, -100)
glEnd()
# cube
glPushMatrix()
glTranslatef(0, 0, -5)
glRotatef(rot[0], 1, 0, 0)
glRotatef(rot[1], 0, 1, 0)
glRotatef(rot[2], 0, 0, 1)
glBegin(GL_QUADS)
glColor4f(1, 0, 0, 1)
glVertex3f(-1, -1, -1)
glVertex3f(-1, 1, -1)
glVertex3f(1, 1, -1)
glVertex3f(1, -1, -1)
glVertex3f(-1, -1, 1)
glVertex3f(-1, 1, 1)
glVertex3f(1, 1, 1)
glVertex3f(1, -1, 1)
glVertex3f(-1, -1, -1)
glVertex3f(-1, -1, 1)
glVertex3f(1, -1, 1)
glVertex3f(1, -1, -1)
glVertex3f(-1, 1, -1)
glVertex3f(-1, 1, 1)
glVertex3f(1, 1, 1)
glVertex3f(1, 1, -1)
glVertex3f(-1, -1, -1)
glVertex3f(-1, 1, -1)
glVertex3f(-1, 1, 1)
glVertex3f(-1, -1, 1)
glVertex3f(1, -1, -1)
glVertex3f(1, 1, -1)
glVertex3f(1, 1, 1)
glVertex3f(1, -1, 1)
glEnd()
glPopMatrix()
def drawTransparent():
# ground
glColor4f(0.5, 0.5, 0.5, 0.1)
glBegin(GL_QUADS)
glVertex3f(-100, -10, -100)
glVertex3f(-100, -10, 100)
glVertex3f(100, -10, 100)
glVertex3f(100, -10, -100)
glEnd()
# cube
glColor4f(0.5, 0.5, 0.5, 0.1)
glPushMatrix()
glRotatef(rot[0], 1, 0, 0)
glRotatef(rot[1], 0, 1, 0)
glRotatef(rot[2], 0, 0, 1)
glBegin(GL_QUADS)
glColor4f(0.5, 0.5, 0.5, 0.5)
glVertex3f(-1.1, -1.1, -1.1)
glVertex3f(-1.1, 1.1, -1.1)
glVertex3f(1.1, 1.1, -1.1)
glVertex3f(1.1, -1.1, -1.1)
glColor4f(0.5, 0.5, 0.5, 0.5)
glVertex3f(-1.1, -1.1, 1.1)
glVertex3f(-1.1, 1.1, 1.1)
glVertex3f(1.1, 1.1, 1.1)
glVertex3f(1.1, -1.1, 1.1)
glColor4f(0.5, 0.5, 0.5, 0.5)
glVertex3f(-1.1, -1.1, -1.1)
glVertex3f(-1.1, -1.1, 1.1)
glVertex3f(1.1, -1.1, 1.1)
glVertex3f(1.1, -1.1, -1.1)
glColor4f(0.5, 0.5, 0.5, 0.5)
glVertex3f(-1.1, 1.1, -1.1)
glVertex3f(-1.1, 1.1, 1.1)
glVertex3f(1.1, 1.1, 1.1)
glVertex3f(1.1, 1.1, -1.1)
glColor4f(0.5, 0.5, 0.5, 0.5)
glVertex3f(-1.1, -1.1, -1.1)
glVertex3f(-1.1, 1.1, -1.1)
glVertex3f(-1.1, 1.1, 1.1)
glVertex3f(-1.1, -1.1, 1.1)
glColor4f(0.5, 0.5, 0.5, 0.5)
glVertex3f(1.1, -1.1, -1.1)
glVertex3f(1.1, 1.1, -1.1)
glVertex3f(1.1, 1.1, 1.1)
glVertex3f(1.1, -1.1, 1.1)
glEnd()
glPopMatrix()
def step(dt):
rot[0] += math.pi / 8
rot[1] += math.pi / 6
rot[2] += math.pi / 7
pyglet.clock.schedule_interval(step, 1/60)
@window.event
def on_draw():
window.clear()
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(70, window.width/window.height, 0.05, 1000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(-campos[0], -campos[1], -campos[2])
glRotatef(camrot[0], 1, 0, 0)
glRotatef(camrot[1], 0, 1, 0)
glEnable(GL_POLYGON_OFFSET_FILL)
glPolygonOffset(1.0, 1.0)
glEnable(GL_LIGHTING)
shader.use()
glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat * 4)(0.2, 0.2, 0.2, 1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat * 4)(0, 0.5, 0.1, 0))
glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat * 4)(0, 0.5, 0.1, 0))
glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat * 4)(0, 0, 1, 0))
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE)
glMaterialfv(GL_FRONT, GL_SPECULAR, (GLfloat * 4)(0.5, 0.5, 0.5, 1))
glMaterialf(GL_FRONT, GL_SHININESS, 125)
glPushMatrix()
glTranslatef(0, 0, -5)
drawTransparent()
glPopMatrix()
glDisable(GL_LIGHTING)
glDisable(GL_POLYGON_OFFSET_FILL)
glDisable(GL_COLOR_MATERIAL)
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
glUseProgram(0)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
drawScene()
if key_[key.A]:
campos[0] -= 0.1
if key_[key.D]:
campos[0] += 0.1
if key_[key.W]:
campos[2] -= 0.1
if key_[key.S]:
campos[2] += 0.1
@window.event
def on_mouse_drag(x, y, dx, dy, buttons, modifiers):
global camrot
camrot[1] -= dx / 4
camrot[0] += dy / 4
pyglet.app.run()
main.vert
varying vec3 vN;
varying vec3 v;
varying vec4 color;
void main(void)
{
v = vec3(gl_ModelViewMatrix * gl_Vertex);
vN = normalize(gl_NormalMatrix * gl_Normal);
color = gl_Color;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
main.frag
varying vec3 vN;
varying vec3 v;
varying vec4 color;
#define MAX_LIGHTS 1
void main (void)
{
vec3 N = normalize(vN);
vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);
vec4 transparent = vec4(0.0, 0.0, 0.0, 0.1);
for (int i=0;i<MAX_LIGHTS;i++)
{
vec3 L = normalize(gl_LightSource[i].position.xyz - v);
vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)
vec3 R = normalize(-reflect(L,N));
vec4 Iamb = gl_LightSource[i].ambient;
vec4 Idiff = gl_LightSource[i].diffuse * max(dot(N,L), 0.0);
Idiff = clamp(Idiff, 0.0, 1.0);
vec4 Ispec = gl_LightSource[i].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
Ispec = clamp(Ispec, 0.0, 1.0);
finalColor += Iamb + Idiff + Ispec;
}
gl_FragColor = color * finalColor * transparent;
}
Screenshots
Expected output
+ with specular lighting
UPDATE
I've disabled depth test, but now there's another problem.