2011-11-17 21 views
37

iOS için bir 3D uygulaması yazıyorum. OpenGL ES 2.0'da yeniyim, bu yüzden hala temel gölgelendiriciler yazarken kendimi alıyorum. Modellerimin bazılarında, tekstüre bazında bir "Glow" efekti kullanmam gerekiyor.OpenGL ES 2.0'da "Glow" gölgelendirici efekti nasıl edinilir?

Bloom/Glow from www.skillmanmedia.com/realbasic/bloomsnapshot.jpg :

İşte bir örnek verilmektedir.

OpenGL ES 2.0 için kod örnekleri arıyorum. İnternette bulduğum çoğu kod ya masaüstü OpenGL ya da D3D için.

Herhangi bir fikrin var mı?

+5

Shader efektleri opengl ES 2.0 ile masaüstü opengl arasında çok az farklılık gösterir. İstediğiniz şeyi yapan iyi bir öğretici bulursanız, onu taşımanız önemsiz olmalıdır. – NickLH

+0

Güveniniz için teşekkürler, bu beni rahatsız eden başka bir şeydi. Bazı (genellikle eski) örnekler, ES belgelerinde bulunamadığım girdi/çıktı değişkenlerini kullanır. Kazmaya devam edeceğim, ancak iyi örneklerin çoğu benim araştırmalarımda ve GLSL'nin nasıl kullanılacağının anlaşılmasında bir sıçramadır. –

+0

Bunun için herhangi bir Android kodunun var mı? – Burf2000

cevap

1

Web sitesi GLSL Sandbox, shader örnekleri içeren bir koleksiyona sahiptir. This one has the glow and appears to be able to compile for ES.

Uv'leri dokudan çekmek için bunları değiştirebilmeniz gerekir.

İşte algoritmalar ve bir parlaklık etkisi oluşturmak için teknikler ton vardır hepsinden some code directly from this site:

#ifdef GL_ES 
precision mediump float; 
#endif 

#extension GL_OES_standard_derivatives : enable 

uniform float time; 
uniform vec2 mouse; 
uniform vec2 resolution; 

void main(void){ 

    vec2 p = (gl_FragCoord.xy * 2.0 - resolution)/min(resolution.x, resolution.y); 
    vec3 color1 = vec3(0.0, 0.3, 0.5); 
    vec3 color2 = vec3(0.5, 0.0, 0.3); 

    float f = 0.0; 
    float g = 0.0; 
    float h = 0.0; 
    float PI = 3.14159265; 
    for(float i = 0.0; i < 40.0; i++){ 
     if (floor(mouse.x * 41.0) < i) 
      break; 
     float s = sin(time + i * PI/20.0) * 0.8; 
     float c = cos(time + i * PI/20.0) * 0.8; 
     float d = abs(p.x + c); 
     float e = abs(p.y + s); 
     f += 0.001/d; 
     g += 0.001/e; 
     h += 0.00003/(d * e); 
    } 


    gl_FragColor = vec4(f * color1 + g * color2 + vec3(h), 1.0); 
} 
2

İlk olduğunu. Sadece bir olasılık sunmak istiyorum.

Öncelikle kendinden aydınlatmalı bir Malzeme oluşturmanız gerekir. Bunun için ışık kaynağına yön her zaman parçanın normal vektörünün tersi yönü olan modifiye blinn-phong ışık modeli kullanın.

varying vec3 vertPos; 
varying vec3 vertNV; 
varying vec3 vertCol; 

void main() 
{ 
    vec3 color = vertCol; 

    float shininess = 10.0; 
    vec3 normalV = normalize(vertNV); 
    vec3 eyeV = normalize(-vertPos); 
    vec3 halfV = normalize(eyeV + normalV); 
    float NdotH = max(0.0, dot(normalV, halfV)); 
    float glowFac = (shininess + 2.0) * pow(NdotH, shininess)/(2.0 * 3.14159265); 

    gl_FragColor = vec4(color.rgb * (0.5 + glowFac), 1.0); 
} 

İkinci adımda, çıktıda bir gauss bulanıklaştırma algoritması gerçekleştirilir. Sahne, renk düzlemine bağlı bir doku ile çerçeve arabelleğine yazılır. Bir ekran boşluk geçişi, çıktıyı bulanıklaştırmak için giriş olarak dokuyu kullanır.
Performans nedenleriyle, bulanıklık algoritması ilk önce görünümün X ekseni boyunca ve görünümün Y ekseni boyunca bir sonraki adımda gerçekleştirilir.
Bulanıklaştırma algoritmasının ayrıntılı bir açıklaması, OpenGL es 2.0 Gaussian blur on triangle numaralı sorunun yanıtında bulunabilir. Aşağıdaki soruya

