[CAM Simulator][1.0] Change usage of sample shader code to one with compatible license. (#16899)
* Change usage of sample shader code to one with compatible license. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -139,7 +139,7 @@ bool GuiDisplay::InitGui()
|
||||
mThumbMaxMotion = (float)guiItems[eGuiItemSlider].texItem.w;
|
||||
|
||||
// init shader
|
||||
mShader.CompileShader((char*)VertShader2DTex, (char*)FragShader2dTex);
|
||||
mShader.CompileShader("GuiDisplay", (char*)VertShader2DTex, (char*)FragShader2dTex);
|
||||
mShader.UpdateTextureSlot(0);
|
||||
|
||||
UpdateSimSpeed(1);
|
||||
|
||||
@@ -372,9 +372,11 @@ void MillSimulation::Render()
|
||||
RenderBaseShape();
|
||||
RenderPath();
|
||||
simDisplay.updateDisplay = false;
|
||||
simDisplay.RenderResult(true);
|
||||
}
|
||||
else {
|
||||
simDisplay.RenderResult(false);
|
||||
}
|
||||
|
||||
simDisplay.RenderResult();
|
||||
|
||||
/* if (mDebug > 0) {
|
||||
mat4x4 test;
|
||||
|
||||
@@ -115,8 +115,8 @@ protected:
|
||||
SolidObject mBaseShape;
|
||||
|
||||
vec3 bgndColor = {0.1f, 0.2f, 0.3f};
|
||||
vec3 stockColor = {0.7f, 0.75f, 0.9f};
|
||||
vec3 cutColor = {0.85f, 0.95f, 0.85f};
|
||||
vec3 stockColor = {0.5f, 0.55f, 0.9f};
|
||||
vec3 cutColor = {0.5f, 0.84f, 0.73f};
|
||||
vec3 toolColor = {0.5f, 0.4f, 0.3f};
|
||||
vec3 baseShapeColor = {0.7f, 0.6f, 0.5f};
|
||||
|
||||
|
||||
@@ -86,4 +86,7 @@ extern QOpenGLContext* gOpenGlContext;
|
||||
#define glVertexAttribIPointer gSimWindow->glVertexAttribIPointer
|
||||
#define glUniform4fv gSimWindow->glUniform4fv
|
||||
#define glLineWidth gSimWindow->glLineWidth
|
||||
#define glGetShaderiv gSimWindow->glGetShaderiv
|
||||
#define glGetShaderInfoLog gSimWindow->glGetShaderInfoLog
|
||||
|
||||
#endif // !__openglwrapper_h__
|
||||
|
||||
@@ -18,11 +18,20 @@
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
* *
|
||||
* Portions of this code are taken from: *
|
||||
* "OpenGL 4 Shading Language cookbook" Third edition *
|
||||
* Written by: David Wolff *
|
||||
* Published by: <packt> www.packt.com *
|
||||
* License: MIT License *
|
||||
* *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "GlUtils.h"
|
||||
#include "Shader.h"
|
||||
#include <iostream>
|
||||
#include <Base/Console.h>
|
||||
|
||||
namespace MillSim
|
||||
{
|
||||
@@ -74,6 +83,16 @@ void Shader::UpdateEnvColor(vec3 lightPos, vec3 lightColor, vec3 ambient, float
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::UpdateScreenDimension(int width, int height)
|
||||
{
|
||||
if (mScreenWidthPos >= 0) {
|
||||
glUniform1f(mScreenWidthPos, (float)width);
|
||||
}
|
||||
if (mScreenHeightPos >= 0) {
|
||||
glUniform1f(mScreenHeightPos, (float)height);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::UpdateObjColor(vec3 objColor)
|
||||
{
|
||||
if (mObjectColorPos >= 0) {
|
||||
@@ -95,6 +114,13 @@ void Shader::UpdateNormalState(bool isInverted)
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::UpdateSsaoActive(bool isActive)
|
||||
{
|
||||
if (mSsaoActivePos >= 0) {
|
||||
glUniform1i(mSsaoActivePos, isActive);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::UpdateTextureSlot(int slot)
|
||||
{
|
||||
if (mTexSlotPos >= 0) {
|
||||
@@ -102,7 +128,7 @@ void Shader::UpdateTextureSlot(int slot)
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::UpdateAlbedoTexSlot(int albedoSlot)
|
||||
void Shader::UpdateColorTexSlot(int albedoSlot)
|
||||
{
|
||||
if (mAlbedoPos >= 0) {
|
||||
glUniform1i(mAlbedoPos, albedoSlot);
|
||||
@@ -123,10 +149,10 @@ void Shader::UpdateNormalTexSlot(int normalSlot)
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::UpdateNoiseTexSlot(int noiseSlot)
|
||||
void Shader::UpdateRandomTexSlot(int randSlot)
|
||||
{
|
||||
if (mNoisePos >= 0) {
|
||||
glUniform1i(mNoisePos, noiseSlot);
|
||||
if (mRandTexPos >= 0) {
|
||||
glUniform1i(mRandTexPos, randSlot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,31 +176,32 @@ void Shader::UpdateCurSegment(int curSeg)
|
||||
}
|
||||
|
||||
|
||||
#ifdef QT_OPENGL_LIB
|
||||
bool CheckCompileResult(int /* shader */)
|
||||
{
|
||||
return false;
|
||||
#else
|
||||
bool CheckCompileResult(int shader)
|
||||
bool CheckCompileResult(int shaderId, const char* shaderName, bool isVertex)
|
||||
{
|
||||
char log[1024];
|
||||
int res = 0;
|
||||
GLsizei len;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &res);
|
||||
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &res);
|
||||
if (res != 0) {
|
||||
return false;
|
||||
}
|
||||
glGetShaderInfoLog(shader, 1020, &len, log);
|
||||
int headerLen = snprintf(log,
|
||||
48,
|
||||
"Error compiling %s %s shader: ",
|
||||
shaderName,
|
||||
isVertex ? "vertex" : "fragment");
|
||||
glGetShaderInfoLog(shaderId, 1020 - headerLen, &len, log + headerLen);
|
||||
len += headerLen;
|
||||
if (len > 1020) {
|
||||
len = 1020;
|
||||
}
|
||||
log[len] = 0;
|
||||
std::cout << log << std::endl;
|
||||
Base::Console().Error(log);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int Shader::CompileShader(const char* _vertShader, const char* _fragShader)
|
||||
unsigned int
|
||||
Shader::CompileShader(const char* name, const char* _vertShader, const char* _fragShader)
|
||||
{
|
||||
vertShader = _vertShader;
|
||||
fragShader = _fragShader;
|
||||
@@ -182,7 +209,7 @@ unsigned int Shader::CompileShader(const char* _vertShader, const char* _fragSha
|
||||
GLint res = 0;
|
||||
glShaderSource(vertex_shader, 1, &vertShader, NULL);
|
||||
glCompileShader(vertex_shader);
|
||||
if (CheckCompileResult(vertex_shader)) {
|
||||
if (CheckCompileResult(vertex_shader, name, true)) {
|
||||
glDeleteShader(vertex_shader);
|
||||
return 0xdeadbeef;
|
||||
}
|
||||
@@ -190,7 +217,7 @@ unsigned int Shader::CompileShader(const char* _vertShader, const char* _fragSha
|
||||
const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader, 1, &fragShader, NULL);
|
||||
glCompileShader(fragment_shader);
|
||||
if (CheckCompileResult(fragment_shader)) {
|
||||
if (CheckCompileResult(fragment_shader, name, false)) {
|
||||
glDeleteShader(fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
return 0xdeadbeef;
|
||||
@@ -220,14 +247,16 @@ unsigned int Shader::CompileShader(const char* _vertShader, const char* _fragSha
|
||||
mObjectColorAlphaPos = glGetUniformLocation(shaderId, "objectColorAlpha");
|
||||
mTexSlotPos = glGetUniformLocation(shaderId, "texSlot");
|
||||
mInvertedNormalsPos = glGetUniformLocation(shaderId, "invertedNormals");
|
||||
mSsaoSamplesPos = glGetUniformLocation(shaderId, "ssaoSamples");
|
||||
mAlbedoPos = glGetUniformLocation(shaderId, "texAlbedo");
|
||||
mPositionPos = glGetUniformLocation(shaderId, "texPosition");
|
||||
mNormalPos = glGetUniformLocation(shaderId, "texNormal");
|
||||
mSsaoPos = glGetUniformLocation(shaderId, "texSsao");
|
||||
mNoisePos = glGetUniformLocation(shaderId, "texNoise");
|
||||
mSamplesPos = glGetUniformLocation(shaderId, "ssaoSamples");
|
||||
mSsaoActivePos = glGetUniformLocation(shaderId, "ssaoActive");
|
||||
mAlbedoPos = glGetUniformLocation(shaderId, "ColorTex");
|
||||
mPositionPos = glGetUniformLocation(shaderId, "PositionTex");
|
||||
mNormalPos = glGetUniformLocation(shaderId, "NormalTex");
|
||||
mSsaoPos = glGetUniformLocation(shaderId, "AoTex");
|
||||
mRandTexPos = glGetUniformLocation(shaderId, "RandTex");
|
||||
mSamplesPos = glGetUniformLocation(shaderId, "SampleKernel");
|
||||
mCurSegmentPos = glGetUniformLocation(shaderId, "curSegment");
|
||||
mScreenWidthPos = glGetUniformLocation(shaderId, "screenWidth");
|
||||
mScreenHeightPos = glGetUniformLocation(shaderId, "screenHeight");
|
||||
|
||||
Activate();
|
||||
return shaderId;
|
||||
@@ -258,7 +287,7 @@ const char* VertShader3DNorm = R"(
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec3 Position;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@@ -268,7 +297,7 @@ const char* VertShader3DNorm = R"(
|
||||
void main(void)
|
||||
{
|
||||
vec4 viewPos = view * model * vec4(aPosition, 1.0);
|
||||
FragPos = vec3(model * vec4(aPosition, 1.0));
|
||||
Position = vec3(model * vec4(aPosition, 1.0));
|
||||
Normal = vec3(normalRot * vec4(aNormal, 1.0));
|
||||
gl_Position = projection * viewPos;
|
||||
}
|
||||
@@ -281,7 +310,7 @@ const char* VertShader3DInvNorm = R"(
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec3 Position;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@@ -291,7 +320,7 @@ const char* VertShader3DInvNorm = R"(
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = projection * view * model * vec4(aPosition, 1.0);
|
||||
FragPos = vec3(model * vec4(aPosition, 1.0));
|
||||
Position = vec3(model * vec4(aPosition, 1.0));
|
||||
Normal = -vec3(normalRot * vec4(aNormal, 1.0));
|
||||
}
|
||||
)";
|
||||
@@ -338,7 +367,7 @@ const char* FragShaderNorm = R"(
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 Normal;
|
||||
in vec3 FragPos;
|
||||
in vec3 Position;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
@@ -348,7 +377,7 @@ const char* FragShaderNorm = R"(
|
||||
void main()
|
||||
{
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
vec3 lightDir = normalize(lightPos - Position);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
vec3 result = (lightAmbient + diffuse) * objectColor;
|
||||
@@ -362,7 +391,7 @@ const char* FragShaderFlat = R"(
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 Normal;
|
||||
in vec3 FragPos;
|
||||
in vec3 Position;
|
||||
uniform vec3 objectColor;
|
||||
|
||||
void main()
|
||||
@@ -407,7 +436,7 @@ const char* VertShaderGeom = R"(
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Position;
|
||||
out vec3 Normal;
|
||||
|
||||
uniform bool invertedNormals;
|
||||
@@ -419,7 +448,7 @@ const char* VertShaderGeom = R"(
|
||||
void main()
|
||||
{
|
||||
vec4 viewPos = view * model * vec4(aPos, 1.0);
|
||||
FragPos = viewPos.xyz;
|
||||
Position = viewPos.xyz;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(view * model)));
|
||||
Normal = normalMatrix * (invertedNormals ? -aNormal : aNormal);
|
||||
@@ -430,82 +459,99 @@ const char* VertShaderGeom = R"(
|
||||
|
||||
const char* FragShaderGeom = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) out vec4 texAlbedo;
|
||||
layout (location = 1) out vec3 texPosition;
|
||||
layout (location = 2) out vec3 texNormal;
|
||||
layout (location = 0) out vec4 ColorTex;
|
||||
layout (location = 1) out vec3 PositionTex;
|
||||
layout (location = 2) out vec3 NormalTex;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
|
||||
uniform vec3 objectColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// store the fragment position vector in the first gbuffer texture
|
||||
texPosition = FragPos;
|
||||
// also store the per-fragment normals into the gbuffer
|
||||
texNormal = normalize(Normal);
|
||||
// and the diffuse per-fragment color
|
||||
texAlbedo = vec4(objectColor, 1.0f);
|
||||
// Store position, normal, and diffuse color in textures
|
||||
PositionTex = Position;
|
||||
NormalTex = normalize(Normal);
|
||||
ColorTex = vec4(objectColor, 1.0f);
|
||||
}
|
||||
)";
|
||||
|
||||
const char* FragShaderSSAO = R"(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
layout (location = 0) out float AoData;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texNoise;
|
||||
uniform sampler2D texPosition;
|
||||
uniform sampler2D texNormal;
|
||||
uniform sampler2D RandTex;
|
||||
uniform sampler2D PositionTex;
|
||||
uniform sampler2D NormalTex;
|
||||
|
||||
uniform vec3 ssaoSamples[64];
|
||||
|
||||
// parameters (you'd probably want to use them as uniforms to more easily tweak the effect)
|
||||
int kernelSize = 64;
|
||||
float radius = 30f;
|
||||
float bias = 0.01;
|
||||
|
||||
// tile noise texture over screen based on screen dimensions divided by noise size
|
||||
const vec2 noiseScale = vec2(800.0/4.0, 600.0/4.0);
|
||||
const int kernelSize = 64;
|
||||
uniform vec3 SampleKernel[kernelSize];
|
||||
uniform float Radius = 20.0f;
|
||||
uniform float screenWidth = 800.0;
|
||||
uniform float screenHeight = 600.0;
|
||||
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
// get input for SSAO algorithm
|
||||
vec3 fragPos = texture(texPosition, texCoord).xyz;
|
||||
vec3 normal = normalize(texture(texNormal, texCoord).rgb);
|
||||
vec3 randomVec = normalize(texture(texNoise, texCoord * noiseScale).xyz);
|
||||
// create TBN change-of-basis matrix: from tangent-space to view-space
|
||||
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
mat3 TBN = mat3(tangent, bitangent, normal);
|
||||
// iterate over the sample kernel and calculate occlusion factor
|
||||
float occlusion = 0.0;
|
||||
for(int i = 0; i < kernelSize; ++i)
|
||||
{
|
||||
// get sample position
|
||||
vec3 samplePos = TBN * ssaoSamples[i]; // from tangent to view-space
|
||||
samplePos = fragPos + samplePos * radius;
|
||||
// Create the random tangent space matrix
|
||||
vec2 randScale = vec2( screenWidth / 4.0, screenHeight / 4.0 );
|
||||
vec3 randDir = normalize( texture(RandTex, texCoord.xy * randScale).xyz );
|
||||
vec3 n = normalize( texture(NormalTex, texCoord).xyz );
|
||||
vec3 biTang = cross( n, randDir );
|
||||
if( length(biTang) < 0.0001 ) // If n and randDir are parallel, n is in x-y plane
|
||||
biTang = cross( n, vec3(0,0,1));
|
||||
biTang = normalize(biTang);
|
||||
vec3 tang = cross(biTang, n);
|
||||
mat3 toCamSpace = mat3(tang, biTang, n);
|
||||
|
||||
// project sample position (to sample texture) (to get position on screen/texture)
|
||||
vec4 offset = vec4(samplePos, 1.0);
|
||||
offset = projection * offset; // from view to clip-space
|
||||
offset.xyz /= offset.w; // perspective divide
|
||||
offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
|
||||
float occlusionSum = 0.0;
|
||||
vec3 camPos = texture(PositionTex, texCoord).xyz;
|
||||
for( int i = 0; i < kernelSize; i++ ) {
|
||||
vec3 samplePos = camPos + Radius * (toCamSpace * SampleKernel[i]);
|
||||
|
||||
// get sample depth
|
||||
float sampleDepth = texture(texPosition, offset.xy).z; // get depth value of kernel
|
||||
// sample
|
||||
// Project point
|
||||
vec4 p = projection * vec4(samplePos,1);
|
||||
p *= 1.0 / p.w;
|
||||
p.xyz = p.xyz * 0.5 + 0.5;
|
||||
|
||||
// range check & accumulate
|
||||
float rangeCheck = smoothstep(0.0, 1.0, radius * 0.1f / abs(sampleDepth - fragPos.z));
|
||||
occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck;
|
||||
// Access camera space z-coordinate at that point
|
||||
float surfaceZ = texture(PositionTex, p.xy).z;
|
||||
float zDist = surfaceZ - camPos.z;
|
||||
|
||||
// Count points that ARE occluded
|
||||
if( zDist >= 0.0 && zDist <= Radius && surfaceZ > samplePos.z ) occlusionSum += 1.0;
|
||||
}
|
||||
occlusion = 1.0 - (occlusion / kernelSize);
|
||||
FragColor = vec4(occlusion, 0, 0, 1);
|
||||
|
||||
float occ = occlusionSum / kernelSize;
|
||||
AoData = 1.0 - occ;
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
const char* FragShaderSSAOBlur = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) out float AoData;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D AoTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 pix = ivec2( gl_FragCoord.xy );
|
||||
float sum = 0.0;
|
||||
for( int x = -1; x <= 2; ++x ) {
|
||||
for( int y = -1; y <= 2; y++ ) {
|
||||
sum += texelFetchOffset( AoTex, pix, 0, ivec2(x,y) ).r;
|
||||
}
|
||||
}
|
||||
|
||||
float ao = sum * (1.0 / 16.0);
|
||||
AoData = ao;
|
||||
}
|
||||
)";
|
||||
|
||||
@@ -515,112 +561,40 @@ const char* FragShaderSSAOLighting = R"(
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texSsao;
|
||||
uniform sampler2D texAlbedo;
|
||||
uniform sampler2D texPosition;
|
||||
uniform sampler2D texNormal;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 lightAmbient;
|
||||
|
||||
uniform float lightLinear;
|
||||
uniform bool ssaoActive;
|
||||
|
||||
uniform sampler2D ColorTex;
|
||||
uniform sampler2D PositionTex;
|
||||
uniform sampler2D NormalTex;
|
||||
uniform sampler2D AoTex;
|
||||
|
||||
vec3 ambAndDiffuse( vec3 pos, vec3 norm, vec3 diff, float ao ) {
|
||||
ao = pow(ao, 4);
|
||||
vec3 ambient = lightAmbient * diff * ao;
|
||||
vec3 s = normalize( lightPos - pos);
|
||||
float sDotN = max( dot(s,norm), 0.0 );
|
||||
return ambient + lightColor * diff * sDotN;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// retrieve data from gbuffer
|
||||
vec4 DiffuseA = texture(texAlbedo, texCoord);
|
||||
vec3 Diffuse = DiffuseA.rgb;
|
||||
vec3 FragPos = texture(texPosition, texCoord).rgb;
|
||||
vec3 Normal = texture(texNormal, texCoord).rgb;
|
||||
float AmbientOcclusion = texture(texSsao, texCoord).r;
|
||||
vec3 pos = texture( PositionTex, texCoord ).xyz;
|
||||
vec3 norm = texture( NormalTex, texCoord ).xyz;
|
||||
vec4 DiffColorA = texture(ColorTex, texCoord);
|
||||
vec3 diffColor = DiffColorA.rgb;
|
||||
float aoVal = ssaoActive ? texture( AoTex, texCoord).r : 1.0;
|
||||
|
||||
// then calculate lighting as usual
|
||||
vec3 lighting = lightAmbient * Diffuse * AmbientOcclusion;
|
||||
vec3 viewDir = normalize(-FragPos); // viewpos is (0.0.0)
|
||||
// diffuse
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * lightColor;
|
||||
// specular
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(Normal, halfwayDir), 0.0), 16.0);
|
||||
vec3 specular = lightColor * spec;
|
||||
// attenuation
|
||||
float distance = length(lightPos - FragPos);
|
||||
float attenuation = 1.0 / (1.0 + lightLinear * distance);
|
||||
lighting += (diffuse + specular * 0.3) * attenuation;
|
||||
vec3 col = ambAndDiffuse(pos, norm, diffColor, aoVal);
|
||||
col = pow(col, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(lighting, DiffuseA.a);
|
||||
FragColor = vec4( col, DiffColorA.a );
|
||||
}
|
||||
)";
|
||||
|
||||
const char* FragShaderStdLighting = R"(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texAlbedo;
|
||||
uniform sampler2D texPosition;
|
||||
uniform sampler2D texNormal;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
uniform float lightLinear;
|
||||
uniform vec3 lightAmbient;
|
||||
|
||||
void main()
|
||||
{
|
||||
// retrieve data from gbuffer
|
||||
vec4 DiffuseA = texture(texAlbedo, texCoord);
|
||||
vec3 Diffuse = DiffuseA.rgb;
|
||||
vec3 FragPos = texture(texPosition, texCoord).rgb;
|
||||
vec3 Normal = texture(texNormal, texCoord).rgb;
|
||||
|
||||
// then calculate lighting as usual
|
||||
vec3 lighting = lightAmbient * Diffuse;
|
||||
vec3 viewDir = normalize(-FragPos); // viewpos is (0.0.0)
|
||||
// diffuse
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * lightColor;
|
||||
// specular
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(Normal, halfwayDir), 0.0), 16.0);
|
||||
vec3 specular = lightColor * spec;
|
||||
// attenuation
|
||||
float distance = length(lightPos - FragPos);
|
||||
float attenuation = 1.0 / (1.0 + lightLinear * distance);
|
||||
lighting += (diffuse + specular * 0.3) * attenuation;
|
||||
|
||||
FragColor = vec4(lighting, DiffuseA.a);
|
||||
}
|
||||
)";
|
||||
|
||||
const char* FragShaderSSAOBlur = R"(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texSsao;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(texSsao, 0));
|
||||
float result = 0.0;
|
||||
for (int x = -2; x <= 1; ++x)
|
||||
{
|
||||
for (int y = -2; y <= 1; ++y)
|
||||
{
|
||||
vec2 offset = vec2(float(x), float(y)) * texelSize;
|
||||
result += texture(texSsao, texCoord + offset).r;
|
||||
}
|
||||
}
|
||||
FragColor = vec4(result / (4.0 * 4.0), 0, 0, 1);
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
const char* VertShader3DLine = R"(
|
||||
#version 330 core
|
||||
|
||||
|
||||
@@ -41,18 +41,20 @@ public:
|
||||
void UpdateProjectionMat(mat4x4 mat);
|
||||
void UpdateViewMat(mat4x4 mat);
|
||||
void UpdateEnvColor(vec3 lightPos, vec3 lightColor, vec3 ambient, float linearity);
|
||||
void UpdateScreenDimension(int width, int height);
|
||||
void UpdateObjColor(vec3 objColor);
|
||||
void UpdateObjColorAlpha(vec4 objColor);
|
||||
void UpdateNormalState(bool isInverted);
|
||||
void UpdateSsaoActive(bool isInverted);
|
||||
void UpdateTextureSlot(int slot);
|
||||
void UpdateAlbedoTexSlot(int albedoSlot);
|
||||
void UpdateColorTexSlot(int albedoSlot);
|
||||
void UpdatePositionTexSlot(int positionSlot);
|
||||
void UpdateNormalTexSlot(int normalSlot);
|
||||
void UpdateNoiseTexSlot(int noiseSlot);
|
||||
void UpdateRandomTexSlot(int noiseSlot);
|
||||
void UpdateSsaoTexSlot(int ssaoSlot);
|
||||
void UpdateKernelVals(int nVals, float* vals);
|
||||
void UpdateCurSegment(int curSeg);
|
||||
unsigned int CompileShader(const char* vertShader, const char* fragShader);
|
||||
unsigned int CompileShader(const char* name, const char* vertShader, const char* fragShader);
|
||||
void Activate();
|
||||
void Destroy();
|
||||
bool IsValid()
|
||||
@@ -74,14 +76,16 @@ protected:
|
||||
int mObjectColorAlphaPos = -1;
|
||||
int mTexSlotPos = -1;
|
||||
int mInvertedNormalsPos = -1;
|
||||
int mSsaoSamplesPos = -1;
|
||||
int mSsaoActivePos = -1;
|
||||
int mAlbedoPos = -1;
|
||||
int mPositionPos = -1;
|
||||
int mNormalPos = -1;
|
||||
int mSsaoPos = -1;
|
||||
int mNoisePos = -1;
|
||||
int mRandTexPos = -1;
|
||||
int mSamplesPos = -1;
|
||||
int mCurSegmentPos = -1;
|
||||
int mScreenWidthPos = -1;
|
||||
int mScreenHeightPos = -1;
|
||||
|
||||
const char* vertShader = nullptr;
|
||||
const char* fragShader = nullptr;
|
||||
|
||||
@@ -18,14 +18,19 @@
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
* *
|
||||
* Portions of this code are taken from: *
|
||||
* "OpenGL 4 Shading Language cookbook" Third edition *
|
||||
* Written by: David Wolff *
|
||||
* Published by: <packt> www.packt.com *
|
||||
* License: MIT License *
|
||||
* *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "SimDisplay.h"
|
||||
#include "linmath.h"
|
||||
#include "OpenGlWrapper.h"
|
||||
#include <random>
|
||||
|
||||
#define GL_UBYTE GL_UNSIGNED_BYTE
|
||||
|
||||
|
||||
namespace MillSim
|
||||
@@ -35,51 +40,44 @@ void SimDisplay::InitShaders()
|
||||
{
|
||||
// use shaders
|
||||
// standard diffuse shader
|
||||
shader3D.CompileShader(VertShader3DNorm, FragShaderNorm);
|
||||
shader3D.CompileShader("StdDiffuse", VertShader3DNorm, FragShaderNorm);
|
||||
shader3D.UpdateEnvColor(lightPos, lightColor, ambientCol, 0.0f);
|
||||
|
||||
// invarted normal diffuse shader for inner mesh
|
||||
shaderInv3D.CompileShader(VertShader3DInvNorm, FragShaderNorm);
|
||||
shaderInv3D.CompileShader("InvertNormal", VertShader3DInvNorm, FragShaderNorm);
|
||||
shaderInv3D.UpdateEnvColor(lightPos, lightColor, ambientCol, 0.0f);
|
||||
|
||||
// null shader to calculate meshes only (simulation stage)
|
||||
shaderFlat.CompileShader(VertShader3DNorm, FragShaderFlat);
|
||||
shaderFlat.CompileShader("Null", VertShader3DNorm, FragShaderFlat);
|
||||
|
||||
// texture shader to render Simulator FBO
|
||||
shaderSimFbo.CompileShader(VertShader2DFbo, FragShader2dFbo);
|
||||
shaderSimFbo.CompileShader("Texture", VertShader2DFbo, FragShader2dFbo);
|
||||
shaderSimFbo.UpdateTextureSlot(0);
|
||||
|
||||
// geometric shader - generate texture with all geometric info for further processing
|
||||
shaderGeom.CompileShader(VertShaderGeom, FragShaderGeom);
|
||||
shaderGeomCloser.CompileShader(VertShaderGeom, FragShaderGeom);
|
||||
|
||||
// lighting shader - apply standard lighting based on geometric buffers
|
||||
shaderLighting.CompileShader(VertShader2DFbo, FragShaderStdLighting);
|
||||
shaderLighting.UpdateAlbedoTexSlot(0);
|
||||
shaderLighting.UpdatePositionTexSlot(1);
|
||||
shaderLighting.UpdateNormalTexSlot(2);
|
||||
shaderLighting.UpdateEnvColor(lightPos, lightColor, ambientCol, 0.01f);
|
||||
shaderGeom.CompileShader("Geometric", VertShaderGeom, FragShaderGeom);
|
||||
shaderGeomCloser.CompileShader("GeomCloser", VertShaderGeom, FragShaderGeom);
|
||||
|
||||
// SSAO shader - generate SSAO info and embed in texture buffer
|
||||
shaderSSAO.CompileShader(VertShader2DFbo, FragShaderSSAO);
|
||||
shaderSSAO.UpdateNoiseTexSlot(0);
|
||||
shaderSSAO.CompileShader("SSAO", VertShader2DFbo, FragShaderSSAO);
|
||||
shaderSSAO.UpdateRandomTexSlot(0);
|
||||
shaderSSAO.UpdatePositionTexSlot(1);
|
||||
shaderSSAO.UpdateNormalTexSlot(2);
|
||||
|
||||
// SSAO blur shader - smooth generated SSAO texture
|
||||
shaderSSAOBlur.CompileShader(VertShader2DFbo, FragShaderSSAOBlur);
|
||||
shaderSSAOBlur.CompileShader("Blur", VertShader2DFbo, FragShaderSSAOBlur);
|
||||
shaderSSAOBlur.UpdateSsaoTexSlot(0);
|
||||
|
||||
// SSAO lighting shader - apply lightig modified by SSAO calculations
|
||||
shaderSSAOLighting.CompileShader(VertShader2DFbo, FragShaderSSAOLighting);
|
||||
shaderSSAOLighting.UpdateAlbedoTexSlot(0);
|
||||
shaderSSAOLighting.CompileShader("SsaoLighting", VertShader2DFbo, FragShaderSSAOLighting);
|
||||
shaderSSAOLighting.UpdateColorTexSlot(0);
|
||||
shaderSSAOLighting.UpdatePositionTexSlot(1);
|
||||
shaderSSAOLighting.UpdateNormalTexSlot(2);
|
||||
shaderSSAOLighting.UpdateSsaoTexSlot(3);
|
||||
shaderSSAOLighting.UpdateEnvColor(lightPos, lightColor, ambientCol, 0.01f);
|
||||
|
||||
// Mill Path Line Shader
|
||||
shaderLinePath.CompileShader(VertShader3DLine, FragShader3DLine);
|
||||
shaderLinePath.CompileShader("PathLine", VertShader3DLine, FragShader3DLine);
|
||||
}
|
||||
|
||||
void SimDisplay::CreateFboQuad()
|
||||
@@ -101,6 +99,40 @@ void SimDisplay::CreateFboQuad()
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
|
||||
}
|
||||
|
||||
void SimDisplay::CreateGBufTex(GLenum texUnit,
|
||||
GLint intFormat,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
GLuint& texid)
|
||||
{
|
||||
glActiveTexture(texUnit);
|
||||
glGenTextures(1, &texid);
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, intFormat, mWidth, mHeight, 0, format, type, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
}
|
||||
|
||||
void SimDisplay::UniformHemisphere(vec3& randVec)
|
||||
{
|
||||
float x1 = distr01(generator);
|
||||
float x2 = distr01(generator);
|
||||
float s = sqrt(1.0f - x1 * x1);
|
||||
randVec[0] = cosf(PI2 * x2) * s;
|
||||
randVec[1] = sinf(PI2 * x2) * s;
|
||||
randVec[2] = x1;
|
||||
}
|
||||
|
||||
void SimDisplay::UniformCircle(vec3& randVec)
|
||||
{
|
||||
float x = distr01(generator);
|
||||
randVec[0] = cosf(PI2 * x);
|
||||
randVec[1] = sinf(PI2 * x);
|
||||
randVec[2] = 0;
|
||||
}
|
||||
|
||||
|
||||
void SimDisplay::CreateDisplayFbos()
|
||||
{
|
||||
// setup frame buffer for simulation
|
||||
@@ -108,51 +140,15 @@ void SimDisplay::CreateDisplayFbos()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
|
||||
|
||||
// a color texture for the frame buffer
|
||||
glGenTextures(1, &mFboColTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboColTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA8,
|
||||
gWindowSizeW,
|
||||
gWindowSizeH,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_UBYTE,
|
||||
NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
CreateGBufTex(GL_TEXTURE0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, mFboColTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFboColTexture, 0);
|
||||
|
||||
// a position texture for the frame buffer
|
||||
glGenTextures(1, &mFboPosTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboPosTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA16F,
|
||||
gWindowSizeW,
|
||||
gWindowSizeH,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
CreateGBufTex(GL_TEXTURE1, GL_RGB32F, GL_RGBA, GL_FLOAT, mFboPosTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mFboPosTexture, 0);
|
||||
|
||||
// a normal texture for the frame buffer
|
||||
glGenTextures(1, &mFboNormTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboNormTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA16F,
|
||||
gWindowSizeW,
|
||||
gWindowSizeH,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
CreateGBufTex(GL_TEXTURE2, GL_RGB32F, GL_RGBA, GL_FLOAT, mFboNormTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, mFboNormTexture, 0);
|
||||
|
||||
|
||||
@@ -166,8 +162,8 @@ void SimDisplay::CreateDisplayFbos()
|
||||
glRenderbufferStorage(
|
||||
GL_RENDERBUFFER,
|
||||
GL_DEPTH24_STENCIL8,
|
||||
gWindowSizeW,
|
||||
gWindowSizeH); // use a single renderbuffer object for both a depth AND stencil buffer.
|
||||
mWidth,
|
||||
mHeight); // use a single renderbuffer object for both a depth AND stencil buffer.
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
|
||||
GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER,
|
||||
@@ -180,7 +176,6 @@ void SimDisplay::CreateDisplayFbos()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
void SimDisplay::CreateSsaoFbos()
|
||||
{
|
||||
|
||||
@@ -190,11 +185,7 @@ void SimDisplay::CreateSsaoFbos()
|
||||
glGenFramebuffers(1, &mSsaoFbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSsaoFbo);
|
||||
// SSAO color buffer
|
||||
glGenTextures(1, &mFboSsaoTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, gWindowSizeW, gWindowSizeH, 0, GL_RED, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
CreateGBufTex(GL_TEXTURE0, GL_R16F, GL_RED, GL_FLOAT, mFboSsaoTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFboSsaoTexture, 0);
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
mSsaoValid = false;
|
||||
@@ -204,11 +195,7 @@ void SimDisplay::CreateSsaoFbos()
|
||||
// setup framebuffer for SSAO blur processing
|
||||
glGenFramebuffers(1, &mSsaoBlurFbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSsaoBlurFbo);
|
||||
glGenTextures(1, &mFboSsaoBlurTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoBlurTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, gWindowSizeW, gWindowSizeH, 0, GL_RED, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
CreateGBufTex(GL_TEXTURE0, GL_R16F, GL_RED, GL_FLOAT, mFboSsaoBlurTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
@@ -222,46 +209,36 @@ void SimDisplay::CreateSsaoFbos()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// generate sample kernel
|
||||
std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0);
|
||||
std::default_random_engine generator;
|
||||
for (unsigned int i = 0; i < 64; ++i) {
|
||||
int kernSize = 64;
|
||||
for (int i = 0; i < kernSize; i++) {
|
||||
vec3 sample;
|
||||
vec3_set(sample,
|
||||
randomFloats(generator) * 2.0f - 1.0f,
|
||||
randomFloats(generator) * 2.0f - 1.0f,
|
||||
randomFloats(generator)); // * 2.0f - 1.0f);
|
||||
vec3_norm(sample, sample);
|
||||
vec3_scale(sample, sample, randomFloats(generator));
|
||||
float scale = float(i) / 64.0f;
|
||||
|
||||
// scale samples s.t. they're more aligned to center of kernel
|
||||
scale = Lerp(0.1f, 1.0f, scale * scale);
|
||||
vec3_scale(sample, sample, scale);
|
||||
UniformHemisphere(sample);
|
||||
float scale = ((float)(i * i)) / (kernSize * kernSize);
|
||||
float interpScale = 0.1f * (1.0f - scale) + scale;
|
||||
vec3_scale(sample, sample, interpScale);
|
||||
mSsaoKernel.push_back(*(Point3D*)sample);
|
||||
}
|
||||
shaderSSAO.Activate();
|
||||
shaderSSAO.UpdateKernelVals(mSsaoKernel.size(), &mSsaoKernel[0].x);
|
||||
|
||||
// generate noise texture
|
||||
std::vector<Point3D> ssaoNoise;
|
||||
for (unsigned int i = 0; i < 16; i++) {
|
||||
vec3 noise;
|
||||
vec3_set(noise,
|
||||
randomFloats(generator) * 2.0f - 1.0f,
|
||||
randomFloats(generator) * 2.0f - 1.0f,
|
||||
0.0f); // rotate around z-axis (in tangent space)
|
||||
ssaoNoise.push_back(*(Point3D*)noise);
|
||||
// generate random direction texture
|
||||
int randSize = 4 * 4;
|
||||
std::vector<Point3D> randDirections;
|
||||
for (int i = 0; i < randSize; i++) {
|
||||
vec3 randvec;
|
||||
UniformCircle(randvec);
|
||||
randDirections.push_back(*(Point3D*)randvec);
|
||||
}
|
||||
glGenTextures(1, &mFboSsaoNoiseTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoNoiseTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
|
||||
|
||||
glGenTextures(1, &mFboRandTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboRandTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, 4, 0, GL_RGB, GL_FLOAT, &randDirections[0].x);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
|
||||
|
||||
SimDisplay::~SimDisplay()
|
||||
{
|
||||
CleanGL();
|
||||
@@ -276,6 +253,8 @@ void SimDisplay::InitGL()
|
||||
// setup light object
|
||||
mlightObject.GenerateBoxStock(-0.5f, -0.5f, -0.5f, 1, 1, 1);
|
||||
|
||||
mWidth = gWindowSizeW;
|
||||
mHeight = gWindowSizeH;
|
||||
InitShaders();
|
||||
CreateDisplayFbos();
|
||||
CreateSsaoFbos();
|
||||
@@ -298,7 +277,7 @@ void SimDisplay::CleanFbos()
|
||||
GLDELETE_TEXTURE(mFboNormTexture);
|
||||
GLDELETE_TEXTURE(mFboSsaoTexture);
|
||||
GLDELETE_TEXTURE(mFboSsaoBlurTexture);
|
||||
GLDELETE_TEXTURE(mFboSsaoNoiseTexture);
|
||||
GLDELETE_TEXTURE(mFboRandTexture);
|
||||
GLDELETE_RENDERBUFFER(mRboDepthStencil);
|
||||
}
|
||||
|
||||
@@ -317,7 +296,6 @@ void SimDisplay::CleanGL()
|
||||
shaderSimFbo.Destroy();
|
||||
shaderGeom.Destroy();
|
||||
shaderSSAO.Destroy();
|
||||
shaderLighting.Destroy();
|
||||
shaderSSAOLighting.Destroy();
|
||||
shaderSSAOBlur.Destroy();
|
||||
|
||||
@@ -394,10 +372,10 @@ void SimDisplay::ScaleViewToStock(StockObject* obj)
|
||||
mlightObject.SetPosition(lightPos);
|
||||
}
|
||||
|
||||
void SimDisplay::RenderResult()
|
||||
void SimDisplay::RenderResult(bool recalculate)
|
||||
{
|
||||
if (mSsaoValid && applySSAO) {
|
||||
RenderResultSSAO();
|
||||
RenderResultSSAO(recalculate);
|
||||
}
|
||||
else {
|
||||
RenderResultStandard();
|
||||
@@ -410,7 +388,11 @@ void SimDisplay::RenderResultStandard()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// display the sim result within the FBO
|
||||
shaderLighting.Activate();
|
||||
shaderSSAOLighting.Activate();
|
||||
shaderSSAOLighting.UpdateColorTexSlot(0);
|
||||
shaderSSAOLighting.UpdatePositionTexSlot(1);
|
||||
shaderSSAOLighting.UpdateNormalTexSlot(2);
|
||||
shaderSSAOLighting.UpdateSsaoActive(false);
|
||||
// shaderSimFbo.Activate();
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@@ -426,47 +408,57 @@ void SimDisplay::RenderResultStandard()
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
void SimDisplay::RenderResultSSAO()
|
||||
void SimDisplay::RenderResultSSAO(bool recalculate)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
// generate SSAO texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSsaoFbo);
|
||||
shaderSSAO.Activate();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoNoiseTexture);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboPosTexture);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboNormTexture);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
if (recalculate) {
|
||||
// generate SSAO texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSsaoFbo);
|
||||
shaderSSAO.Activate();
|
||||
shaderSSAO.UpdateRandomTexSlot(0);
|
||||
shaderSSAO.UpdatePositionTexSlot(1);
|
||||
shaderSSAO.UpdateNormalTexSlot(2);
|
||||
shaderSSAO.UpdateScreenDimension(mWidth, mHeight);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboRandTexture);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboPosTexture);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboNormTexture);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// blur SSAO texture to remove noise
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSsaoBlurFbo);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
shaderSSAOBlur.Activate();
|
||||
shaderSSAOBlur.UpdateSsaoTexSlot(0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoTexture);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
// lighting pass:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// blur SSAO texture to remove noise
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSsaoBlurFbo);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
shaderSSAOBlur.Activate();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoTexture);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// lighting pass: deferred Blinn-Phong lighting with added screen-space ambient occlusion
|
||||
shaderSSAOLighting.Activate();
|
||||
shaderSSAOLighting.UpdateAlbedoTexSlot(0);
|
||||
shaderSSAOLighting.UpdateColorTexSlot(0);
|
||||
shaderSSAOLighting.UpdatePositionTexSlot(1);
|
||||
shaderSSAOLighting.UpdateNormalTexSlot(2);
|
||||
shaderSSAOLighting.UpdateSsaoTexSlot(3);
|
||||
shaderSSAOLighting.UpdateSsaoActive(true);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboColTexture);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboPosTexture);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboNormTexture);
|
||||
glActiveTexture(GL_TEXTURE3); // add extra SSAO texture to lighting pass
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoBlurTexture);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -544,6 +536,8 @@ void SimDisplay::UpdateEyeFactor(float factor)
|
||||
|
||||
void SimDisplay::UpdateWindowScale()
|
||||
{
|
||||
mWidth = gWindowSizeW;
|
||||
mHeight = gWindowSizeH;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
|
||||
CleanFbos();
|
||||
CreateDisplayFbos();
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
#include "StockObject.h"
|
||||
#include "MillPathLine.h"
|
||||
#include <vector>
|
||||
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
|
||||
namespace MillSim
|
||||
{
|
||||
@@ -52,9 +53,9 @@ public:
|
||||
void StartCloserGeometryPass(vec3 objColor);
|
||||
void RenderLightObject();
|
||||
void ScaleViewToStock(StockObject* obj);
|
||||
void RenderResult();
|
||||
void RenderResult(bool recalculate);
|
||||
void RenderResultStandard();
|
||||
void RenderResultSSAO();
|
||||
void RenderResultSSAO(bool recalculate);
|
||||
void SetupLinePathPass(int curSegment, bool isHidden);
|
||||
void TiltEye(float tiltStep);
|
||||
void RotateEye(float rotStep);
|
||||
@@ -79,20 +80,19 @@ protected:
|
||||
void CreateDisplayFbos();
|
||||
void CreateSsaoFbos();
|
||||
void CreateFboQuad();
|
||||
float Lerp(float a, float b, float f)
|
||||
{
|
||||
return a + f * (b - a);
|
||||
}
|
||||
void CreateGBufTex(GLenum texUnit, GLint intFormat, GLenum format, GLenum type, GLuint& texid);
|
||||
void UniformHemisphere(vec3& randVec);
|
||||
void UniformCircle(vec3& randVec);
|
||||
|
||||
protected:
|
||||
// shaders
|
||||
Shader shader3D, shaderInv3D, shaderFlat, shaderSimFbo;
|
||||
Shader shaderGeom, shaderSSAO, shaderLighting, shaderSSAOLighting, shaderSSAOBlur;
|
||||
Shader shaderGeom, shaderSSAO, shaderSSAOLighting, shaderSSAOBlur;
|
||||
Shader shaderGeomCloser;
|
||||
Shader shaderLinePath;
|
||||
vec3 lightColor = {0.8f, 0.9f, 1.0f};
|
||||
vec3 lightColor = {0.5f, 0.6f, 0.7f};
|
||||
vec3 lightPos = {20.0f, 20.0f, 10.0f};
|
||||
vec3 ambientCol = {0.6f, 0.6f, 0.7f};
|
||||
vec3 ambientCol = {0.2f, 0.2f, 0.25f};
|
||||
vec4 pathLineColor = {0.0f, 0.9f, 0.0f, 1.0};
|
||||
vec3 pathLineColorPassed = {0.9f, 0.3f, 0.3f};
|
||||
|
||||
@@ -103,6 +103,12 @@ protected:
|
||||
mat4x4 mMatLookAt;
|
||||
StockObject mlightObject;
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
|
||||
std::mt19937 generator;
|
||||
std::uniform_real_distribution<float> distr01;
|
||||
|
||||
|
||||
float mEyeDistance = 30;
|
||||
float mEyeRoration = 0;
|
||||
@@ -131,7 +137,7 @@ protected:
|
||||
unsigned int mSsaoBlurFbo;
|
||||
unsigned int mFboSsaoTexture;
|
||||
unsigned int mFboSsaoBlurTexture;
|
||||
unsigned int mFboSsaoNoiseTexture;
|
||||
unsigned int mFboRandTexture;
|
||||
};
|
||||
|
||||
} // namespace MillSim
|
||||
|
||||
Reference in New Issue
Block a user