Добрый вечер. Изучаю туториалы по шейдерам в Libgdx. Использую этот туториал. Пытаюсь нарисовать круг, получаю просто черную текстуру. Код шейдера ниже.
Шейдер
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
uniform sampler2D u_texture;
uniform vec2 u_resolution;
varying LOWP vec4 v_color;
varying vec2 v_texCoord0;
const float RADIUS = 0.75;
const float SOFTNESS = 0.45;
const vec3 SEPIA = vec3(1.2, 1.0, 0.8);
void main() {
vec4 texColor = texture2D(u_texture, v_texCoord0);
vec2 position = (gl_FragCoord.xy / u_resolution.xy) - vec2(0.5);
float len = length(position);
//gl_FragColor = texColor * v_color;
float r = 0.5;
float softness = 0.05;
gl_FragColor = vec4( vec3( smoothstep(r, r-softness, len) ), 1.0 );
}Класс
public class ShaderTest extends ApplicationAdapter {
private SpriteBatch batch;
private Texture img;
private ShaderProgram shaderProgram;
private OrthographicCamera cam;
@Override
public void create() {
batch = new SpriteBatch();
img = new Texture("scene.png");
ShaderProgram.pedantic = false;
shaderProgram = new ShaderProgram(Gdx.files.internal("shaders/lesson2.vp"), Gdx.files.internal("shaders/lesson3.fp"));
if (!shaderProgram.isCompiled()) {
System.out.println(shaderProgram.getLog());
}
batch.setShader(shaderProgram);
cam = new OrthographicCamera(img.getWidth(), img.getHeight());
cam.position.set(img.getWidth() / 2, img.getHeight() / 2, 0);
}
@Override
public void resize(int width, int height) {
System.out.println("resize");
cam.setToOrtho(false, width, height);
batch.setProjectionMatrix(cam.combined);
shaderProgram.begin();
shaderProgram.setUniformf("resolution", width, height);
shaderProgram.end();
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//batch.setProjectionMatrix(cam.combined);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
}
@Override
public void pause() {}
@Override
public void resume() {}
@Override
public void dispose() {
shaderProgram.dispose();
img.dispose();
batch.dispose();
}
}Я ни яву ни либгдх не знаю,
но чет я не пойму, как оно должно рисовать что-то, если ты в шейдер ничего не передаешь,
кроме как u_resolution, который передается только при изменении размеров окна?
Тебе же надо передать туда текстуру и разрешение окна.
Итого в create методе запили :
shaderProgram.begin();
shaderProgram.setUniformf("resolution", width, height);
shaderProgram.end();А в методе render:
img.bind(0); //<а текстурку то забиндить надо
batch.begin();
batch.draw(img, 0, 0);
batch.end();Это я бегло пробежался по твоей статье, может что-то упустил.
dmitryhryppa, там как бы все под LibGdx переделано, метод resize с передачей разрешения экрана запускается сразу после метода create и текстуры движок сам биндит.
Да? Ну это хорошо. Тогда просто поищи какая часть кода не работает...
Ну например в шейдере напиши:
gl_FragColor = texture2D(u_texture, v_texCoord0);
а остальные расчеты закоменти и посмотри выведется ли картинка.
Попробуй такой шейдер для отрисовки окружности диаметром, совпадающей с высотой экрана, и шириной "переходящей" части в 0.05
const float RADIUS = 0.5;
void main() {
vec4 texColor = texture2D(u_texture, vTexCoord);
vec2 position;
position.x = ((gl_FragCoord.x / resolution.x) - 0.5) * resolution.x/resolution.y; // иначе овал рисуется для неквадратного окна
position.y = ((gl_FragCoord.y / resolution.y) - 0.5 );
texColor.rgb = mix(texColor.rgb, texColor.rgb * smoothstep(RADIUS, RADIUS - 0.05, length(position)), 1.0); // здесь смешиваем цвет текстуры и интерполированное значение
gl_FragColor = texColor * vColor;
};Самое интересное происходит в smoothstep(RADIUS, RADIUS - 0.05, length(position))
Насколько я понял, то это записана следующая функция:
gl_FragColor = smoothstep(RADIUS, RADIUS - 0.05, length(position)) * vColor
Всё это в уроке описано: и почему надо координаты поправить и как smoothstep работает. В коде для LibGdx перерасчета координат нет.
P.S. Спасибо за ссыль на мануал. Нравится как мужик пишет, потому хоть немного с шейдерами разобрался :D
Тема в архиве.