varying vec2 vertPos; 
uniform sampler2D u_textureCol; 
uniform vec2 u_textureSize; 
uniform float u_sigma; 
uniform int u_width; 

float CalcGauss(float x, float sigma) 
{ 
    float coeff = 1.0/(2.0 * 3.14157 * sigma); 
    float expon = -(x*x)/(2.0 * sigma); 
    return (coeff*exp(expon)); 
} 

void main() 
{ 
    vec2 texC = vertPos.st * 0.5 + 0.5; 
    vec4 texCol = texture(u_textureCol, texC); 
    vec4 gaussCol = vec4(texCol.rgb, 1.0); 
    vec2 step = 1.0/u_textureSize; 
    for (int i = 1; i <= u_width; ++ i) 
    { 
     vec2 actStep = vec2(float(i) * step.x, 0.0); // this is for the X-axis 
     // vec2 actStep = vec2(0.0, float(i) * step.y); this would be for the Y-axis 

     float weight = CalcGauss(float(i)/float(u_width), u_sigma); 
     texCol = texture2D(u_textureCol, texC + actStep);  
     gaussCol += vec4(texCol.rgb * weight, weight); 
     texCol = texture2D(u_textureCol, texC - actStep); 
     gaussCol += vec4(texCol.rgb * weight, weight); 
    } 
    gaussCol.rgb /= gaussCol.w; 
    gl_FragColor = vec4(gaussCol.rgb, 1.0); 
} 

Ayrıca bkz cevaplar:

hep birlikte koyar aşağıdaki benzer WebGL örneğe bakın:

var readInput = true; 
 
function changeEventHandler(event){ 
 
    readInput = true; 
 
} 
 
    
 
