2

我正在尝试phongLibGDX. 如果我使用默认着色器LibGDX,场景如下所示: 使用默认着色器 但是我想将光影应用到场景中,如果使用phong着色器,就会出现问题。场景闪烁,看起来与原始场景非常不同。见下图: 使用 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) ;
}

我究竟做错了什么?

4

0 回答 0