2016-07-14 2 views
2

У меня, похоже, проблема с шейдером для работы в обработке. Я работаю над эффектом чернил, и, получив некоторую помощь, чтобы написать остальную часть шейдера, я, похоже, не могу ничего сделать. Цвет остается черным, и когда я изменяю gl_FragColor = vertColor; (который обрабатывает запасы для цвета), изображение становится белым. Из того, что я понимаю, он должен просто пройти прямо в этом случае, так что теперь я считаю, что что-то может быть неправильным. У кого-нибудь есть совет?Обработка фрагмента шейдера, не отображающего ничего

EDIT: Я внес некоторые изменения, чтобы попытаться сопоставить его ближе к тому, что я вижу в других обработчиках. Вместо vertColor теперь я использую sampler2D (source, coord) .rgb, который все еще не работает.

PShader shader; 
PImage photo; 

void setup() { 
    size(619,619,P2D); 
    photo = loadImage("paintedsky.jpg"); 
    shader = loadShader("inkspread.glsl"); 
} 

void draw() { 
    shader.set("T",(float) millis()/1000.0); 
    shader(shader); 
    image(photo,619,619); 
} 

#ifdef GL_ES 
precision mediump float; 
precision mediump int; 
#endif 

#define PROCESSING_TEXTURE_SHADER 

uniform sampler2D source; 
varying vec4 vertTexCoord; 

uniform float T; 
const float diag = 1.414213562373095; 

vec3 F(vec3 x0,vec3 x1,float dist){ 
    return (x1 - x0)/(T * dist); 
} 

void main() { 
    vec2 ix = vertTexCoord.st; 

    vec2 c11 = vertTexCoord.st + vec2(0.0, 0.0); 
    vec2 c01 = vertTexCoord.st + vec2(-1.0, 0.0); 
    vec2 c21 = vertTexCoord.st + vec2(1.0, 0.0); 
    vec2 c10 = vertTexCoord.st + vec2(0.0,-1.0); 
    vec2 c12 = vertTexCoord.st + vec2(0.0, 1.0); 
    vec2 c00 = vertTexCoord.st + vec2(-1.0,-1.0); 
    vec2 c02 = vertTexCoord.st + vec2(-1.0, 1.0); 
    vec2 c20 = vertTexCoord.st + vec2(1.0,-1.0); 
    vec2 c22 = vertTexCoord.st + vec2(1.0, 1.0); 

    vec3 x11 = texture2D(source, c11).rgb; 
    vec3 x01 = texture2D(source, c01).rgb; 
    vec3 x21 = texture2D(source, c21).rgb; 
    vec3 x10 = texture2D(source, c10).rgb; 
    vec3 x12 = texture2D(source, c12).rgb; 
    vec3 x00 = texture2D(source, c00).rgb; 
    vec3 x02 = texture2D(source, c02).rgb; 
    vec3 x20 = texture2D(source, c20).rgb; 
    vec3 x22 = texture2D(source, c22).rgb; 

    vec3 d01 = F(x11,x01,1.0); 
    vec3 d21 = F(x11,x21,1.0); 
    vec3 d10 = F(x11,x10,1.0); 
    vec3 d12 = F(x11,x12,1.0); 
    vec3 d00 = F(x11,x00,diag); 
    vec3 d02 = F(x11,x02,diag); 
    vec3 d20 = F(x11,x20,diag); 
    vec3 d22 = F(x11,x22,diag); 

    vec3 result = (x11 + d01+d21+d10+d12 + d00+d02+d20+d22); 

    vec3 col = texture2D(source, ix).rgb; 
    gl_FragColor = vec4(col*result,1.0); 
} 
+0

Какого эффекта вы пытаетесь достигли? Из приведенного выше кода я предполагаю, что 'T' является переменной с плавающей запятой. Кажется, он никогда не получает значения. Я предполагаю, что это означает, что он либо инициализирован нулем, либо рассматривается как нулевой указатель - возможно, у вас есть деление на ноль или какая-либо другая ошибка, возникающая из функции F(). Я не знаю, как работает glsl под капотом. – Nolo