(function loadscene() { 
 
    
 
    var resize, gl, progDraw, progBlurX, progPost, vp_size, blurFB; 
 
    var bufCube = {}; 
 
    var bufQuad = {}; 
 
    var shininess = 10.0; 
 
    var glow = 10.0; 
 
    var sigma = 0.8; 
 
    
 
    function render(delteMS){ 
 

 
     if (readInput) { 
 
      readInput = false; 
 
      var sliderScale = 100; 
 
      shininess = document.getElementById("shine").value; 
 
      glow  = document.getElementById("glow").value/sliderScale; 
 
      sigma  = document.getElementById("sigma").value/sliderScale; 
 
     } 
 

 
     Camera.create(); 
 
     Camera.vp = vp_size; 
 
      
 
     gl.enable(gl.DEPTH_TEST); 
 
     gl.clearColor(0.0, 0.0, 0.0, 1.0); 
 
     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
 

 
     // set up framebuffer 
 
     gl.bindFramebuffer(gl.FRAMEBUFFER, blurFB[0]); 
 
     gl.viewport(0, 0, blurFB[0].width, blurFB[0].height); 
 
     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
 
    
 
     // set up draw shader 
 
     ShaderProgram.Use(progDraw.prog); 
 
     ShaderProgram.SetUniformM44(progDraw.prog, "u_projectionMat44", Camera.Perspective()); 
 
     ShaderProgram.SetUniformM44(progDraw.prog, "u_viewMat44", Camera.LookAt()); 
 
     var modelMat = IdentityMat44() 
 
     modelMat = RotateAxis(modelMat, CalcAng(delteMS, 13.0), 0); 
 
     modelMat = RotateAxis(modelMat, CalcAng(delteMS, 17.0), 1); 
 
     ShaderProgram.SetUniformM44(progDraw.prog, "u_modelMat44", modelMat); 
 
     ShaderProgram.SetUniformF1(progDraw.prog, "u_shininess", shininess); 
 
     ShaderProgram.SetUniformF1(progDraw.prog, "u_glow", glow); 
 
     
 
     // draw scene 
 
     VertexBuffer.Draw(bufCube); 
 

 
     // set blur-X framebuffer and bind frambuffer texture 
 
     gl.bindFramebuffer(gl.FRAMEBUFFER, blurFB[1]); 
 
     gl.viewport(0, 0, blurFB[1].width, blurFB[1].height); 
 
     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
 
     var texUnit = 1; 
 
     gl.activeTexture(gl.TEXTURE0 + texUnit); 
 
     gl.bindTexture(gl.TEXTURE_2D, blurFB[0].color0_texture); 
 

 
     // set up blur-X shader 
 
     ShaderProgram.Use(progBlurX.prog); 
 
     ShaderProgram.SetUniformI1(progBlurX.prog , "u_texture", texUnit) 
 
     ShaderProgram.SetUniformF2(progBlurX.prog , "u_textureSize", vp_size); 
 
     ShaderProgram.SetUniformF1(progBlurX.prog , "u_sigma", sigma) 
 

 
     // draw full screen space 
 
     gl.enableVertexAttribArray(progBlurX.inPos); 
 
     gl.bindBuffer(gl.ARRAY_BUFFER, bufQuad.pos); 
 
     gl.vertexAttribPointer(progBlurX.inPos, 2, gl.FLOAT, false, 0, 0); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx); 
 
     gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 
 
     gl.disableVertexAttribArray(progBlurX.inPos); 
 

 
     // reset framebuffer and bind frambuffer texture 
 
     gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
 
     gl.viewport(0, 0, vp_size[0], vp_size[1]); 
 
     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
 
     texUnit = 2; 
 
     gl.activeTexture(gl.TEXTURE0 + texUnit); 
 
     gl.bindTexture(gl.TEXTURE_2D, blurFB[1].color0_texture); 
 

 
     // set up pst process shader 
 
     ShaderProgram.Use(progPost.prog); 
 
     ShaderProgram.SetUniformI1(progPost.prog, "u_texture", texUnit) 
 
     ShaderProgram.SetUniformF2(progPost.prog, "u_textureSize", vp_size); 
 
     ShaderProgram.SetUniformF1(progPost.prog, "u_sigma", sigma); 
 

 
     // draw full screen space 
 
     gl.enableVertexAttribArray(progPost.inPos); 
 
     gl.bindBuffer(gl.ARRAY_BUFFER, bufQuad.pos); 
 
     gl.vertexAttribPointer(progPost.inPos, 2, gl.FLOAT, false, 0, 0); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx); 
 
     gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 
 
     gl.disableVertexAttribArray(progPost.inPos); 
 

 
     requestAnimationFrame(render); 
 
    } 
 
    
 
    function resize() { 
 
     //vp_size = [gl.drawingBufferWidth, gl.drawingBufferHeight]; 
 
     vp_size = [window.innerWidth, window.innerHeight] 
 
     canvas.width = vp_size[0]; 
 
     canvas.height = vp_size[1]; 
 

 
     var fbsize = Math.max(vp_size[0], vp_size[1])-1; 
 
     fbsize = 1 << 31 - Math.clz32(fbsize); // nearest power of 2 
 
     fbsize = fbsize * 2 
 

 
     blurFB = []; 
 
     for (var i = 0; i < 2; ++ i) { 
 
      fb = gl.createFramebuffer(); 
 
      fb.width = fbsize; 
 
      fb.height = fbsize; 
 
      gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 
 
      fb.color0_texture = gl.createTexture(); 
 
      gl.bindTexture(gl.TEXTURE_2D, fb.color0_texture); 
 
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
 
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
 
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, fb.width, fb.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 
 
      fb.renderbuffer = gl.createRenderbuffer(); 
 
      gl.bindRenderbuffer(gl.RENDERBUFFER, fb.renderbuffer); 
 
      gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, fb.width, fb.height); 
 
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fb.color0_texture, 0); 
 
      gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, fb.renderbuffer); 
 
      gl.bindTexture(gl.TEXTURE_2D, null); 
 
      gl.bindRenderbuffer(gl.RENDERBUFFER, null); 
 
      gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
 
      blurFB.push(fb); 
 
     } 
 
    } 
 
    
 
    function initScene() { 
 
    
 
     canvas = document.getElementById("canvas"); 
 
     gl = canvas.getContext("experimental-webgl"); 
 
     if (!gl) 
 
     return null; 
 
    
 
     progDraw = {} 
 
     progDraw.prog = ShaderProgram.Create( 
 
     [ { source : "draw-shader-vs", stage : gl.VERTEX_SHADER }, 
 
      { source : "draw-shader-fs", stage : gl.FRAGMENT_SHADER } 
 
     ]); 
 
     if (!progDraw.prog) 
 
      return null; 
 
     progDraw.inPos = gl.getAttribLocation(progDraw.prog, "inPos"); 
 
     progDraw.inNV = gl.getAttribLocation(progDraw.prog, "inNV"); 
 
     progDraw.inCol = gl.getAttribLocation(progDraw.prog, "inCol"); 
 

 
     progBlurX = {} 
 
     progBlurX.prog = ShaderProgram.Create( 
 
     [ { source : "post-shader-vs", stage : gl.VERTEX_SHADER }, 
 
      { source : "blurX-shader-fs", stage : gl.FRAGMENT_SHADER } 
 
     ]); 
 
     progBlurX.inPos = gl.getAttribLocation(progBlurX.prog, "inPos"); 
 
     if (!progBlurX.prog) 
 
      return;  
 

 
     progPost = {} 
 
     progPost.prog = ShaderProgram.Create( 
 
     [ { source : "post-shader-vs", stage : gl.VERTEX_SHADER }, 
 
      { source : "blurY-shader-fs", stage : gl.FRAGMENT_SHADER } 
 
     ]); 
 
     progPost.inPos = gl.getAttribLocation(progPost.prog, "inPos"); 
 
     if (!progPost.prog) 
 
      return; 
 
     
 
     // create cube 
 
     var cubePos = [ 
 
     -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 
 
     -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 ]; 
 
     var cubeCol = [ 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ]; 
 
     var cubeHlpInx = [ 0, 1, 2, 3, 1, 5, 6, 2, 5, 4, 7, 6, 4, 0, 3, 7, 3, 2, 6, 7, 1, 0, 4, 5 ]; 
 
     var cubePosData = []; 
 
     for (var i = 0; i < cubeHlpInx.length; ++ i) { 
 
     cubePosData.push(cubePos[cubeHlpInx[i]*3], cubePos[cubeHlpInx[i]*3+1], cubePos[cubeHlpInx[i]*3+2]); 
 
     } 
 
     var cubeNVData = []; 
 
     for (var i1 = 0; i1 < cubeHlpInx.length; i1 += 4) { 
 
     var nv = [0, 0, 0]; 
 
     for (i2 = 0; i2 < 4; ++ i2) { 
 
      var i = i1 + i2; 
 
      nv[0] += cubePosData[i*3]; nv[1] += cubePosData[i*3+1]; nv[2] += cubePosData[i*3+2]; 
 
     } 
 
     for (i2 = 0; i2 < 4; ++ i2) 
 
     cubeNVData.push(nv[0], nv[1], nv[2]); 
 
     } 
 
     var cubeColData = []; 
 
     for (var is = 0; is < 6; ++ is) { 
 
     for (var ip = 0; ip < 4; ++ ip) { 
 
     cubeColData.push(cubeCol[is*3], cubeCol[is*3+1], cubeCol[is*3+2]); 
 
     } 
 
     } 
 
     var cubeInxData = []; 
 
     for (var i = 0; i < cubeHlpInx.length; i += 4) { 
 
     cubeInxData.push(i, i+1, i+2, i, i+2, i+3); 
 
     } 
 
     bufCube = VertexBuffer.Create(
 
     [ { data : cubePosData, attrSize : 3, attrLoc : progDraw.inPos }, 
 
     { data : cubeNVData, attrSize : 3, attrLoc : progDraw.inNV }, 
 
     { data : cubeColData, attrSize : 3, attrLoc : progDraw.inCol } ], 
 
     cubeInxData); 
 

 
     bufQuad.pos = gl.createBuffer(); 
 
     gl.bindBuffer(gl.ARRAY_BUFFER, bufQuad.pos); 
 
     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ]), gl.STATIC_DRAW); 
 
     bufQuad.inx = gl.createBuffer(); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx); 
 
     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([ 0, 1, 2, 0, 2, 3 ]), gl.STATIC_DRAW); 
 
     
 
     window.onresize = resize; 
 
     resize(); 
 
     requestAnimationFrame(render); 
 
    } 
 
    
 
    function Fract(val) { 
 
     return val - Math.trunc(val); 
 
    } 
 
    function CalcAng(deltaTime, intervall) { 
 
     return Fract(deltaTime/(1000*intervall)) * 2.0 * Math.PI; 
 
    } 
 
    function CalcMove(deltaTime, intervall, range) { 
 
     var pos = self.Fract(deltaTime/(1000*intervall)) * 2.0 
 
     var pos = pos < 1.0 ? pos : (2.0-pos) 
 
     return range[0] + (range[1] - range[0]) * pos; 
 
    }  
 
    function EllipticalPosition(a, b, angRag) { 
 
     var a_b = a * a - b * b 
 
     var ea = (a_b <= 0) ? 0 : Math.sqrt(a_b); 
 
     var eb = (a_b >= 0) ? 0 : Math.sqrt(-a_b); 
 
     return [ a * Math.sin(angRag) - ea, b * Math.cos(angRag) - eb, 0 ]; 
 
    } 
 
    
 
    glArrayType = typeof Float32Array !="undefined" ? Float32Array : (typeof WebGLFloatArray != "undefined" ? WebGLFloatArray : Array); 
 
    
 
    function IdentityMat44() { 
 
    var m = new glArrayType(16); 
 
    m[0] = 1; m[1] = 0; m[2] = 0; m[3] = 0; 
 
    m[4] = 0; m[5] = 1; m[6] = 0; m[7] = 0; 
 
    m[8] = 0; m[9] = 0; m[10] = 1; m[11] = 0; 
 
    m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; 
 
    return m; 
 
    }; 
 
    
 
    function RotateAxis(matA, angRad, axis) { 
 
     var aMap = [ [1, 2], [2, 0], [0, 1] ]; 
 
     var a0 = aMap[axis][0], a1 = aMap[axis][1]; 
 
     var sinAng = Math.sin(angRad), cosAng = Math.cos(angRad); 
 
     var matB = new glArrayType(16); 
 
     for (var i = 0; i < 16; ++ i) matB[i] = matA[i]; 
 
     for (var i = 0; i < 3; ++ i) { 
 
      matB[a0*4+i] = matA[a0*4+i] * cosAng + matA[a1*4+i] * sinAng; 
 
      matB[a1*4+i] = matA[a0*4+i] * -sinAng + matA[a1*4+i] * cosAng; 
 
     } 
 
     return matB; 
 
    } 
 
    
 
    function Cross(a, b) { return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], 0.0 ]; } 
 
    function Dot(a, b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } 
 
    function Normalize(v) { 
 
     var len = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 
 
     return [ v[0]/len, v[1]/len, v[2]/len ]; 
 
    } 
 
    
 
    var Camera = {}; 
 
    Camera.create = function() { 
 
     this.pos = [0, 3, 0.0]; 
 
     this.target = [0, 0, 0]; 
 
     this.up  = [0, 0, 1]; 
 
     this.fov_y = 90; 
 
     this.vp  = [800, 600]; 
 
     this.near = 0.5; 
 
     this.far = 100.0; 
 
    } 
 
    Camera.Perspective = function() { 
 
     var fn = this.far + this.near; 
 
     var f_n = this.far - this.near; 
 
     var r = this.vp[0]/this.vp[1]; 
 
     var t = 1/Math.tan(Math.PI * this.fov_y/360); 
 
     var m = IdentityMat44(); 
 
     m[0] = t/r; m[1] = 0; m[2] = 0;        m[3] = 0; 
 
     m[4] = 0; m[5] = t; m[6] = 0;        m[7] = 0; 
 
     m[8] = 0; m[9] = 0; m[10] = -fn/f_n;      m[11] = -1; 
 
     m[12] = 0; m[13] = 0; m[14] = -2 * this.far * this.near/f_n; m[15] = 0; 
 
     return m; 
 
    } 
 
    Camera.LookAt = function() { 
 
     var mz = Normalize([ this.pos[0]-this.target[0], this.pos[1]-this.target[1], this.pos[2]-this.target[2] ]); 
 
     var mx = Normalize(Cross(this.up, mz)); 
 
     var my = Normalize(Cross(mz, mx)); 
 
     var tx = Dot(mx, this.pos); 
 
     var ty = Dot(my, this.pos); 
 
     var tz = Dot([-mz[0], -mz[1], -mz[2]], this.pos); 
 
     var m = IdentityMat44(); 
 
     m[0] = mx[0]; m[1] = my[0]; m[2] = mz[0]; m[3] = 0; 
 
     m[4] = mx[1]; m[5] = my[1]; m[6] = mz[1]; m[7] = 0; 
 
     m[8] = mx[2]; m[9] = my[2]; m[10] = mz[2]; m[11] = 0; 
 
     m[12] = tx; m[13] = ty; m[14] = tz; m[15] = 1; 
 
     return m; 
 
    } 
 
    
 
    var ShaderProgram = {}; 
 
    ShaderProgram.Create = function(shaderList) { 
 
     var shaderObjs = []; 
 
     for (var i_sh = 0; i_sh < shaderList.length; ++ i_sh) { 
 
      var shderObj = this.CompileShader(shaderList[i_sh].source, shaderList[i_sh].stage); 
 
      if (shderObj == 0) 
 
       return 0; 
 
      shaderObjs.push(shderObj); 
 
     } 
 
     var progObj = this.LinkProgram(shaderObjs) 
 
     if (progObj != 0) { 
 
      progObj.attribIndex = {}; 
 
      var noOfAttributes = gl.getProgramParameter(progObj, gl.ACTIVE_ATTRIBUTES); 
 
      for (var i_n = 0; i_n < noOfAttributes; ++ i_n) { 
 
       var name = gl.getActiveAttrib(progObj, i_n).name; 
 
       progObj.attribIndex[name] = gl.getAttribLocation(progObj, name); 
 
      } 
 
      progObj.unifomLocation = {}; 
 
      var noOfUniforms = gl.getProgramParameter(progObj, gl.ACTIVE_UNIFORMS); 
 
      for (var i_n = 0; i_n < noOfUniforms; ++ i_n) { 
 
       var name = gl.getActiveUniform(progObj, i_n).name; 
 
       progObj.unifomLocation[name] = gl.getUniformLocation(progObj, name); 
 
      } 
 
     } 
 
     return progObj; 
 
    } 
 
    ShaderProgram.AttributeIndex = function(progObj, name) { return progObj.attribIndex[name]; } 
 
    ShaderProgram.UniformLocation = function(progObj, name) { return progObj.unifomLocation[name]; } 
 
    ShaderProgram.Use = function(progObj) { gl.useProgram(progObj); } 
 
    ShaderProgram.SetUniformI1 = function(progObj, name, val) { if(progObj.unifomLocation[name]) gl.uniform1i(progObj.unifomLocation[name], val); } 
 
    ShaderProgram.SetUniformF1 = function(progObj, name, val) { if(progObj.unifomLocation[name]) gl.uniform1f(progObj.unifomLocation[name], val); } 
 
    ShaderProgram.SetUniformF2 = function(progObj, name, arr) { if(progObj.unifomLocation[name]) gl.uniform2fv(progObj.unifomLocation[name], arr); } 
 
    ShaderProgram.SetUniformF3 = function(progObj, name, arr) { if(progObj.unifomLocation[name]) gl.uniform3fv(progObj.unifomLocation[name], arr); } 
 
    ShaderProgram.SetUniformF4 = function(progObj, name, arr) { if(progObj.unifomLocation[name]) gl.uniform4fv(progObj.unifomLocation[name], arr); } 
 
    ShaderProgram.SetUniformM33 = function(progObj, name, mat) { if(progObj.unifomLocation[name]) gl.uniformMatrix3fv(progObj.unifomLocation[name], false, mat); } 
 
    ShaderProgram.SetUniformM44 = function(progObj, name, mat) { if(progObj.unifomLocation[name]) gl.uniformMatrix4fv(progObj.unifomLocation[name], false, mat); } 
 
    ShaderProgram.CompileShader = function(source, shaderStage) { 
 
     var shaderScript = document.getElementById(source); 
 
     if (shaderScript) 
 
     source = shaderScript.text; 
 
     var shaderObj = gl.createShader(shaderStage); 
 
     gl.shaderSource(shaderObj, source); 
 
     gl.compileShader(shaderObj); 
 
     var status = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS); 
 
     if (!status) alert(gl.getShaderInfoLog(shaderObj)); 
 
     return status ? shaderObj : null; 
 
    } 
 
    ShaderProgram.LinkProgram = function(shaderObjs) { 
 
     var prog = gl.createProgram(); 
 
     for (var i_sh = 0; i_sh < shaderObjs.length; ++ i_sh) 
 
      gl.attachShader(prog, shaderObjs[i_sh]); 
 
     gl.linkProgram(prog); 
 
     status = gl.getProgramParameter(prog, gl.LINK_STATUS); 
 
     if (!status) alert("Could not initialise shaders"); 
 
     gl.useProgram(null); 
 
     return status ? prog : null; 
 
    } 
 
    
 
    var VertexBuffer = {}; 
 
    VertexBuffer.Create = function(attributes, indices) { 
 
     var buffer = {}; 
 
     buffer.buf = []; 
 
     buffer.attr = [] 
 
     for (var i = 0; i < attributes.length; ++ i) { 
 
      buffer.buf.push(gl.createBuffer()); 
 
      buffer.attr.push({ size : attributes[i].attrSize, loc : attributes[i].attrLoc }); 
 
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer.buf[i]); 
 
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributes[i].data), gl.STATIC_DRAW); 
 
     } 
 
     buffer.inx = gl.createBuffer(); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer.inx); 
 
     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 
 
     buffer.inxLen = indices.length; 
 
     gl.bindBuffer(gl.ARRAY_BUFFER, null); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 
 
     return buffer; 
 
    } 
 
    VertexBuffer.Draw = function(bufObj) { 
 
    for (var i = 0; i < bufObj.buf.length; ++ i) { 
 
      gl.bindBuffer(gl.ARRAY_BUFFER, bufObj.buf[i]); 
 
      gl.vertexAttribPointer(bufObj.attr[i].loc, bufObj.attr[i].size, gl.FLOAT, false, 0, 0); 
 
      gl.enableVertexAttribArray(bufObj.attr[i].loc); 
 
     } 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufObj.inx); 
 
     gl.drawElements(gl.TRIANGLES, bufObj.inxLen, gl.UNSIGNED_SHORT, 0); 
 
     for (var i = 0; i < bufObj.buf.length; ++ i) 
 
     gl.disableVertexAttribArray(bufObj.attr[i].loc); 
 
     gl.bindBuffer(gl.ARRAY_BUFFER, null); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 
 
    } 
 
    
 
    initScene(); 
 
    
 
})();
html,body { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0; 
 
    overflow: hidden; 
 
} 
 

 
#gui { 
 
    position : absolute; 
 
    top : 0; 
 
    left : 0; 
 
}
<script id="draw-shader-vs" type="x-shader/x-vertex"> 
 
    precision highp float; 
 
    
 
    attribute vec3 inPos; 
 
    attribute vec3 inNV; 
 
    attribute vec3 inCol; 
 
    
 
    varying vec3 vertPos; 
 
    varying vec3 vertNV; 
 
    varying vec3 vertCol; 
 
    
 
    uniform mat4 u_projectionMat44; 
 
    uniform mat4 u_viewMat44; 
 
    uniform mat4 u_modelMat44; 
 
    
 
    void main() 
 
    { 
 
     mat4 mv  = u_viewMat44 * u_modelMat44; 
 
     vertCol  = inCol; 
 
     vertNV  = normalize(mat3(mv) * inNV); 
 
     vec4 viewPos = mv * vec4(inPos, 1.0); 
 
     vertPos  = viewPos.xyz; 
 
     gl_Position = u_projectionMat44 * viewPos; 
 
    } 
 
