我正在尝试phong
在LibGDX
. 如果我使用默认着色器LibGDX
,场景如下所示:
但是我想将光影应用到场景中,如果使用phong
着色器,就会出现问题。场景闪烁,看起来与原始场景非常不同。见下图:
所以,我的代码片段是:
public void init(){
assets = new AssetManager();
assets.load("models/test.g3dj", Model.class);
loading = true;
shadowMap = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
lightCam = new PerspectiveCamera(67, shadowMap.getWidth(), shadowMap.getHeight());
lightCam.position.set(40f, 30f, 70f);
lightCam.lookAt(0, 0, 0);
lightCam.update();
shadowGenShader = new ShaderProgram(Gdx.files.internal("shaders/shadowgen-vert.glsl").readString(), Gdx.files
.internal("shaders/shadowgen-frag.glsl").readString());
if (!shadowGenShader.isCompiled())
throw new GdxRuntimeException("Couldn't compile shadow gen shader: " + shadowGenShader.getLog());
shadowMapShader = new ShaderProgram(Gdx.files.internal("shaders/phong_vs.glsl").readString(), Gdx.files
.internal("shaders/phong_ps.glsl").readString());
if (!shadowMapShader.isCompiled())
throw new GdxRuntimeException("Couldn't compile shadow map shader: " + shadowMapShader.getLog());
u_lightProjTrans = shadowMapShader.getUniformLocation("u_lightProjTrans");
shadowTexture = shadowMapShader.getUniformLocation("shadowTexture");
uMVPMatrix = shadowMapShader.getUniformLocation("uMVPMatrix");
u_color = shadowMapShader.getUniformLocation("u_color");
u_texture = shadowMapShader.getUniformLocation("u_texture");
}
private void doneLoading() {
Model model = assets.get("models/test.g3dj", Model.class);
ModelInstance instance = new ModelInstance(model);
instances.add(instance);
loading = false;
}
@Override
public void render(float delta) {
if (loading && assets.update())
doneLoading();
camController.update();
//CREATE DEPTH TEXTURE
shadowMap.begin();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glEnable(GL20.GL_CULL_FACE);
Gdx.gl.glCullFace(GL20.GL_FRONT);
shadowGenShader.begin();
shadowGenShader.setUniformMatrix("u_projTrans", lightCam.combined);
if(instances.size>0){
for(int j=0; j< instances.size; j++)
for(int i=0; i< instances.get(j).model.meshes.size; i++)
instances.get(j).model.meshes.get(i).render(shadowGenShader, GL20.GL_TRIANGLES);
}
shadowGenShader.end();
shadowMap.end();
Gdx.gl.glDisable(GL20.GL_CULL_FACE);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
shadowMapShader.begin();
shadowMap.getColorBufferTexture().bind();
shadowMapShader.setUniformi(shadowTexture, 0);
shadowMapShader.setUniformMatrix(uMVPMatrix, cam.combined);
shadowMapShader.setUniformMatrix(u_lightProjTrans, lightCam.combined);
shadowMapShader.setUniformf("lightPos", 5.0f, 7.0f, 0.0f);
shadowMapShader.setUniformf("lightColor", 1.0f, 1.0f, 1.0f);
shadowMapShader.setUniformf("matAmbient", 1.0f, 0.5f, 0.5f, 1.0f);
shadowMapShader.setUniformf("matDiffuse", 0.5f, 0.5f, 0.5f, 1.0f);
shadowMapShader.setUniformf("matSpecular", 1.0f, 1.0f, 1.0f, 1.0f);
shadowMapShader.setUniformf("matShininess", 5.0f);
Matrix4 normalMat = cam.combined.toNormalMatrix();
shadowMapShader.setUniformMatrix("normalMatrix", normalMat);
Matrix4 shadowMat = lightCam.combined;
shadowMapShader.setUniformMatrix("shadowProjMatrix", shadowMat);
shadowMapShader.setUniformf(u_color, 1, 1, 0, 1);
if(instances.size>0){
for(int j=0; j< instances.size; j++)
for(int i=0; i< instances.get(j).model.meshes.size; i++){
tex.bind(1);
shadowMapShader.setUniformi(u_texture, 1);
instances.get(j).model.meshes.get(i).render(shadowMapShader, GL20.GL_TRIANGLES);
}
}
shadowMapShader.end();
}
shadowgen-vert.glsl:
attribute vec3 a_position;
varying vec4 v_position;
uniform mat4 u_projTrans;
void main(void)
{
gl_Position = u_projTrans * vec4(a_position,1.0) ;
v_position = gl_Position;
}
shadowgen-frag.glsl:
#ifdef GL_ES
precision highp float;
#endif
varying vec4 v_position;
void main(void)
{
float normalizedDistance = v_position.z / v_position.w;
normalizedDistance = (normalizedDistance + 1.0) / 2.0;
normalizedDistance += 0.001;
const vec4 packFactors = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
const vec4 bitMask = vec4(0.0 , 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 packedValue = vec4(fract(packFactors*normalizedDistance));
packedValue -= packedValue.xxyz * bitMask;
gl_FragColor = packedValue;
}
phong-vs.glsl:
uniform mat4 uMVPMatrix;
uniform mat4 normalMatrix;
// the shadow projection matrix
uniform mat4 shadowProjMatrix;
// eye pos
uniform vec3 eyePos;
// position and normal of the vertices
attribute vec4 a_position;
attribute vec3 a_normal;
// texture variables
varying float tex;
attribute vec2 a_texCoord0;
varying vec2 tCoord;
// lighting
uniform vec4 lightPos;
uniform vec4 lightColor;
// material
uniform vec4 matAmbient;
uniform vec4 matDiffuse;
uniform vec4 matSpecular;
uniform float matShininess;
// to pass on
varying vec3 vNormal;
varying vec3 EyespaceNormal;
varying vec4 shadowCoord;
varying vec3 lightDir, eyeVec;
void main() {
// pass on texture variables
tex = 1.0;
tCoord = a_texCoord0;
// normal
EyespaceNormal = vec3(normalMatrix * vec4(a_normal, 1.0));
// the vertex position
vec4 position = uMVPMatrix * a_position;
// light dir
lightDir = lightPos.xyz - position.xyz;
eyeVec = -position.xyz;
// shadow coordinates
mat4 bias2 = mat4(0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.0, 0.5,
0.0, 0.0, 0.0, 1.0);
mat4 bias = mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.0, 0.5,
0.5, 0.5, 0.5, 1.0);
mat4 shadowProjMatrix2 = bias * shadowProjMatrix;
shadowCoord = shadowProjMatrix * a_position;
gl_Position = position;
}
phong-ps.glsl:
precision highp float;
// texture variables
uniform sampler2D shadowTexture; // depth texture
uniform sampler2D u_texture; // color texture
varying float tex;
varying vec2 tCoord;
varying vec3 vNormal;
varying vec3 EyespaceNormal;
// light
uniform vec4 lightPos;
uniform vec4 lightColor;
// shadow projection matrix
uniform mat4 shadowProjMatrix;
// material
uniform vec4 matAmbient;
uniform vec4 matDiffuse;
uniform vec4 matSpecular;
uniform float matShininess;
// eye pos
uniform vec3 eyePos;
// from vertex s
varying vec3 lightDir, eyeVec;
// shadow coordinates
varying vec4 shadowCoord;
float getShadowFactor(vec4 lightZ)
{
vec4 packedZValue = texture2D(shadowTexture, lightZ.st);
// unpack
const vec4 bitShifts = vec4(1.0 / (256.0 * 256.0 * 256.0),
1.0 / (256.0 * 256.0),
1.0 / 256.0,
1);
float shadow = dot(packedZValue , bitShifts);
return float(shadow > lightZ.z);
}
void main() {
// Just to show them being used
//vec4 a = lightPos;
vec4 b = lightColor;
vec4 c = matAmbient;
vec4 d = matDiffuse;
vec4 e = matSpecular;
vec3 g = eyePos;
float f = matShininess;
vec3 N = normalize(EyespaceNormal);
vec3 E = normalize(eyeVec);
vec3 L = normalize(lightDir);
// Reflect the vector. Use this or reflect(incidentV, N);
vec3 reflectV = reflect(-L, N);
// Get lighting terms
vec4 ambientTerm;
if (tex >= 1.0) {
ambientTerm = texture2D(u_texture, tCoord);
}
else
ambientTerm = matAmbient * lightColor;
vec4 diffuseTerm = matDiffuse * max(dot(N, L), 0.0);
vec4 specularTerm = matSpecular * pow(max(dot(reflectV, E), 0.0), matShininess);
// Shadow
float sValue = 1.0;
float sValue2 = 1.0;
if (shadowCoord.w > 0.0) {
vec4 lightZ = shadowCoord / shadowCoord.w;
lightZ = (lightZ + 1.0) /2.0;
sValue = getShadowFactor(lightZ);
// scale the value from 0.5-1.0 to get a "softer" shadow for ambient
float newMin = 0.5;
float v1 = (1.0)/(1.0 - newMin);
float v2 = sValue/v1;
sValue2 = sValue + newMin;//v2 + newMin;
}
gl_FragColor = ( ambientTerm * sValue2 + (diffuseTerm + specularTerm) * sValue) ;
}
我究竟做错了什么?