Krita Source Code Documentation
Loading...
Searching...
No Matches
phong_pixel_processor.cpp
Go to the documentation of this file.
1/*
2* SPDX-FileCopyrightText: 2010-2012 José Luis Vergara <pentalis@gmail.com>
3*
4* SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
8#include <cmath>
9#include <iostream>
10#include <KoChannelInfo.h>
11
13{
14 m_pixelArea = pixelArea;
15 initialize(config);
16}
17
19{
20 // Basic, fundamental
21 normal_vector = QVector3D(0, 0, 1);
22 vision_vector = QVector3D(0, 0, 1);
23 x_vector = QVector3D(1, 0, 0);
24 y_vector = QVector3D(0, 1, 0);
25
26 // Mutable
27 light_vector = QVector3D(0, 0, 0);
28 reflection_vector = QVector3D(0, 0, 0);
29
30 //setLightVector(QVector3D(-8, 8, 2));
31
33 QVariant guiLight[PHONG_TOTAL_ILLUMINANTS];
34
35 qint32 azimuth;
36 qint32 inclination;
37
38 for (int i = 0; i < PHONG_TOTAL_ILLUMINANTS; i++) {
39 if (config->getBool(PHONG_ILLUMINANT_IS_ENABLED[i])) {
40 if (config->getProperty(PHONG_ILLUMINANT_COLOR[i], guiLight[i])) {
41 light[i].RGBvalue << guiLight[i].value<QColor>().redF();
42 light[i].RGBvalue << guiLight[i].value<QColor>().greenF();
43 light[i].RGBvalue << guiLight[i].value<QColor>().blueF();
44
45 azimuth = config->getInt(PHONG_ILLUMINANT_AZIMUTH[i]) - 90;
46 inclination = config->getInt(PHONG_ILLUMINANT_INCLINATION[i]);
47
48 qreal m; //2D vector magnitude
49 light[i].lightVector.setZ( sin( inclination * M_PI / 180 ) );
50 m = cos( inclination * M_PI / 180);
51
52 light[i].lightVector.setX( cos( azimuth * M_PI / 180 ) * m );
53 light[i].lightVector.setY( sin( azimuth * M_PI / 180 ) * m );
54 //Pay close attention to this, indexes will move in this line
55 lightSources.append(light[i]);
56 }
57 }
58 }
59
60 size = lightSources.size();
61
62 //Code that exists only to swiftly switch to the other algorithm (reallyFastIlluminatePixel) to test
63 if (size > 0) {
64 fastLight = light[0];
65 fastLight2 = light[0];
66 }
67
68 //Ka, Kd and Ks must be between 0 and 1 or grave errors will happen
69 Ka = config->getDouble(PHONG_AMBIENT_REFLECTIVITY);
70 Kd = config->getDouble(PHONG_DIFFUSE_REFLECTIVITY);
71 Ks = config->getDouble(PHONG_SPECULAR_REFLECTIVITY);
72 shiny_exp = config->getInt(PHONG_SHINYNESS_EXPONENT);
73
74 Ia = Id = Is = 0;
75
78
80}
81
82
87
88
89void PhongPixelProcessor::setLightVector(QVector3D lightVector)
90{
91 lightVector.normalize();
92 light_vector = lightVector;
93}
94
95QVector<quint16> PhongPixelProcessor::IlluminatePixelFromHeightmap(quint32 posup, quint32 posdown, quint32 posleft, quint32 posright)
96{
97 QVector<quint16> finalPixel(4, 0xFFFF);
98
99 if (lightSources.size() == 0)
100 return finalPixel;
101
102 // Algorithm begins, Phong Illumination Model
103 normal_vector.setX(- realheightmap[posright] + realheightmap[posleft]);
104 normal_vector.setY(- realheightmap[posup] + realheightmap[posdown]);
105 normal_vector.setZ(8);
106 normal_vector.normalize();
107
108 // PREPARE ALGORITHM HERE
109
110 finalPixel = IlluminatePixel();
111
112 return finalPixel;
113}
114
116{
117 qreal temp;
118 quint8 channel = 0;
119 const quint8 totalChannels = 3; // The 4th is alpha and we'll fill it with a nice 0xFFFF
120 qreal computation[] = {0, 0, 0};
121 QVector<quint16> finalPixel(4, 0xFFFF);
122
123 if (lightSources.size() == 0)
124 return finalPixel;
125
126 // PREPARE ALGORITHM HERE
127
128 for (int i = 0; i < size; i++) {
129 light_vector = lightSources.at(i).lightVector;
130
131 for (channel = 0; channel < totalChannels; channel++) {
132 Ia = lightSources.at(i).RGBvalue.at(channel) * Ka;
133 computation[channel] += Ia;
134 }
136 temp = Kd * QVector3D::dotProduct(normal_vector, light_vector);
137 for (channel = 0; channel < totalChannels; channel++) {
138 Id = lightSources.at(i).RGBvalue.at(channel) * temp;
139 if (Id < 0) Id = 0;
140 if (Id > 1) Id = 1;
141 computation[channel] += Id;
142 }
143 }
144
146 reflection_vector = (2 * pow(QVector3D::dotProduct(normal_vector, light_vector), shiny_exp)) * normal_vector - light_vector;
147 temp = Ks * QVector3D::dotProduct(vision_vector, reflection_vector);
148 for (channel = 0; channel < totalChannels; channel++) {
149 Is = lightSources.at(i).RGBvalue.at(channel) * temp;
150 if (Is < 0) Is = 0;
151 if (Is > 1) Is = 1;
152 computation[channel] += Is;
153 }
154 }
155 }
156
157 for (channel = 0; channel < totalChannels; channel++) {
158 if (computation[channel] > 1)
159 computation[channel] = 1;
160 if (computation[channel] < 0)
161 computation[channel] = 0;
162 }
163
164 //RGBA actually uses the BGRA order of channels, hence the disorder
165 finalPixel[2] = quint16(computation[0] * 0xFFFF);
166 finalPixel[1] = quint16(computation[1] * 0xFFFF);
167 finalPixel[0] = quint16(computation[2] * 0xFFFF);
168
169 return finalPixel;
170}
171
173{
174 QVector<quint16> finalPixel(4, 0xFFFF);
175
176 if (lightSources.size() == 0)
177 return finalPixel;
178
179 // if ()
180 // Algorithm begins, Phong Illumination Model
181 normal_vector.setX(r*2-1.0);
182 normal_vector.setY(-(g*2-1.0));
183 normal_vector.setZ(b*2-1.0);
184 //normal_vector.normalize();
185
186 // PREPARE ALGORITHM HERE
187
188 finalPixel = IlluminatePixel();
189
190 return finalPixel;
191}
qreal Kd
Diffuse light coefficient.
void setLightVector(QVector3D light_vector)
qreal Ks
Specular light coefficient.
qreal shiny_exp
Shinyness exponent.
qreal Is
Total specular light.
QVector< quint16 > IlluminatePixelFromHeightmap(quint32 posup, quint32 posdown, quint32 posleft, quint32 posright)
qreal Ia
Total ambient light.
qreal Id
Total diffuse light.
qreal Ka
Ambient light coefficient.
QVector< quint16 > IlluminatePixel()
PhongPixelProcessor(quint32 pixelArea, const KisPropertiesConfigurationSP config)
QVector< double > realheightmap
void initialize(const KisPropertiesConfigurationSP config)
quint8 size
Size of this stuff.
QVector< quint16 > IlluminatePixelFromNormalmap(qreal r, qreal g, qreal b)
QList< Illuminant > lightSources
Light sources to use (those disabled in the GUI are not present here)
#define M_PI
Definition kis_global.h:111
const QString PHONG_SPECULAR_REFLECTIVITY_IS_ENABLED
const QString PHONG_DIFFUSE_REFLECTIVITY_IS_ENABLED
const QString PHONG_ILLUMINANT_AZIMUTH[]
const QString PHONG_ILLUMINANT_INCLINATION[]
const QString PHONG_ILLUMINANT_COLOR[]
const quint8 PHONG_TOTAL_ILLUMINANTS
const QString PHONG_SHINYNESS_EXPONENT
const QString PHONG_DIFFUSE_REFLECTIVITY
const QString PHONG_ILLUMINANT_IS_ENABLED[]
const QString PHONG_SPECULAR_REFLECTIVITY
const QString PHONG_AMBIENT_REFLECTIVITY
QList< qreal > RGBvalue