</script> 
 
    
 
<script id="draw-shader-fs" type="x-shader/x-fragment"> 
 
    precision mediump float; 
 

 
    varying vec3 vertPos; 
 
    varying vec3 vertNV; 
 
    varying vec3 vertCol; 
 
    
 
    uniform float u_shininess; 
 
    uniform float u_glow; 
 
    
 
    void main() 
 
    { 
 
     vec3 color = vertCol; 
 
     vec3 normalV = normalize(vertNV); 
 
     vec3 eyeV  = normalize(-vertPos); 
 
     vec3 halfV = normalize(eyeV + normalV); 
 
     float NdotH = max(0.0, dot(normalV, halfV)); 
 
     float shineFac = (u_shininess + 2.0) * pow(NdotH, u_shininess)/(2.0 * 3.14159265); 
 
     gl_FragColor = vec4(color.rgb * u_glow * shineFac * 0.5, 1.0); 
 
    } 
 
</script> 
 
    
 
<script id="post-shader-vs" type="x-shader/x-vertex"> 
 
    precision mediump float; 
 
    
 
    attribute vec2 inPos; 
 
    
 
    varying vec2 pos; 
 
    
 
    void main() 
 
    { 
 
     pos = inPos; 
 
     gl_Position = vec4(inPos, 0.0, 1.0); 
 
    } 
 
