Недавно я использовал шейдер Глубина поля ниже (первоначально из библиотеки ofxPostProcessing для OpenFrameworks) для моих эскизов Обработки.
deep.glsl
uniform float maxDepth;
void main() {
float depth = gl_FragCoord.z / gl_FragCoord.w;
gl_FragColor = vec4(vec3(1.0 - depth/maxDepth), 1.0);
}
dof.glsl
uniform sampler2D texture;
varying vec4 vertexture;
varying vec4 vertTexCoord;
uniform sampler2D tDepth;
uniform float maxBlur; // max blur amount
uniform float aperture; // aperture - bigger values for shallower depth of field
uniform float focus;
uniform float aspect;
void main() {
vec2 vUv = vertTexCoord.st;
vec2 aspectcorrect = vec2( 1.0, aspect );
vec4 depth1 = texture2D( tDepth, vUv );
float factor = depth1.x - focus;
vec2 dofblur = vec2 ( clamp( factor * aperture, -maxBlur, maxBlur ) );
vec2 dofblur9 = dofblur * 0.9;
vec2 dofblur7 = dofblur * 0.7;
vec2 dofblur4 = dofblur * 0.4;
vec4 col = vec4( 0.0 );
col += texture2D( texture, vUv.xy );
col += texture2D( texture, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );
col += texture2D( texture, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
col += texture2D( texture, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );
col += texture2D( texture, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
col += texture2D( texture, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );
gl_FragColor = col / 41.0;
gl_FragColor.a = 1.0;
}
Эффект DOF отлично работает с такими примитивами, какBOX
или SPHERE
(см. Пример скриншота ниже), но, к сожалению, не работает, когда дело доходит до отображения POINT
и STROKE
(одинаковое количество размытия для каждой точки, независимо от того, как далекоони от камеры).
Я думаю, что это связано с тем фактом, что точки и обводки нельзя контролировать с помощью цветного шейдера, но я не могу сказать наверняка, так как я все еще новичок в шейдерахв общем.
Вопросы :
- Можно ли настроить шейдеры выше, чтобы они работали с точками / штрихами, или мне нужно использовать/ написать совершенно другой шейдер глубины поля для этих специфических примитивов?
- Если возможен простой твик, не могли бы вы помочь мне выяснить, что мне нужно добавить / изменить, чтобы заставить его работать с точками?
Любое предложение будет с благодарностью.
Thank you
Пример эскиза (необходим режим Python + библиотека PeasyCam)
add_library('peasycam')
colors, liste = [[0,189,202], [251,183,0], [255,17,79], [252,128,35], [0,108,254]], []
def setup():
global depthShader, dofShader, cam, buf1, buf2, buf3, pnt
size(900, 900, P3D)
frameRate(1000)
cam = PeasyCam(this, 900)
cam.setMaximumDistance(width)
pnt = createShape(BOX, 30)
pnt.setStroke(False)
depthShader, dofShader = loadShader("depth.glsl"), loadShader("dof.glsl")
depthShader.set("maxDepth", cam.getDistance()*2)
dofShader.set("aspect", width / float(height)), dofShader.set("maxBlur", 0.02), dofShader.set("aperture", 0.06)
buf1, buf2, buf3 = [createGraphics(width, height, P3D) for e in range(3)]
buf1.smooth(8), buf2.shader(depthShader), buf3.shader(dofShader)
for e in range(300): liste.append(PVector(random(width), random(height), random(width)))
def drawScene(pg):
pg.beginDraw()
pg.background(0)
for i in range(len(liste)):
pg.pushMatrix()
pg.translate(liste[i].x-width/2, liste[i].y-width/2, liste[i].z-width/2)
pg.shape(pnt)
pnt.setFill(color(colors[i%5][0], colors[i%5][1], colors[i%5][2]))
pg.popMatrix()
pg.endDraw()
cam.getState().apply(pg)
def draw():
drawScene(buf1)
drawScene(buf2)
buf3.beginDraw()
dofShader.set("tDepth", buf2)
dofShader.set("focus", map(mouseX, 0, width, .3, 1))
buf3.image(buf1, 0, 0)
buf3.endDraw()
cam.beginHUD()
image(buf3, 0, 0)
cam.endHUD()