OGRE演示例子剖析

1  CelShading卡通渲染

关键部分shader代码:

Vert部分

   

vec3 n = normalize(inNormal);
    vec3 l = lightPosition - inPosition;
    diffuse = max(dot(n, l), 0.0);

    vec3 e = normalize( eyePosition - inPosition);
    vec3 H = normalize(l + e);
    specular = pow(max(dot(H, n), 0.0), 10);

    if(diffuse == 0.0) {
        specular = 0.0;
    }

    edge = max(dot(e, n), 0.0);

 

frag部分:(diffuseRamp、specularRamp和edgeRamp都为一维贴图)

cel_shading_specular.png(edgeRamp)

cel_shading_diffuse.png(diffuseRamp)

cel_shading_edge.png (SpecularRamp)

  

float diffuseFact = texture2D(m_DiffuseRamp, vec2(diffuse, 0.0)).r;
    float specularFact = texture2D(m_SpecularRamp, vec2(specular, 0.0)).r;
    float edgeFact = texture2D(m_EdgeRamp, vec2(edge, 0.0)).r;

    vec4 color = edgeFact * ((diffuseColor * diffuseFact) + (specularColor * specularFact));
    gl_FragColor = color ;

 

2  动态贴图

在CPU上对贴图进行单个像素调整,so easy!

3  OldTV (未完全理解, 取贴图部分)

Vert部分:

  1. void main(){
        gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
        texCoord = inTexCoord;
    
        texCoord2 = gl_Position.xy;
    }

frag部分:

参数:       

oldTVMat.setFloat("distortionFreq", 2.7f );
        oldTVMat.setFloat("distortionScale", 2.5f );
        oldTVMat.setFloat("distortionRoll", 0.93f );
        oldTVMat.setFloat("interference", 0.5f );
        oldTVMat.setFloat("frameLimit", 0.4f );
        oldTVMat.setFloat("frameShape", 0.26f );
        oldTVMat.setFloat("frameSharpness", 6.0f );

void main(){
       // Define a frame shape
       vec2 pos = texCoord2;
       float f = (1 - pos.x * pos.x) * (1 - pos.y * pos.y);
       float frame = clamp(frameSharpness * (pow(f, frameShape) - frameLimit), 0.0, 1.0);

       // Interference ... just a texture filled with rand()
       float rand = texture2D(m_RandMap, vec2(0.5 * texCoord + mod(g_Time, 0.5))).r - 0.2;

       // Some signed noise for the distortion effect
       float noisy = texture2D(m_NoiseMap, vec2(0, 0.5 * pos.y + 0.1 * g_Time)).r - 0.5;

       // Repeat a 1 - x^2 (0 < x < 1) curve and roll it with sinus.
       float dst = fract(pos.y * distortionFreq + distortionRoll * sin(g_Time));
       dst *= (1 - dst);
       // Make sure distortion is highest in the center of the image
       dst /= 1 + distortionScale * abs(pos.y);

       // ... and finally distort
       vec2 newTexCoord = vec2(texCoord.x + distortionScale * noisy * dst, texCoord2.y);
       vec4 image = texture2D(m_Texture, newTexCoord);

       // Combine frame, distorted image and interference
       gl_FragColor = frame * (interference * rand + image);
}

 

分析:

边框函数公式:clamp(6 * (pow((1 - x^2) * (1 - y^2), 0.26) - 0.4), 0.0, 1.0)           (x, y 属于 [-1, 1] )

Excel曲面图形如下:

边框公式.png

4、浮雕(Emboss)

void main(){

    vec4 Color;
    Color.a = 1.0;
    Color.rgb = vec3(0.5);
    Color -= texture2D( m_Texture, texCoord - 0.001) * 2.0;
    Color += texture2D( m_Texture, texCoord + 0.001) * 2.0;
    Color.rgb = vec3((Color.r + Color.g + Color.b) / 3.0);

    gl_FragColor =      Color;
}

 

5、Posterize色调分离,简单来说就是增加色彩的跳跃性,阶数降低

void main ( )  {
    float nColors = 8;
    float gamma = 0.6;

    vec4 texCol = tex2D(RT, iTexCoord);
    vec3 tc = texCol.xyz;
    tc = pow(tc, gamma);
    tc = tc * nColors;
    tc = floor(tc);
    tc = tc / nColors;
    tc = pow(tc,1.0/gamma);
    return vec4(tc,texCol.w);
}

6、Radial Blur放射状模糊

uniform sampler2D m_Texture;
uniform float m_SampleDist;
uniform float m_SampleStrength;

varying vec2 texCoord;
// 下面值跟分辨率有关,需细调
const float samples[10] = float[10] ( -0.8,-0.5,-0.3,-0.2,-0.1,0.1,0.2,0.3,0.5,0.8);

void main(){
   //Vector from pixel to the center of the screen
   vec2 dir = 0.5 - texCoord;

   //Distance from pixel to the center (distant pixels have stronger effect)
   float dist = sqrt( dir.x*dir.x + dir.y*dir.y );
   //Now that we have dist, we can normlize vector
   dir = normalize( dir );

   //Save the color to be used later
   vec4 color = texture2D( m_Texture, texCoord );
   //Average the pixels going along the vector
   vec4 sum = color;
   for (int i = 0; i < 10; i++) {
      vec4 res=texture2D( m_Texture, texCoord + dir * samples[i] * m_SampleDist );
      sum += res;
   }
   sum /= 11.0;

   //Calculate amount of blur based on distance and a strength parameter
   float t = dist * m_SampleStrength;
   t = clamp( t, 0.0, 1.0 );//We need 0 <= t <= 1

   //Blend the original color with the averaged pixels
    gl_FragColor =  color * (1-t) + sum * t;
}

 

posted @ 2012-09-09 17:41  ActionFG  阅读(385)  评论(0编辑  收藏  举报