</script> 
 
    
 
<script id="blurX-shader-fs" type="x-shader/x-fragment"> 
 
    precision mediump float; 
 
    
 
    varying vec2 pos; 
 
    
 
    uniform sampler2D u_texture; 
 
    uniform vec2  u_textureSize; 
 
    uniform float  u_sigma; 
 
    
 
    float CalcGauss(float x, float sigma) 
 
    { 
 
     float coeff = 1.0/(2.0 * 3.14157 * sigma); 
 
     float expon = -(x*x)/(2.0 * sigma); 
 
     return (coeff*exp(expon)); 
 
    } 
 
    
 
    void main() 
 
    { 
 
     vec2 texC = pos.st * 0.5 + 0.5; 
 
     vec4 texCol = texture2D(u_texture, texC); 
 
     vec4 gaussCol = vec4(texCol.rgb, 1.0); 
 
     float stepX = 1.0/u_textureSize.x; 
 
     for (int i = 1; i <= 20; ++ i) 
 
     { 
 
      float weight = CalcGauss(float(i)/32.0, u_sigma * 0.5); 
 
      texCol = texture2D(u_texture, texC + vec2(float(i) * stepX, 0.0)); 
 
      gaussCol += vec4(texCol.rgb * weight, weight); 
 
      texCol = texture2D(u_texture, texC - vec2(float(i) * stepX, 0.0)); 
 
      gaussCol += vec4(texCol.rgb * weight, weight); 
 
     } 
 
     gaussCol.rgb /= gaussCol.w; 
 
     gl_FragColor = vec4(gaussCol.rgb, 1.0); 
 
    } 
 
