diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /KaplaDemo/samples/sampleViewer3/HDRHelper.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/HDRHelper.cpp')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/HDRHelper.cpp | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/HDRHelper.cpp b/KaplaDemo/samples/sampleViewer3/HDRHelper.cpp new file mode 100644 index 00000000..6f750986 --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/HDRHelper.cpp @@ -0,0 +1,356 @@ +#include "HDRHelper.h" +#include "foundation/PxMat44.h" + +namespace +{ +PxMat44 PerspectiveProjectionMatrix(float fovy,float x,float y,float n,float f) +{ + float PPM[16]; + + float coty = 1.0f / tan(fovy * physx::PxPi / 360.0f); + float aspect = x / (y > 0.0f ? y : 1.0f); + + PPM[0] = coty / aspect; + PPM[1] = 0.0f; + PPM[2] = 0.0f; + PPM[3] = 0.0f; + + PPM[4] = 0.0f; + PPM[5] = coty; + PPM[6] = 0.0f; + PPM[7] = 0.0f; + + PPM[8] = 0.0f; + PPM[9] = 0.0f; + PPM[10] = (n + f) / (n - f); + PPM[11] = -1.0f; + + PPM[12] = 0.0f; + PPM[13] = 0.0f; + PPM[14] = 2.0f * n * f / (n - f); + PPM[15] = 0.0f; + + return PxMat44(PPM); +} +} + +const char *HDRToneMappingVS = STRINGIFY( + void main(void) + { + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex * 2.0 - 1.0; + } +); + +const char *HDRBlurHFS = STRINGIFY( + uniform sampler2D colorTex; + uniform float sx; + + void main (void) + { + vec3 bloom = vec3(0.0, 0.0, 0.0); + const float hdrScale = 1.5; + const int kernelSize = 10; + const float invScale = 1.0 / (hdrScale * float(kernelSize)); + + for (int x = -kernelSize; x <= kernelSize; x++) + { + float s = gl_TexCoord[0].s + x * sx; + float t = gl_TexCoord[0].t; + vec3 color = texture2D(colorTex, vec2(s,t)).rgb; + float luminance = dot(color, vec3(0.2125, 0.7154, 0.0721)); + if (luminance > 1.0) + { + bloom += color * ((kernelSize+1) - abs(float(x))); + } + } + + gl_FragColor = vec4(bloom * invScale, 1.0); + } +); + +const char *HDRBlurVFS = STRINGIFY( + uniform sampler2D colorTex; + uniform sampler2D blurTex; + uniform float sy; + + void main (void) + { + const float hdrScale = 1.5; + const int kernelSize = 10; + const float invScale = 1.0 / (hdrScale * float(kernelSize) * 100.0); + + vec3 colorP = texture2D(colorTex, gl_TexCoord[0]).rgb; + vec3 bloom = vec3(0.0, 0.0, 0.0); + + for (int y = -kernelSize; y <= kernelSize; y++) + { + float s = gl_TexCoord[0].s; + float t = gl_TexCoord[0].t + y * sy; + vec3 color = texture2D(blurTex, vec2(s,t)).rgb; + float luminance = dot(color, vec3(0.2125, 0.7154, 0.0721)); + if (luminance > 1.0) + { + bloom += color * ((kernelSize+1) - abs(float(y))); + } + } + + vec3 hdrColor = invScale * bloom + colorP; + + vec3 toneMappedColor = 2.0 * hdrColor / (hdrColor + vec3(1.0)); + gl_FragColor = vec4(toneMappedColor, 1.0); + } +); + +const char *HDRDepthOfFieldFS = STRINGIFY( + uniform sampler2D colorTex; + uniform sampler2D depthTex; + uniform float sx; + uniform float sy; + + void main(void) + { + const float depthEnd = 0.993; + const float depthSize = 0.01; + + vec3 colorP = texture2D(colorTex, gl_TexCoord[0]).rgb; + float depth = texture2D(depthTex, gl_TexCoord[0].st).r; + + if ((depth - depthEnd) < depthSize) + { + const int depthKernelSize = 5; + vec3 colorSum = vec3(0.0); + float cnt = 0.0; + for (int x = -depthKernelSize; x <= depthKernelSize; x++) + for (int y = -depthKernelSize; y <= depthKernelSize; y++) + { + float s = gl_TexCoord[0].s + x * sy; + float t = gl_TexCoord[0].t + y * sy; + float scalex = ((depthKernelSize + 1) - abs(float(x))) / depthKernelSize; + float scaley = ((depthKernelSize + 1) - abs(float(y))) / depthKernelSize; + float scale = scalex * scaley; + vec3 color = texture2D(colorTex, vec2(s, t)).rgb; + colorSum += scale * color; + cnt += scale; + } + + colorSum /= cnt; + float depthScale = pow(max(0.0f, min(1.0, (abs(depth - depthEnd)) / depthSize)), 1.5); + colorP = depthScale * colorSum + (1.0 - depthScale) * colorP; + } + + gl_FragColor = vec4(colorP, 1.0); + } +); + +HDRHelper::HDRHelper(float fov,float padding,float zNear,float zFar, const char* resourcePath, float scale) : fov(fov),padding(padding),zNear(zNear),zFar(zFar), scale(scale) +{ + mShaderBloomH.loadShaderCode(HDRToneMappingVS, HDRBlurHFS); + mShaderBloomV.loadShaderCode(HDRToneMappingVS, HDRBlurVFS); + mShaderDOF.loadShaderCode(HDRToneMappingVS, HDRDepthOfFieldFS); + + glGenTextures(1,&mHDRColorTex); + glGenTextures(1,&mHDRDepthTex); + glGenTextures(1,&mHDRBlurTex); + glGenTextures(1,&mHDRBloomTex); + + glGenFramebuffers(1,&mHDRFbo); + glBindFramebuffer(GL_FRAMEBUFFER, mHDRFbo); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRColorTex, 0); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glReadBuffer(GL_COLOR_ATTACHMENT0); + + glGenFramebuffers(1,&mHDRBlurFbo); + glBindFramebuffer(GL_FRAMEBUFFER, mHDRBlurFbo); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRBlurTex, 0); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glReadBuffer(GL_COLOR_ATTACHMENT0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + //printf("Frame buffer status %d\n\n\n", + // (status == GL_FRAMEBUFFER_COMPLETE) ? 1 : 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void HDRHelper::Resize(int w,int h) { + + realWidth = w; + realHeight = h; + Width = w*scale; + Height = h*scale; + + fovPad = 2.0f*atan(tan(fov*0.5f*physx::PxPi/180.0f)*(1.0f+padding))*180.0f/physx::PxPi; + + glViewport(0,0,w,h); + + // allocate HDR color buffer + glBindFramebuffer(GL_FRAMEBUFFER, mHDRFbo); + + glBindTexture(GL_TEXTURE_2D,mHDRColorTex); + 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_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F,w,h,0,GL_RGBA,GL_FLOAT,NULL); + + glBindTexture(GL_TEXTURE_2D,mHDRDepthTex); + 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_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT24,w,h,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL); + + // allocate HDR color buffer for blur operations + glBindFramebuffer(GL_FRAMEBUFFER, mHDRBlurFbo); + + glBindTexture(GL_TEXTURE_2D,mHDRBlurTex); + 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_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F,w,h,0,GL_RGBA,GL_FLOAT,NULL); + + glBindTexture(GL_TEXTURE_2D,mHDRBloomTex); + 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_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F,w,h,0,GL_RGBA,GL_FLOAT,NULL); + + // set program values + glUseProgram(mShaderBloomH); + glUniform1f(glGetUniformLocation(mShaderBloomH,"sx"),1.0f / (float)w); + + glUseProgram(mShaderBloomV); + glUniform1f(glGetUniformLocation(mShaderBloomV,"sy"),1.0f / (float)h); + + glUseProgram(mShaderDOF); + glUniform1f(glGetUniformLocation(mShaderDOF,"sx"),1.0f / (float)w); + glUniform1f(glGetUniformLocation(mShaderDOF,"sy"),1.0f / (float)h); + + glUseProgram(0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + +} + +void HDRHelper::Destroy() { + + mShaderBloomH.deleteShaders(); + mShaderBloomV.deleteShaders(); + + glDeleteTextures(1,&mHDRColorTex); + glDeleteTextures(1,&mHDRDepthTex); + glDeleteTextures(1,&mHDRBlurTex); + glDeleteTextures(1,&mHDRBloomTex); + + glDeleteFramebuffers(1,&mHDRFbo); + glDeleteFramebuffers(1,&mHDRBlurFbo); +} + +void HDRHelper::beginHDR(bool useOwnFbo) +{ + if (useOwnFbo) + { + glBindFramebuffer(GL_FRAMEBUFFER, mHDRFbo); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRColorTex, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,mHDRDepthTex,0); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } +} + +void HDRHelper::endHDR(bool useOwnFbo) +{ + if (useOwnFbo) + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void +drawQuads(float s = 1.0f) +{ + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f,0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex2f(s,0.0f); + glTexCoord2f(1.0f, 1.0f); glVertex2f(s,s); + glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f,s); + glEnd(); +} + +void HDRHelper::DoHDR(GLuint oldFBO, bool useDOF) { + + PxMat44 Projection = PerspectiveProjectionMatrix(fov,Width,Height,zNear,zFar); + + // render stored HDR fbo onto blur fbo, first with horizontal blur + glBindFramebuffer(GL_FRAMEBUFFER, mHDRBlurFbo); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRBlurTex,0); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0); + + glViewport(0,0,realWidth,realHeight); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(&Projection.column0.x); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mHDRColorTex); + + glUseProgram(mShaderBloomH); + glUniform1f(glGetUniformLocation(mShaderBloomH, "sx"), 1.0f / (float)realWidth); + glUniform1i(glGetUniformLocation(mShaderBloomH,"colorTex"),0); + + drawQuads(); + + glUseProgram(0); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0); + + // now apply vertical blur for the bloom + if (useDOF) + { + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRBloomTex,0); + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0); + } + else + glBindFramebuffer(GL_FRAMEBUFFER,oldFBO); + + glViewport(0,0,realWidth,realHeight); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(&Projection.column0.x); + + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,mHDRColorTex); + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,mHDRBlurTex); + + glUseProgram(mShaderBloomV); + glUniform1f(glGetUniformLocation(mShaderBloomV, "sy"), 1.0f / (float)realHeight); + glUniform1i(glGetUniformLocation(mShaderBloomV,"colorTex"),0); + glUniform1i(glGetUniformLocation(mShaderBloomV,"blurTex"),1); + + drawQuads(); + + glUseProgram(0); + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,0); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0); + + // now render the final image onto supplied fbo, apply DOF + if (!useDOF) return; + + glBindFramebuffer(GL_FRAMEBUFFER,oldFBO); + + glViewport(0,0,realWidth,realHeight); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(&Projection.column0.x); + + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,mHDRBloomTex); + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,mHDRDepthTex); + + glUseProgram(mShaderDOF); + glUniform1f(glGetUniformLocation(mShaderDOF, "sx"), 1.0f / (float)realWidth); + glUniform1f(glGetUniformLocation(mShaderDOF, "sy"), 1.0f / (float)realHeight); + glUniform1i(glGetUniformLocation(mShaderDOF,"colorTex"),0); + glUniform1i(glGetUniformLocation(mShaderDOF,"depthTex"),1); + + drawQuads(); + + glUseProgram(0); + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,0); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0); +} |