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都为一维贴图)
(edgeRamp)
(diffuseRamp)
(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部分:
-
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); }
分析:
边框函数公式: (x, y 属于 [-1, 1] )
Excel曲面图形如下:
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; }