</script> 
 
    
 
<script id="blurY-shader-fs" type="x-shader/x-fragment"> 
 
    precision mediump float; 
 
    
 
    varying vec2 pos; 
 
    
 
    uniform sampler2D u_texture; 
 
    uniform vec2  u_textureSize; 
 
    uniform float  u_sigma; 
 
    
 
    float CalcGauss(float x, float sigma) 
 
    { 
 
     float coeff = 1.0/(2.0 * 3.14157 * sigma); 
 
     float expon = -(x*x)/(2.0 * sigma); 
 
     return (coeff*exp(expon)); 
 
    } 
 
    
 
    void main() 
 
    { 
 
     vec2 texC = pos.st * 0.5 + 0.5; 
 
     vec4 texCol = texture2D(u_texture, texC); 
 
     vec4 gaussCol = vec4(texCol.rgb, 1.0); 
 
     float stepY = 1.0/u_textureSize.y; 
 
     for (int i = 1; i <= 20; ++ i) 
 
     { 
 
      float weight = CalcGauss(float(i)/32.0, u_sigma * 0.5); 
 
      texCol = texture2D(u_texture, texC + vec2(0.0, float(i) * stepY)); 
 
      gaussCol += vec4(texCol.rgb * weight, weight); 
 
      texCol = texture2D(u_texture, texC - vec2(0.0, float(i) * stepY)); 
 
      gaussCol += vec4(texCol.rgb * weight, weight); 
 
     } 
 
     vec3 hdrCol = 2.0 * gaussCol.xyz/gaussCol.w; 
 
     vec3 mappedCol = vec3(1.0) - exp(-hdrCol.rgb * 3.0); 
 
     gl_FragColor = vec4(clamp(mappedCol.rgb, 0.0, 1.0), 1.0); 
 
    } 
 
