git-svn-id: svn://db.shs.com.ru/libs@702 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
BIN
qglengine/coeffs_brdf.png
Normal file
BIN
qglengine/coeffs_brdf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
@@ -1,5 +1,6 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
|
<file>coeffs_brdf.png</file>
|
||||||
<file>icons/add-type-camera.png</file>
|
<file>icons/add-type-camera.png</file>
|
||||||
<file>icons/add-type-geo.png</file>
|
<file>icons/add-type-geo.png</file>
|
||||||
<file>icons/add-type-light.png</file>
|
<file>icons/add-type-light.png</file>
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ void Renderer::initShaders() {
|
|||||||
if (!bindShader(roles[p], &prog)) continue;
|
if (!bindShader(roles[p], &prog)) continue;
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
|
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
|
||||||
//prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount);
|
prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount);
|
||||||
//prog->setUniformValue("tex_coeffs[1]", (int)Renderer::dbrBuffersCount+1);
|
//prog->setUniformValue("tex_coeffs[1]", (int)Renderer::dbrBuffersCount+1);
|
||||||
}
|
}
|
||||||
if (bindShader(srFinalPass, &prog)) {
|
if (bindShader(srFinalPass, &prog)) {
|
||||||
|
|||||||
@@ -301,7 +301,93 @@ void RendererBase::renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera *
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float RadicalInverse_VdC(uint bits) {
|
||||||
|
bits = (bits << 16u) | (bits >> 16u);
|
||||||
|
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||||
|
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||||
|
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||||
|
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||||
|
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
QVector2D Hammersley(uint i, uint N) {
|
||||||
|
return QVector2D(float(i)/float(N), RadicalInverse_VdC(i));
|
||||||
|
}
|
||||||
|
QVector3D ImportanceSampleGGX(QVector2D Xi, QVector3D N, float roughness) {
|
||||||
|
float a = roughness*roughness;
|
||||||
|
float phi = 2.0 * M_PI * Xi[0];
|
||||||
|
float cosTheta = sqrt((1.0 - Xi[1]) / (1.0 + (a*a - 1.0) * Xi[1]));
|
||||||
|
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||||
|
// преобразование из сферических в декартовы координаты
|
||||||
|
QVector3D H;
|
||||||
|
H[0] = cos(phi) * sinTheta;
|
||||||
|
H[1] = sin(phi) * sinTheta;
|
||||||
|
H[2] = cosTheta;
|
||||||
|
// преобразование из касательного пространства в мировые координаты
|
||||||
|
QVector3D up = qAbs(N[2]) < 0.999 ? QVector3D(0.0, 0.0, 1.0) : QVector3D(1.0, 0.0, 0.0);
|
||||||
|
QVector3D tangent = QVector3D::crossProduct(up, N).normalized();
|
||||||
|
QVector3D bitangent = QVector3D::crossProduct(N, tangent);
|
||||||
|
QVector3D sampleVec = tangent * H[0] + bitangent * H[1] + N * H[2];
|
||||||
|
return sampleVec.normalized();
|
||||||
|
}
|
||||||
|
float GeometrySchlickGGX(float NdotV, float roughness) {
|
||||||
|
float k = (roughness * roughness) / 2.0;
|
||||||
|
float nom = NdotV;
|
||||||
|
float denom = NdotV * (1.0 - k) + k;
|
||||||
|
return nom / denom;
|
||||||
|
}
|
||||||
|
float GeometrySmith(QVector3D N, QVector3D V, QVector3D L, float roughness) {
|
||||||
|
float NdotV = piMax(QVector3D::dotProduct(N, V), 0.f);
|
||||||
|
float NdotL = piMax(QVector3D::dotProduct(N, L), 0.f);
|
||||||
|
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||||
|
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||||
|
return ggx1 * ggx2;
|
||||||
|
}
|
||||||
|
QVector2D IntegrateBRDF(float NdotV, float roughness) {
|
||||||
|
QVector3D V;
|
||||||
|
V[0] = sqrt(1.f - NdotV*NdotV);
|
||||||
|
V[1] = 0.f;
|
||||||
|
V[2] = NdotV;
|
||||||
|
float A = 0.f;
|
||||||
|
float B = 0.f;
|
||||||
|
QVector3D N = QVector3D(0.f, 0.f, 1.f);
|
||||||
|
const uint SAMPLE_COUNT = 256u;
|
||||||
|
for(uint i = 0u; i < SAMPLE_COUNT; ++i) {
|
||||||
|
QVector2D Xi = Hammersley(i, SAMPLE_COUNT);
|
||||||
|
QVector3D H = ImportanceSampleGGX(Xi, N, roughness);
|
||||||
|
QVector3D L = (2.f * QVector3D::dotProduct(V, H) * H - V).normalized();
|
||||||
|
float NdotL = piMax(L[2], 0.f);
|
||||||
|
float NdotH = piMax(H[2], 0.f);
|
||||||
|
float VdotH = piMax(QVector3D::dotProduct(V, H), 0.f);
|
||||||
|
if(NdotL > 0.f) {
|
||||||
|
float G = GeometrySmith(N, V, L, roughness);
|
||||||
|
float G_Vis = (G * VdotH) / (NdotH * NdotV);
|
||||||
|
float Fc = pow(1.f - VdotH, 5.f);
|
||||||
|
A += (1.f - Fc) * G_Vis;
|
||||||
|
B += Fc * G_Vis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
A /= float(SAMPLE_COUNT);
|
||||||
|
B /= float(SAMPLE_COUNT);
|
||||||
|
return QVector2D(A, B);
|
||||||
|
}
|
||||||
|
|
||||||
void RendererBase::initCoeffTextures() {
|
void RendererBase::initCoeffTextures() {
|
||||||
|
QImage im = QImage(":/coeffs_brdf.png").mirrored();
|
||||||
|
int size = im.width();
|
||||||
|
QVector<QVector2D> data(size*size);
|
||||||
|
int ind = -1;
|
||||||
|
for (int x = 0; x < size; ++x) {
|
||||||
|
//float c = x / double(size - 1) + 1.E-3;
|
||||||
|
for (int y = 0; y < size; ++y) {
|
||||||
|
//float r = y / double(size - 1);
|
||||||
|
QColor p = im.pixelColor(x, y);
|
||||||
|
data[++ind] = QVector2D(p.redF(), p.greenF());//IntegrateBRDF(c, 1.f - r + 1.E-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createCoeffTexture(tex_coeff[0], data.constData(), size, 2);
|
||||||
/*const int size = 512;
|
/*const int size = 512;
|
||||||
QVector<float> data_diff(size*size), data_spec(size*size);
|
QVector<float> data_diff(size*size), data_spec(size*size);
|
||||||
double r, c, c2;
|
double r, c, c2;
|
||||||
@@ -334,15 +420,19 @@ void RendererBase::initCoeffTextures() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RendererBase::createCoeffTexture(GLuint & id, const QVector<float> & data, int size) {
|
void RendererBase::createCoeffTexture(GLuint & id, const void * data, int size, int channels) {
|
||||||
QOpenGLExtraFunctions * f = view;
|
QOpenGLExtraFunctions * f = view;
|
||||||
deleteGLTexture(f, id);
|
deleteGLTexture(f, id);
|
||||||
f->glGenTextures(1, &id);
|
f->glGenTextures(1, &id);
|
||||||
f->glBindTexture(GL_TEXTURE_2D, id);
|
f->glBindTexture(GL_TEXTURE_2D, id);
|
||||||
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
|
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
f->glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, size, size, 0, GL_RED, GL_FLOAT, data.constData());
|
GLenum iformat = GL_R16F, format = GL_RED;
|
||||||
|
if (channels == 2) {iformat = GL_RG16F; format = GL_RG;}
|
||||||
|
if (channels == 3) {iformat = GL_RGB16F; format = GL_RGB;}
|
||||||
|
if (channels == 4) {iformat = GL_RGBA16F; format = GL_RGBA;}
|
||||||
|
f->glTexImage2D(GL_TEXTURE_2D, 0, iformat, size, size, 0, format, GL_FLOAT, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ protected:
|
|||||||
void initQuad(Mesh * mesh, QMatrix4x4 mat = QMatrix4x4());
|
void initQuad(Mesh * mesh, QMatrix4x4 mat = QMatrix4x4());
|
||||||
void renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * cam = 0, bool uniforms = true);
|
void renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * cam = 0, bool uniforms = true);
|
||||||
void initCoeffTextures();
|
void initCoeffTextures();
|
||||||
void createCoeffTexture(GLuint & id, const QVector<float> & data, int size);
|
void createCoeffTexture(GLuint & id, const void * data, int size, int channels = 1);
|
||||||
|
|
||||||
QGLView * view;
|
QGLView * view;
|
||||||
TextureManager * textures_manager;
|
TextureManager * textures_manager;
|
||||||
|
|||||||
@@ -95,6 +95,26 @@ void calcLight(in int index, in vec3 n, in vec3 v) {
|
|||||||
si += spot * spec * qgl_light_parameter[index].color.rgb;
|
si += spot * spec * qgl_light_parameter[index].color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float GeometrySchlickGGX(float NdotV, float roughness) {
|
||||||
|
float a = roughness;
|
||||||
|
float k = (a * a) / 2.0;
|
||||||
|
float nom = NdotV;
|
||||||
|
float denom = NdotV * (1.0 - k) + k;
|
||||||
|
return nom / denom;
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
|
||||||
|
float NdotV = max(dot(N, V), 0.0);
|
||||||
|
float NdotL = max(dot(N, L), 0.0);
|
||||||
|
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||||
|
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||||
|
return ggx1 * ggx2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
ivec2 tc = ivec2(gl_FragCoord.xy);
|
ivec2 tc = ivec2(gl_FragCoord.xy);
|
||||||
vec4 v1 = texelFetch(tex_1, tc, 0);
|
vec4 v1 = texelFetch(tex_1, tc, 0);
|
||||||
@@ -118,11 +138,13 @@ void main(void) {
|
|||||||
float metalness = v2.r;
|
float metalness = v2.r;
|
||||||
float roughness = v2.g;
|
float roughness = v2.g;
|
||||||
float reflectivity = v2.b;
|
float reflectivity = v2.b;
|
||||||
|
float NdotV = dot(normal, v);
|
||||||
|
float roughness3 = roughness*roughness*roughness;
|
||||||
//bn = normalize(vec3(v3.w, v4.zw));
|
//bn = normalize(vec3(v3.w, v4.zw));
|
||||||
//bn2 = normalize(cross(n, bn));
|
//bn2 = normalize(cross(n, bn));
|
||||||
rough_diff = max(roughness, _min_rough);
|
rough_diff = max(roughness, _min_rough);
|
||||||
rough_spec = max(roughness*roughness*roughness, _min_rough);
|
rough_spec = max(roughness3, _min_rough);
|
||||||
float shlick = clamp(metalness + (1 - metalness) * pow(1 - dot(normal, v), 5), 0, 1);
|
float shlick = clamp(metalness + (1 - metalness) * pow(1 - NdotV, 5), 0, 1);
|
||||||
|
|
||||||
li = vec3(0.);//qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity;
|
li = vec3(0.);//qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity;
|
||||||
si = vec3(0.);
|
si = vec3(0.);
|
||||||
@@ -131,7 +153,12 @@ void main(void) {
|
|||||||
si *= shlick;
|
si *= shlick;
|
||||||
li *= (1 - shlick);
|
li *= (1 - shlick);
|
||||||
alpha = min(1, alpha * (1 + shlick));
|
alpha = min(1, alpha * (1 + shlick));
|
||||||
|
|
||||||
|
vec2 brdf = texture(tex_coeffs[0], vec2(NdotV*0.99, roughness3*0.995)).rg;
|
||||||
|
float env_spec = shlick * brdf.x + brdf.y;
|
||||||
|
|
||||||
vec3 res_col = max(vec3(0), li * diffuse + si * mix(vec3(1), diffuse, metalness) + emission);
|
vec3 res_col = max(vec3(0), li * diffuse + si * mix(vec3(1), diffuse, metalness) + emission);
|
||||||
|
res_col = mix(res_col, fog_color.rgb, env_spec);
|
||||||
|
|
||||||
float plen = length(pos.xyz);
|
float plen = length(pos.xyz);
|
||||||
float fog = 1 - exp(-plen / fog_decay);
|
float fog = 1 - exp(-plen / fog_decay);
|
||||||
@@ -140,6 +167,8 @@ void main(void) {
|
|||||||
|
|
||||||
qgl_FragColor = vec4(res_col, alpha);
|
qgl_FragColor = vec4(res_col, alpha);
|
||||||
|
|
||||||
//qgl_FragColor.rgb = vec3(texture(tex_coeffs[0], qgl_FragTexture.xy).r);
|
//vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
|
||||||
//qgl_FragColor.rgb = vec3(ldir);
|
//qgl_FragColor.rgb = vec3(shlick * brdf.x + brdf.y);
|
||||||
|
//qgl_FragColor.rgb = vec3(env_spec);
|
||||||
|
//qgl_FragColor.rgb = vec3(1-GeometrySchlickGGX(dot(normal, v),roughness));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user