SSAO getting close (excited)
parent
532a0fa9f2
commit
39d2bb68f8
|
@ -1,6 +1,6 @@
|
||||||
#version 150 core
|
#version 150 core
|
||||||
|
|
||||||
in vec2 ioUV;
|
in vec2 ioFragTexCoords;
|
||||||
|
|
||||||
out vec3 outColor;
|
out vec3 outColor;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ uniform float uNear;
|
||||||
uniform float uFar;
|
uniform float uFar;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float z = texture(uDepthTexture, ioUV).r;
|
float z = texture(uDepthTexture, ioFragTexCoords).r;
|
||||||
float c;
|
float c;
|
||||||
if (uIsOrthographic == 1.0) {
|
if (uIsOrthographic == 1.0) {
|
||||||
c = z;
|
c = z;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#version 150 core
|
#version 150 core
|
||||||
|
|
||||||
in vec2 ioUV;
|
in vec2 ioFragTexCoords;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
uniform sampler2D uTexture;
|
uniform sampler2D uTexture;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
outColor = texture(uTexture, ioUV);
|
outColor = texture(uTexture, ioFragTexCoords);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#version 150 core
|
||||||
|
|
||||||
|
in vec2 ioFragTexCoords;
|
||||||
|
|
||||||
|
out vec3 outColor;
|
||||||
|
|
||||||
|
uniform sampler2D uPositions;
|
||||||
|
uniform sampler2D uNormals;
|
||||||
|
uniform sampler2D uNoise;
|
||||||
|
|
||||||
|
uniform float uRadius;
|
||||||
|
uniform float uBias;
|
||||||
|
uniform int uSampleCount;
|
||||||
|
uniform vec3 uSamples[64];
|
||||||
|
uniform mat4 uProjection;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 noise_scale = textureSize(uPositions, 0) / 2.0;
|
||||||
|
|
||||||
|
vec3 position = texture(uPositions, ioFragTexCoords).xyz;
|
||||||
|
vec3 normal = normalize(texture(uNormals, ioFragTexCoords)).rgb;
|
||||||
|
vec3 random_vector = normalize(texture(uNoise, ioFragTexCoords * noise_scale).xyz);
|
||||||
|
|
||||||
|
vec3 tangent = normalize(random_vector - normal * dot(random_vector, normal));
|
||||||
|
vec3 bitangent = cross(normal, tangent);
|
||||||
|
mat3 TBN = mat3 (tangent, bitangent, normal);
|
||||||
|
|
||||||
|
float occlusion = 0.0;
|
||||||
|
for (int i = 0; i < uSampleCount; ++i) {
|
||||||
|
vec3 sample = TBN * uSamples[i];
|
||||||
|
sample = position + sample * uRadius;
|
||||||
|
|
||||||
|
vec4 offset = vec4(sample, 1.0);
|
||||||
|
offset = uProjection * offset;
|
||||||
|
offset.xyz /= offset.w;
|
||||||
|
offset.xyz = offset.xyz * 0.5 + 0.5;
|
||||||
|
float sample_depth = texture(uPositions, offset.xy).z;
|
||||||
|
|
||||||
|
float range_check = smoothstep(0.0, 1.0, uRadius / abs(position.z - sample_depth));
|
||||||
|
occlusion += (sample_depth >= sample.z + uBias ? 1.0 : 0.0) * range_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
occlusion = 1.0 - (occlusion / uSampleCount);
|
||||||
|
outColor = vec3(occlusion);
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
#version 150 core
|
#version 150 core
|
||||||
#extension GL_ARB_explicit_attrib_location : require
|
|
||||||
|
|
||||||
in vec4 inCoord;
|
in vec4 inCoord;
|
||||||
in vec3 inNormal;
|
in vec3 inNormal;
|
||||||
|
@ -21,11 +20,11 @@ smooth out vec4 ioFragColor;
|
||||||
out vec4 ioFragPosLightSpace;
|
out vec4 ioFragPosLightSpace;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ioFragPosition = (uModelMatrix * inCoord).xyz;
|
ioFragPosition = (uViewMatrix * uModelMatrix * inCoord).xyz;
|
||||||
ioFragNormal = transpose(inverse(mat3(uModelMatrix))) * inNormal;
|
ioFragNormal = transpose(inverse(mat3(uModelMatrix))) * inNormal;
|
||||||
ioFragTexCoords = inUV;
|
ioFragTexCoords = inUV;
|
||||||
ioFragColor = inColor;
|
ioFragColor = inColor;
|
||||||
ioFragPosLightSpace = uLightSpaceMatrix * vec4(ioFragPosition, 1.0);
|
ioFragPosLightSpace = uLightSpaceMatrix * uModelMatrix * inCoord;
|
||||||
|
|
||||||
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * inCoord;
|
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * inCoord;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
in vec4 inCoord;
|
in vec4 inCoord;
|
||||||
in vec2 inUV;
|
in vec2 inUV;
|
||||||
|
|
||||||
out vec2 ioUV;
|
out vec2 ioFragTexCoords;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ioUV = inUV;
|
ioFragTexCoords = inUV;
|
||||||
gl_Position = inCoord;
|
gl_Position = inCoord;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,5 +78,8 @@ inline void gLog (const char* format, ...) {
|
||||||
fprintf(gLogFile, "%s\n", buffer);
|
fprintf(gLogFile, "%s\n", buffer);
|
||||||
|
|
||||||
fflush(gLogFile);
|
fflush(gLogFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float gRandomFloat() {
|
||||||
|
return (static_cast<float>(rand()) / static_cast<float>(RAND_MAX));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ float moving_factor = 1.0f;
|
||||||
struct RendererSettings {
|
struct RendererSettings {
|
||||||
bool DrawDepth = false;
|
bool DrawDepth = false;
|
||||||
bool DrawLightDepth = false;
|
bool DrawLightDepth = false;
|
||||||
|
bool DrawSSAO = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static RendererSettings sRendererSettings;
|
static RendererSettings sRendererSettings;
|
||||||
|
@ -87,8 +88,9 @@ static void module_serialize (
|
||||||
Serializer* serializer) {
|
Serializer* serializer) {
|
||||||
SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth);
|
SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth);
|
||||||
SerializeBool(*serializer, "protot.RenderModule.DrawLightDepth", sRendererSettings.DrawLightDepth);
|
SerializeBool(*serializer, "protot.RenderModule.DrawLightDepth", sRendererSettings.DrawLightDepth);
|
||||||
SerializeBool(*serializer, "protot.RenderModule.mIsSSAOEnabled", gRenderer->mIsSSAOEnabled);
|
SerializeBool(*serializer, "protot.RenderModule.DrawSSAO", sRendererSettings.DrawSSAO);
|
||||||
|
|
||||||
|
SerializeBool(*serializer, "protot.RenderModule.mIsSSAOEnabled", gRenderer->mIsSSAOEnabled);
|
||||||
SerializeBool(*serializer, "protot.RenderModule.Camera.mIsOrthographic", gRenderer->mCamera.mIsOrthographic);
|
SerializeBool(*serializer, "protot.RenderModule.Camera.mIsOrthographic", gRenderer->mCamera.mIsOrthographic);
|
||||||
SerializeFloat(*serializer, "protot.RenderModule.Camera.mFov", gRenderer->mCamera.mFov);
|
SerializeFloat(*serializer, "protot.RenderModule.Camera.mFov", gRenderer->mCamera.mFov);
|
||||||
SerializeVec3(*serializer, "protot.RenderModule.Camera.mEye", gRenderer->mCamera.mEye);
|
SerializeVec3(*serializer, "protot.RenderModule.Camera.mEye", gRenderer->mCamera.mEye);
|
||||||
|
@ -163,8 +165,6 @@ const struct module_api MODULE_API = {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Light::Initialize() {
|
void Light::Initialize() {
|
||||||
gLog("Initializing light");
|
gLog("Initializing light");
|
||||||
mShadowMapProgram = RenderProgram("data/shaders/vs_shadowmap.vert", "data/shaders/fs_shadowmap.frag");
|
mShadowMapProgram = RenderProgram("data/shaders/vs_shadowmap.vert", "data/shaders/fs_shadowmap.frag");
|
||||||
|
@ -374,6 +374,14 @@ void Renderer::Initialize(int width, int height) {
|
||||||
mRenderQuadProgramDepth.RegisterFileModification();
|
mRenderQuadProgramDepth.RegisterFileModification();
|
||||||
assert(load_result);
|
assert(load_result);
|
||||||
|
|
||||||
|
// Program for SSAO
|
||||||
|
mSSAOProgram = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_ssao.glsl");
|
||||||
|
load_result = mSSAOProgram.Load();
|
||||||
|
mSSAOProgram.RegisterFileModification();
|
||||||
|
assert(load_result);
|
||||||
|
|
||||||
|
InitializeSSAOKernelAndNoise();
|
||||||
|
|
||||||
// Render Target
|
// Render Target
|
||||||
gLog("Initializing main render target size: %d,%d", width, height);
|
gLog("Initializing main render target size: %d,%d", width, height);
|
||||||
int render_target_flags = RenderTarget::EnableColor
|
int render_target_flags = RenderTarget::EnableColor
|
||||||
|
@ -392,6 +400,9 @@ void Renderer::Initialize(int width, int height) {
|
||||||
mRenderTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth;
|
mRenderTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth;
|
||||||
mRenderTarget.mLinearizeDepthProgram.RegisterFileModification();
|
mRenderTarget.mLinearizeDepthProgram.RegisterFileModification();
|
||||||
|
|
||||||
|
// SSAO Target
|
||||||
|
mSSAOTarget.Initialize(width, height, RenderTarget::EnableColor);
|
||||||
|
|
||||||
// Light
|
// Light
|
||||||
mLight.Initialize();
|
mLight.Initialize();
|
||||||
mLight.mShadowMapTarget.mVertexArray = &gVertexArray;
|
mLight.mShadowMapTarget.mVertexArray = &gVertexArray;
|
||||||
|
@ -406,6 +417,9 @@ void Renderer::Initialize(int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shutdown() {
|
void Renderer::Shutdown() {
|
||||||
|
if (mSSAONoiseTexture != -1) {
|
||||||
|
glDeleteTextures(1, &mSSAONoiseTexture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -428,6 +442,9 @@ void Renderer::RenderGl() {
|
||||||
|| mSceneAreaHeight != mRenderTarget.mHeight
|
|| mSceneAreaHeight != mRenderTarget.mHeight
|
||||||
|| mRenderTarget.mFlags != required_render_flags ) {
|
|| mRenderTarget.mFlags != required_render_flags ) {
|
||||||
mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, required_render_flags);
|
mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, required_render_flags);
|
||||||
|
if (mIsSSAOEnabled) {
|
||||||
|
mSSAOTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCamera.mWidth != mSceneAreaWidth
|
if (mCamera.mWidth != mSceneAreaWidth
|
||||||
|
@ -522,6 +539,46 @@ void Renderer::RenderGl() {
|
||||||
if (mSettings->DrawDepth) {
|
if (mSettings->DrawDepth) {
|
||||||
mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic);
|
mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mIsSSAOEnabled) {
|
||||||
|
mSSAOTarget.Bind();
|
||||||
|
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
|
||||||
|
GLenum draw_attachment_0[] = {GL_COLOR_ATTACHMENT0 };
|
||||||
|
glDrawBuffers(1, draw_attachment_0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// Positions
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mPositionTexture);
|
||||||
|
|
||||||
|
// Normals
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture);
|
||||||
|
|
||||||
|
// TODO: noise texture
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mSSAONoiseTexture);
|
||||||
|
|
||||||
|
glUseProgram(mSSAOProgram.mProgramId);
|
||||||
|
|
||||||
|
mSSAOProgram.SetInt("uPositions", 0);
|
||||||
|
mSSAOProgram.SetInt("uNormals", 1);
|
||||||
|
mSSAOProgram.SetInt("uNoise", 2);
|
||||||
|
|
||||||
|
mSSAOProgram.SetFloat("uRadius", mSSAORadius);
|
||||||
|
mSSAOProgram.SetFloat("uBias", mSSAOBias);
|
||||||
|
mSSAOProgram.SetInt("uSampleCount", mSSAOKernel.size());
|
||||||
|
mSSAOProgram.SetMat44("uProjection", mCamera.mProjectionMatrix);
|
||||||
|
|
||||||
|
mSSAOProgram.SetVec3Array("uSamples", mSSAOKernel.size(), &mSSAOKernel[0][0]);
|
||||||
|
// for (int i = 0; i < mSSAOKernel.size(); ++i) {
|
||||||
|
// mSSAOProgram.SetVec3(std::string("uSamples[" + std::to_string(i) + "]").c_str(), mSSAOKernel[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
gVertexArray.Bind();
|
||||||
|
gScreenQuad.Draw(GL_TRIANGLES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
|
void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
|
||||||
|
@ -593,10 +650,33 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
|
||||||
|
|
||||||
void Renderer::DrawGui() {
|
void Renderer::DrawGui() {
|
||||||
if (ImGui::BeginDock("Scene")) {
|
if (ImGui::BeginDock("Scene")) {
|
||||||
ImGui::Checkbox("Draw Depth", &mSettings->DrawDepth);
|
static int e = 0;
|
||||||
|
if (mSettings->DrawDepth) {
|
||||||
|
e = 1;
|
||||||
|
} else if (mSettings->DrawSSAO) {
|
||||||
|
e = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::RadioButton("Default", &e, 0); ImGui::SameLine();
|
||||||
|
ImGui::RadioButton("Depth", &e, 1); ImGui::SameLine();
|
||||||
|
ImGui::RadioButton("SSAO", &e, 2);
|
||||||
|
|
||||||
|
switch (e) {
|
||||||
|
case 0: mSettings->DrawDepth = 0;
|
||||||
|
mSettings->DrawSSAO = 0;
|
||||||
|
break;
|
||||||
|
case 1: mSettings->DrawDepth = 1;
|
||||||
|
mSettings->DrawSSAO = 0;
|
||||||
|
break;
|
||||||
|
case 2: mSettings->DrawDepth = 0;
|
||||||
|
mSettings->DrawSSAO = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (mSettings->DrawDepth) {
|
if (mSettings->DrawDepth) {
|
||||||
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mLinearizedDepthTexture;
|
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mLinearizedDepthTexture;
|
||||||
|
} else if (mSettings->DrawSSAO) {
|
||||||
|
mRenderTextureRef.mTextureIdPtr = &mSSAOTarget.mColorTexture;
|
||||||
} else {
|
} else {
|
||||||
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mColorTexture;
|
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mColorTexture;
|
||||||
}
|
}
|
||||||
|
@ -628,6 +708,14 @@ void Renderer::DrawGui() {
|
||||||
ImGui::Checkbox("Enable SSAO", &mIsSSAOEnabled);
|
ImGui::Checkbox("Enable SSAO", &mIsSSAOEnabled);
|
||||||
|
|
||||||
if (mIsSSAOEnabled) {
|
if (mIsSSAOEnabled) {
|
||||||
|
ImGui::SliderFloat("Radius", &mSSAORadius, 0.0f, 1.0f);
|
||||||
|
ImGui::SliderFloat("Bias", &mSSAOBias, 0.0f, 0.1f);
|
||||||
|
ImGui::SliderInt("Samples", &mSSAOKernelSize, 1, 64);
|
||||||
|
|
||||||
|
if (mSSAOKernelSize != mSSAOKernel.size()) {
|
||||||
|
InitializeSSAOKernelAndNoise();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Text("Position Texture");
|
ImGui::Text("Position Texture");
|
||||||
mPositionTextureRef.mTextureIdPtr = &mRenderTarget.mPositionTexture;
|
mPositionTextureRef.mTextureIdPtr = &mRenderTarget.mPositionTexture;
|
||||||
mPositionTextureRef.magic = (GLuint)0xbadface;
|
mPositionTextureRef.magic = (GLuint)0xbadface;
|
||||||
|
@ -657,3 +745,43 @@ void Renderer::DrawGui() {
|
||||||
ImGui::EndDock();
|
ImGui::EndDock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::InitializeSSAOKernelAndNoise() {
|
||||||
|
mSSAOKernel.clear();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mSSAOKernelSize; ++i) {
|
||||||
|
Vector3f sample(
|
||||||
|
gRandomFloat() * 2.0f - 1.0f,
|
||||||
|
gRandomFloat() * 2.0f - 1.0f,
|
||||||
|
gRandomFloat()
|
||||||
|
);
|
||||||
|
sample.normalize();
|
||||||
|
|
||||||
|
// Have a higher distribution of samples close to the origin
|
||||||
|
float scale = (float) i / mSSAOKernelSize;
|
||||||
|
scale = 0.1 + scale * scale * (1.0f - 0.1);
|
||||||
|
|
||||||
|
mSSAOKernel.push_back(sample * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vector3f> noise_vectors;
|
||||||
|
for (unsigned int i = 0; i < 16; ++i) {
|
||||||
|
Vector3f noise(
|
||||||
|
gRandomFloat() * 2.0f - 1.0f,
|
||||||
|
gRandomFloat() * 2.0f - 1.0f,
|
||||||
|
0.0f);
|
||||||
|
noise_vectors.push_back(noise);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSSAONoiseTexture != -1) {
|
||||||
|
glDeleteTextures(1, &mSSAONoiseTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures(1, &mSSAONoiseTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mSSAONoiseTexture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 4, 4, 0, GL_RGB, GL_FLOAT, &noise_vectors[0][0]);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,12 +71,21 @@ struct Renderer {
|
||||||
RenderProgram mDefaultProgram;
|
RenderProgram mDefaultProgram;
|
||||||
RenderProgram mRenderQuadProgramColor;
|
RenderProgram mRenderQuadProgramColor;
|
||||||
RenderProgram mRenderQuadProgramDepth;
|
RenderProgram mRenderQuadProgramDepth;
|
||||||
|
RenderProgram mSSAOProgram;
|
||||||
|
|
||||||
RenderTarget mRenderTarget;
|
RenderTarget mRenderTarget;
|
||||||
|
RenderTarget mSSAOTarget;
|
||||||
|
|
||||||
GLTextureRef mRenderTextureRef = { (int)0xbadface };
|
GLTextureRef mRenderTextureRef = { (int)0xbadface };
|
||||||
GLTextureRef mPositionTextureRef = { (int)0xbadface };
|
GLTextureRef mPositionTextureRef = { (int)0xbadface };
|
||||||
GLTextureRef mNormalTextureRef = { (int)0xbadface };
|
GLTextureRef mNormalTextureRef = { (int)0xbadface };
|
||||||
|
|
||||||
|
float mSSAORadius = 0.5f;
|
||||||
|
float mSSAOBias = 0.025f;
|
||||||
|
int mSSAOKernelSize = 64;
|
||||||
|
std::vector<Vector3f> mSSAOKernel;
|
||||||
|
GLuint mSSAONoiseTexture = -1;
|
||||||
|
|
||||||
Renderer() :
|
Renderer() :
|
||||||
mInitialized(false),
|
mInitialized(false),
|
||||||
mWidth (0),
|
mWidth (0),
|
||||||
|
@ -88,4 +97,6 @@ struct Renderer {
|
||||||
void RenderGl();
|
void RenderGl();
|
||||||
void RenderScene(RenderProgram &program, const Camera& camera);
|
void RenderScene(RenderProgram &program, const Camera& camera);
|
||||||
void DrawGui();
|
void DrawGui();
|
||||||
|
|
||||||
|
void InitializeSSAOKernelAndNoise();
|
||||||
};
|
};
|
||||||
|
|
|
@ -218,6 +218,11 @@ struct RenderProgram : AFileModificationListener {
|
||||||
glUniform3fv(location, 1, vec.data());
|
glUniform3fv(location, 1, vec.data());
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
GLint SetVec3Array(const char* name, int count, const float* array) {
|
||||||
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
|
glUniform3fv(location, count, array);
|
||||||
|
return location;
|
||||||
|
}
|
||||||
GLint SetVec4(const char* name, const Vector3f& vec, float w = 1.0f) {
|
GLint SetVec4(const char* name, const Vector3f& vec, float w = 1.0f) {
|
||||||
GLint location = glGetUniformLocation(mProgramId, name);
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
glUniform4f(location, vec[0], vec[1], vec[2], w);
|
glUniform4f(location, vec[0], vec[1], vec[2], w);
|
||||||
|
|
Loading…
Reference in New Issue