我正在尝试制作一个照明系统,程序改变纹理(块)亮度取决于它获得的光,并且程序为播放器可见的每个块(纹理)执行此操作。
然而,照明系统工作得很好,但是当使用着色器进行渲染时,一切都会被破坏。
此代码位于渲染循环中 -
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;
}
答案 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);
}
现在我渲染了明亮的块并且它起作用..结果很好。
但是我不知道它为什么会这样,就像将渲染循环切割成两个,一个用于暗块,一个用于亮块。
谢谢:)