+0

О, неважно. Мои извинения, я просто посмотрел на определение «униформа». – Nolo

+0

Не беспокойтесь, моя клиентская программа (Обработка) отправляет поплавок для T, который, кажется, не имеет проблем. – aceslowman

ответ

0

есть несколько проблем, с ваш код:

1) В inkspread.glsl вы определили uniform sampler2D source, однако у вас есть Установите эту форму на шейдер. Если вы хотите передать объект PImage или PGraphics в шейдер с помощью этой униформы, вам нужно будет позвонить shader.set("source", photo) так же, как вы проходите в T для времени. ОДНАКО, обработка уже дает вам текстуру бесплатно. Если вы измените source на texture на весь ваш файл шейдера, обработка автоматически перенесет основной холст рисунка в ваш шейдерный uniform sampler2D texture. Ваша переменная vertTexCoord - это еще одно специальное свойство, которое автоматически обрабатывает ваш фрагментарный шейдер. Есть еще несколько таких, но я не думаю, что они в настоящее время хорошо документированы.

2) Вторая проблема - это порядок вашего изображения() & shader() calls. Поскольку ваш шейдер предназначен для постобработки изображения, сначала вы хотите нарисовать изображение, а затем вызвать шейдер, чтобы действовать на основном холсте рисования. Тогда все должно работать должным образом. Это должно выглядеть так:

void draw() { 
    image(photo,619,619); 
    shader.set("T",(float) millis()/1000.0); 
    shader(shader); 
} 

Я проверил это исправление, и все работает. Я не уверен, каков предполагаемый эффект, но ваш шейдер дал моей фотографии хороший эффект затемнения/насыщения.

+0

Спасибо! У меня все еще есть работа, чтобы идти по самому шейдеру, но это помогло получить его на самом деле. – aceslowman

0

цвет остается черным, а при изменении gl_FragColor = vertColor; (который обрабатывает запасы для colro), изображение становится белым.

Я предполагаю, что vertColor является позицией вершины, интерпретируемой как цвет. В этом случае все выше 1 зажимается до 1, поэтому, если у вас есть вершинная позиция в (1,1,1), цвет белый. Если позиция вершины находится в точке (2,2,2), она будет зажата (1,1,1), и, следовательно, цвет снова станет белым. У вас должен быть не белый цвет, где по крайней мере одно из значений позиции равно < 1. Для целей тестирования вы можете попытаться масштабировать свой vertColor здесь от 0 (ранее наименьший из координат положения) до 1 (ранее самый высокий из вашей позиции coordiantes)

Я не могу ответить на ваш первоначальный вопрос, как вы делаете много вычислений с плавающей точкой, но нет никакого способа определить, что будет установлен как gl_FragColor

+0

Мне помогли вычисления с плавающей точкой, и я могу только предположить, что они представляют только один цветной канал (так что я должен просто изменить его на vec3 или что-то еще). Масштабирование vertColor кажется мне странным, просто потому, что в общем случае vertColor, похоже, обрабатывается так, как если бы он был 0 - 1 в других обработчиках Shaders, которые я видел. – aceslowman

+0

Я сделал обновление, используя sampler2D (source, coord) .rgb вместо vertColor, который по-прежнему имеет ту же проблему. – aceslowman

+0

попробуйте использовать 'verTexCoord.st' вместо ваших вычисленных значений' c' для чтения значений 'x'. в идеальном случае они не имеют видимого эффекта в любом случае, но сейчас они могут создавать проблемы, я не уверен в настройках по умолчанию для glsl. также попробуйте не использовать результат в gl_FragColor, чтобы посмотреть, не является ли результат не черным. – Tare

Смежные вопросы