</script> 
 

 
<div> 
 
    <form id="gui" name="inputs"> 
 
     <table> 
 
      <tr> <td> <font color= #CCF>shininess</font> </td> 
 
       <td> <input type="range" id="shine" min="0" max="50" value="10" onchange="changeEventHandler(event);"/></td> </tr> 
 
      <tr> <td> <font color= #CCF>glow</font> </td> 
 
       <td> <input type="range" id="glow" min="100" max="400" value="300" onchange="changeEventHandler(event);"/></td> </tr> 
 
      <tr> <td> <font color= #CCF>blur</font> </td> 
 
       <td> <input type="range" id="sigma" min="1" max="100" value="60" onchange="changeEventHandler(event);"/></td> </tr> 
 
     </table> 
 
    </form> 
 
</div> 
 

 
<canvas id="canvas" style="border: none;" width="100%" height="100%"></canvas>

+0

'dan daha fazla desteğe sahip olan OpenGL ES 3.0'ı kullanabilirsiniz, ancak bu neden 'vertPos = pos.xyz/pos.w; ' köşe gölgesinde? burada bölmek gerekli mi? Bu aşamada w'nin her zaman 1 olduğunu düşündüm. – wdanxna

+0

@wdanxna Hayır, bu durumda gerekli değildir. – Rabbid76