GLSL渲染纹理错误

时间:2014-01-24 14:45:26

标签: java opengl glsl libgdx

我正在尝试制作一个照明系统,程序改变纹理(块)亮度取决于它获得的光,并且程序为播放器可见的每个块(纹理)执行此操作。

然而,照明系统工作得很好,但是当使用着色器进行渲染时,一切都会被破坏。

此代码位于渲染循环中 -

float light = Lighting.checkLight(mapPosY, mapPosX, this); // Returns the light the current block gets
map[mapPos].light = light; // Applies the light to the block
Shaders.block.setUniformf("lightBlock", light); // Sets the light value to the shader's uniform, to change the brightness of the current block / texture.

batch.draw(map[mapPos].TEXTURE, (mapPosX * Block.WIDTH), (mapPosY * Block.HEIGHT), Block.WIDTH, Block.HEIGHT); // Renders the block / texture to the screen. 

结果非常随机..
正如我所说,前两行完美无缺,问题可能出在第三行或着色器本身。

着色器:
顶点着色器 -

attribute vec4 a_color;
attribute vec3 a_position;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;

varying vec4 vColor;
varying vec2 vTexCoord;

void main() {
    vColor = a_color;
    vTexCoord = a_texCoord0;
    gl_Position =  u_projTrans * vec4(a_position, 1.0f);
}

片段着色器 -

varying vec4 vColor;
varying vec2 vTexCoord;

uniform vec2 screenSize;

uniform sampler2D tex;
uniform float lightBlock;

const float outerRadius = .65, innerRadius = .4, intensity = .6;

const float SOFTNESS = 0.6;

void main() {

    vec4 texColor = texture2D(tex, vTexCoord) * vColor;

    vec2 relativePosition = gl_FragCoord.xy / screenSize - .5;

    float len = length(relativePosition);

    float vignette = smoothstep(outerRadius, innerRadius, len);

    texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette * lightBlock, intensity);

    gl_FragColor = texColor;
}

1 个答案:

答案 0 :(得分:0)

我解决了问题..但我不知道为什么修复它。
感谢Pedro,我更专注于渲染循环而不是着色器本身。

在循环之前,我添加了这两行 -

List<Integer> lBlocks = new ArrayList<Integer>();
Shaders.block.setUniformf("lightBlock", 0.3f);

基本上我创建了一个数组,以便稍后存储明亮的块 我将着色器的制服设置为0.3f,这意味着很暗。该值应为0-1f。

现在在渲染循环中,在for -

float light = Lighting.checkLight(mapPosY, mapPosX, this);
map[mapPos].light = light;
if( light == 1.0f) { 
    lBlocks.add(mapPos);
} else {
    batch.draw(map[mapPos].TEXTURE, (mapPosX * Block.WIDTH), (mapPosY * Block.HEIGHT), Block.WIDTH, Block.HEIGHT);
}   

正如你所看到的,我添加到数组的亮块和我渲染的暗块,我在渲染循环之前将均匀设置为0.3f,就像在第一个代码示例中一样。

在渲染循环之后,我再次循环通过明亮的块...因为我们没有渲染它们。

Shaders.block.setUniformf("lightBlock", 1.0f);
    for(int i = 0; i < lBlocks.size(); i++) {
        batch.draw(map[lBlocks.get(i)].TEXTURE, ((lBlocks.get(i) % width) * Block.WIDTH), ((lBlocks.get(i) / width) * Block.HEIGHT), Block.WIDTH, Block.HEIGHT);
    }

现在我渲染了明亮的块并且它起作用..结果很好。
但是我不知道它为什么会这样,就像将渲染循环切割成两个,一个用于暗块,一个用于亮块。

谢谢:)