framework2

Форк
0
170 строк · 7.0 Кб
1
/*
2
 *  ToonPass.cpp
3
 *
4
 *  Copyright (c) 2013, satcy, http://satcy.net
5
 *  All rights reserved. 
6
 *  
7
 *  Redistribution and use in source and binary forms, with or without 
8
 *  modification, are permitted provided that the following conditions are met: 
9
 *  
10
 *  * Redistributions of source code must retain the above copyright notice, 
11
 *    this list of conditions and the following disclaimer. 
12
 *  * Redistributions in binary form must reproduce the above copyright 
13
 *    notice, this list of conditions and the following disclaimer in the 
14
 *    documentation and/or other materials provided with the distribution. 
15
 *  * Neither the name of Neil Mendoza nor the names of its contributors may be used 
16
 *    to endorse or promote products derived from this software without 
17
 *    specific prior written permission. 
18
 *  
19
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
20
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
21
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
22
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
23
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
24
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
25
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
26
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
27
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
28
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
29
 *  POSSIBILITY OF SUCH DAMAGE. 
30
 *
31
 */
32
#include "ToonPass.h"
33
#include "ofMain.h"
34

35
namespace itg
36
{
37
    ToonPass::ToonPass(const ofVec2f& aspect, bool arb, float edgeThreshold, float level,
38
                       const ofVec4f& ambientColor,
39
                       const ofVec4f& diffuseColor,
40
                       const ofVec4f& specularColor,
41
                       bool isSpecular, float shinyness) :
42
        edgeThreshold(edgeThreshold), level(level), ambientColor(ambientColor), diffuseColor(diffuseColor), specularColor(specularColor), isSpecular(isSpecular), shinyness(shinyness), RenderPass(aspect, arb, "toon")
43
    {
44
        string vertShaderSrc = STRINGIFY(
45
            varying vec3 v;
46
            varying vec3 N;
47

48
            void main()
49
            {
50
                v = vec3(gl_ModelViewMatrix * gl_Vertex);
51
                N = normalize(gl_NormalMatrix * gl_Normal);
52

53
                gl_TexCoord[0] = gl_MultiTexCoord0;
54
                gl_Position = ftransform();
55
            }
56
        );
57
        
58
        string fragShaderSrc = STRINGIFY(
59
            uniform sampler2D normalImage;
60
            uniform float textureSizeX;
61
            uniform float textureSizeY;
62
            uniform float normalEdgeThreshold;
63
            uniform float qLevel;
64
            uniform int bSpecular;
65
            uniform vec4 ambient;
66
            uniform vec4 diffuse;
67
            uniform vec4 specular;
68
            uniform float shinyness;
69
                                         
70
            varying vec3 v;
71
            varying vec3 N;
72

73
            vec3 getNormal(vec2 st){
74
                vec2 texcoord = clamp(st, 0.001, 0.999);
75
                return texture2D(normalImage, texcoord).rgb;
76
            }
77

78
            void main(void){
79
                float dxtex = 1.0 / textureSizeX;
80
                float dytex = 1.0 / textureSizeY;
81

82
                vec2 st = gl_TexCoord[0].st;
83
                // access center pixel and 4 surrounded pixel
84
                vec3 center = getNormal(st).rgb;
85
                vec3 left = getNormal(st + vec2(dxtex, 0.0)).rgb;
86
                vec3 right = getNormal(st + vec2(-dxtex, 0.0)).rgb;
87
                vec3 up = getNormal(st + vec2(0.0, -dytex)).rgb;
88
                vec3 down = getNormal(st + vec2(0.0, dytex)).rgb;
89

90
                // discrete Laplace operator
91
                vec3 laplace = abs(-4.0*center + left + right + up + down);
92
                // if one rgb-component of convolution result is over threshold => edge
93
                vec4 line = texture2D(normalImage, st);
94
                if(laplace.r > normalEdgeThreshold
95
                || laplace.g > normalEdgeThreshold
96
                || laplace.b > normalEdgeThreshold){
97
                    line = vec4(0.0, 0.0, 0.0, 1.0); // => color the pixel green
98
                } else {
99
                    line = vec4(1.0, 1.0, 1.0, 1.0); // black
100
                }
101

102
                //end Line;
103

104
                //start Phong
105

106
                //vec3 lightPosition = vec3(100.0, 100.0, 50.0);
107
                vec3 lightPosition = gl_LightSource[0].position.xyz;
108

109
                vec3 L = normalize(lightPosition - v);
110
                vec3 E = normalize(-v);
111
                vec3 R = normalize(-reflect(L,N));
112

113
                // ambient term
114
                vec4 Iamb = ambient;
115

116
                // diffuse term
117
                vec4 Idiff = texture2D( normalImage, gl_TexCoord[0].st) * diffuse;
118
                //vec4 Idiff = vec4(1.0, 1.0, 1.0, 1.0) * diffuse;
119
                Idiff *= max(dot(N,L), 0.0);
120
                Idiff = clamp(Idiff, 0.0, 1.0);
121

122
                // specular term
123
                vec4 Ispec = specular;
124
                Ispec *= pow(max(dot(R,E),0.0), shinyness);
125
                Ispec = clamp(Ispec, 0.0, 1.0); 
126
                
127
                vec4 color = Iamb + Idiff;
128
                if ( bSpecular == 1 ) color += Ispec;
129
                // store previous alpha value
130
                float alpha = color.a;
131
                // quantize process: multiply by factor, round and divde by factor
132
                color = floor(0.5 + (qLevel * color)) / qLevel;
133
                // set fragment/pixel color
134
                color.a = alpha;
135

136
                gl_FragColor = color * line;
137
            }
138
                                         
139

140
        );
141
        shader.setupShaderFromSource(GL_VERTEX_SHADER, vertShaderSrc);
142
        shader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragShaderSrc);
143
        shader.linkProgram();
144
        
145
    }
146
    
147
    void ToonPass::render(ofFbo& readFbo, ofFbo& writeFbo, ofTexture& depthTex)
148
    {
149
        
150
        writeFbo.begin();
151
        
152
        shader.begin();
153
        
154
        shader.setUniformTexture("normalImage", readFbo.getTexture(), 0);
155
        shader.setUniform1f("textureSizeX", writeFbo.getWidth());
156
        shader.setUniform1f("textureSizeY", writeFbo.getHeight());
157
        shader.setUniform1f("normalEdgeThreshold", edgeThreshold);
158
        shader.setUniform1f("qLevel", level);
159
        shader.setUniform1i("bSpecular", isSpecular ? 1 : 0);
160
        shader.setUniform4f("ambient", ambientColor.x, ambientColor.y, ambientColor.z, ambientColor.w);
161
        shader.setUniform4f("diffuse", diffuseColor.x, diffuseColor.y, diffuseColor.z, diffuseColor.w);
162
        shader.setUniform4f("specular", specularColor.x, specularColor.y, specularColor.z, specularColor.w);
163
        shader.setUniform1f("shinyness", shinyness);
164
        
165
        texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight());
166
        
167
        shader.end();
168
        writeFbo.end();
169
    }
170
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.