【问题标题】:GLSL renders textures wrongGLSL 渲染纹理错误
【发布时间】:2014-01-24 14:45:26
【问题描述】:

我正在尝试制作一个照明系统,程序会根据它获得的光来更改纹理(块)亮度,并且程序会为玩家可见的每个块(纹理)执行此操作。

但是,照明系统运行良好,但在使用着色器进行渲染时,一切都会被破坏。

这段代码在渲染循环中-

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;
}

【问题讨论】:

  • 为什么投反对票?这个问题很好..
  • 你确定问题是制服没有正确传递给你的片段着色器吗?您是否尝试过使用此变量(即:硬编码值)?我对libgdx一无所知,但你的程序似乎很简单......
  • @PedroBoechat 是的,我现在玩了 2 天的值,但似乎制服没有正确传递给片段着色器。如果你说着色器很好,它对我有帮助很多,因为现在我知道我不应该在哪里搜索修复程序。
  • 嗯,根据旧的 GLSL 规范,这似乎没问题,而且你没有遇到编译错误......但我想检查针对特定 GLSL 版本的语义问题会更好(即:在着色器源的开头添加#version 150)
  • @IsraelG.: 如果 genpfault 因他投反对票的每一个问题而失去声誉,我认为他现在的声誉将是 0 ;) 它开始变得有点烦人,尽管我确实同意这一点案例 - 您问题中的某些语言非常不专业(不足以值得反对,但仍然不合适)。

标签: java opengl glsl libgdx


【解决方案1】:

我解决了这个问题..但我不知道为什么它解决了它。
感谢 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);
}   

如您所见,我添加到数组中的亮块和渲染的暗块,我在渲染循环之前将 uniform 设置为 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);
    }

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

谢谢:)

【讨论】:

    猜你喜欢
    • 2013-10-05
    • 2015-05-10
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多