From 08548e1ef0b0a66866183c5e49575bb0f6263113 Mon Sep 17 00:00:00 2001 From: yunfeibai Date: Sun, 11 Feb 2018 13:50:45 -0800 Subject: [PATCH] Add example for projective texture. --- data/cube.mtl | 2 +- .../CommonInterfaces/CommonRenderInterface.h | 1 + .../OpenGLWindow/GLInstancingRenderer.cpp | 107 +++++++++++++++++- .../Shaders/useShadowMapInstancingPS.glsl | 8 +- .../Shaders/useShadowMapInstancingPS.h | 8 +- .../Shaders/useShadowMapInstancingVS.glsl | 4 +- .../Shaders/useShadowMapInstancingVS.h | 4 +- .../pybullet/examples/projective_texture.py | 49 ++++++++ 8 files changed, 163 insertions(+), 20 deletions(-) create mode 100644 examples/pybullet/examples/projective_texture.py diff --git a/data/cube.mtl b/data/cube.mtl index ffce2975d..d9c0d88cd 100644 --- a/data/cube.mtl +++ b/data/cube.mtl @@ -10,7 +10,7 @@ newmtl cube Ks 0.0000 0.0000 0.0000 Ke 0.0000 0.0000 0.0000 map_Ka cube.tga - map_Kd cube.png + map_Kd checker_blue.png diff --git a/examples/CommonInterfaces/CommonRenderInterface.h b/examples/CommonInterfaces/CommonRenderInterface.h index d8c9e37ce..bc828b1aa 100644 --- a/examples/CommonInterfaces/CommonRenderInterface.h +++ b/examples/CommonInterfaces/CommonRenderInterface.h @@ -16,6 +16,7 @@ enum B3_CREATE_SHADOWMAP_RENDERMODE, B3_USE_SHADOWMAP_RENDERMODE, B3_USE_SHADOWMAP_RENDERMODE_REFLECTION, + B3_USE_PROJECTIVE_TEXTURE_RENDERMODE, }; diff --git a/examples/OpenGLWindow/GLInstancingRenderer.cpp b/examples/OpenGLWindow/GLInstancingRenderer.cpp index c7cac6709..24a10f4b7 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.cpp +++ b/examples/OpenGLWindow/GLInstancingRenderer.cpp @@ -16,7 +16,9 @@ subject to the following restrictions: ///todo: make this configurable in the gui -bool useShadowMap = true;// true;//false;//true; +bool useShadowMap = false;// true;//false;//true; +float projectiveTextureViewSize = 10; +bool useProjectiveTexture = true; int shadowMapWidth= 4096; int shadowMapHeight= 4096; float shadowMapWorldSize=10; @@ -224,6 +226,9 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData b3Vector3 m_lightPos; b3Vector3 m_lightSpecularIntensity; + + b3Vector3 m_projectorPos; + b3Vector3 m_projectorDir; GLuint m_defaultTexturehandle; b3AlignedObjectArray m_textureHandles; @@ -1530,7 +1535,13 @@ void GLInstancingRenderer::renderScene() //renderSceneInternal(B3_USE_SHADOWMAP_RENDERMODE_REFLECTION); renderSceneInternal(B3_USE_SHADOWMAP_RENDERMODE); - } else + } + else if (useProjectiveTexture) + { + renderSceneInternal(B3_CREATE_SHADOWMAP_RENDERMODE); + renderSceneInternal(B3_USE_PROJECTIVE_TEXTURE_RENDERMODE); + } + else { renderSceneInternal(); } @@ -1970,11 +1981,16 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) reflectionPass = true; renderMode = B3_USE_SHADOWMAP_RENDERMODE; } - + if (!useShadowMap) { renderMode = B3_DEFAULT_RENDERMODE; } + + if (orgRenderMode==B3_USE_PROJECTIVE_TEXTURE_RENDERMODE) + { + renderMode = B3_USE_PROJECTIVE_TEXTURE_RENDERMODE; + } // glEnable(GL_DEPTH_TEST); @@ -2003,6 +2019,10 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) float depthProjectionMatrix[4][4]; GLfloat depthModelViewMatrix[4][4]; //GLfloat depthModelViewMatrix2[4][4]; + + // For projective texture mapping + float textureProjectionMatrix[4][4]; + GLfloat textureModelViewMatrix[4][4]; // Compute the MVP matrix from the light's point of view if (renderMode==B3_CREATE_SHADOWMAP_RENDERMODE) @@ -2113,6 +2133,18 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) GLfloat depthBiasMVP[4][4]; b3Matrix4x4Mul(biasMatrix,depthMVP,depthBiasMVP); + // Compute projection matrix for texture projector + float textureViewMatrix[4][4]; + b3Vector3 projectorDir = m_data->m_projectorDir.normalize(); + float projectorDist = 3.0; + b3Vector3 projectorUp = b3MakeVector3(0,0,1.0); + b3CreateLookAt(m_data->m_projectorPos, m_data->m_projectorDir*projectorDist, projectorUp, &textureViewMatrix[0][0]); + GLfloat textureModelMatrix[4][4]; + b3CreateDiagonalMatrix(1.f, textureModelMatrix); + b3Matrix4x4Mul(textureViewMatrix, textureModelMatrix, textureModelViewMatrix); + b3CreateOrtho(-projectiveTextureViewSize,projectiveTextureViewSize,-projectiveTextureViewSize,projectiveTextureViewSize,1,300,textureProjectionMatrix); + GLfloat textureMVP[4][4]; + b3Matrix4x4Mul(textureProjectionMatrix, textureModelViewMatrix, textureMVP); //float m_frustumZNear=0.1; //float m_frustumZFar=100.f; @@ -2459,6 +2491,75 @@ b3Assert(glGetError() ==GL_NO_ERROR); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,0); + break; + } + case B3_USE_PROJECTIVE_TEXTURE_RENDERMODE: + { + if ( gfxObj->m_flags&eGfxTransparency) + { + glDepthMask(false); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glUseProgram(useShadowMapInstancingShader); + glUniformMatrix4fv(useShadow_ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]); + glUniform3f(useShadow_lightSpecularIntensity, m_data->m_lightSpecularIntensity[0],m_data->m_lightSpecularIntensity[1],m_data->m_lightSpecularIntensity[2]); + glUniform3f(useShadow_materialSpecularColor, gfxObj->m_materialSpecularColor[0],gfxObj->m_materialSpecularColor[1],gfxObj->m_materialSpecularColor[2]); + + float MVP[16]; + if (reflectionPass) + { + float tmp[16]; + float reflectionMatrix[16] = {1,0,0,0, + 0,1,0,0, + 0,0,-1,0, + 0,0,0,1}; + glCullFace(GL_FRONT); + b3Matrix4x4Mul16(m_data->m_viewMatrix,reflectionMatrix,tmp); + b3Matrix4x4Mul16(m_data->m_projectionMatrix,tmp,MVP); + } else + { + b3Matrix4x4Mul16(m_data->m_projectionMatrix,m_data->m_viewMatrix,MVP); + glCullFace(GL_BACK); + } + + glUniformMatrix4fv(useShadow_MVP, 1, false, &MVP[0]); + glUniform3f(useShadow_lightPosIn,m_data->m_lightPos[0],m_data->m_lightPos[1],m_data->m_lightPos[2]); + float camPos[3]; + m_data->m_activeCamera->getCameraPosition(camPos); + glUniform3f(useShadow_cameraPositionIn,camPos[0],camPos[1],camPos[2]); + glUniform1f(useShadow_materialShininessIn,gfxObj->m_materialShinyNess); + + glUniformMatrix4fv(useShadow_DepthBiasModelViewMatrix, 1, false, &textureMVP[0][0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_data->m_shadowTexture); + glUniform1i(useShadow_shadowMap,1); + + //sort transparent objects + if ( gfxObj->m_flags&eGfxTransparency) + { + int instanceId = transparentInstances[i].m_instanceId; + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)((instanceId)*4*sizeof(float)+m_data->m_maxShapeCapacityInBytes)); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)((instanceId)*4*sizeof(float)+m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE)); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)((instanceId)*4*sizeof(float)+m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE)); + glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)((instanceId)*3*sizeof(float)+m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE)); + glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0); + } else + { + glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances); + } + + if ( gfxObj->m_flags&eGfxTransparency) + { + glDisable (GL_BLEND); + glDepthMask(true); + } + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,0); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0); break; diff --git a/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl b/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl index 809494902..4e11e3762 100644 --- a/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl +++ b/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl @@ -12,11 +12,9 @@ in Vert } vert; uniform sampler2D Diffuse; -uniform sampler2DShadow shadowMap; uniform mat4 ViewMatrixInverse; in vec3 lightPos,cameraPosition, normal,ambient; -in vec4 ShadowCoord; in vec4 vertexPos; in float materialShininess; in vec3 lightSpecularIntensity; @@ -28,7 +26,7 @@ out vec4 color; void main(void) { - vec4 texel = fragment.color*texture(Diffuse,vert.texcoord); + vec4 texel = fragment.color*texture(Diffuse,vert.texcoord.xy); vec3 ct,cf; float intensity,at,af; if (fragment.color.w==0) @@ -65,9 +63,7 @@ void main(void) } - float visibility = texture(shadowMap, vec3(ShadowCoord.xy,(ShadowCoord.z)/ShadowCoord.w)); - if (intensity<0.5) - visibility = 0; + float visibility = 1.0; intensity = 0.7*intensity + 0.3*intensity*visibility; diff --git a/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.h b/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.h index e34883d85..43407e156 100644 --- a/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.h +++ b/examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.h @@ -11,10 +11,8 @@ static const char* useShadowMapInstancingFragmentShader= \ " vec2 texcoord;\n" "} vert;\n" "uniform sampler2D Diffuse;\n" -"uniform sampler2DShadow shadowMap;\n" "uniform mat4 ViewMatrixInverse;\n" "in vec3 lightPos,cameraPosition, normal,ambient;\n" -"in vec4 ShadowCoord;\n" "in vec4 vertexPos;\n" "in float materialShininess;\n" "in vec3 lightSpecularIntensity;\n" @@ -22,7 +20,7 @@ static const char* useShadowMapInstancingFragmentShader= \ "out vec4 color;\n" "void main(void)\n" "{\n" -" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);\n" +" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord.xy);\n" " vec3 ct,cf;\n" " float intensity,at,af;\n" " if (fragment.color.w==0)\n" @@ -58,9 +56,7 @@ static const char* useShadowMapInstancingFragmentShader= \ " \n" " }\n" " \n" -" float visibility = texture(shadowMap, vec3(ShadowCoord.xy,(ShadowCoord.z)/ShadowCoord.w));\n" -" if (intensity<0.5)\n" -" visibility = 0;\n" +" float visibility = 1.0;\n" " intensity = 0.7*intensity + 0.3*intensity*visibility;\n" " \n" " cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient+specularReflection*visibility;\n" diff --git a/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl b/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl index 83ed4839f..01d73c2d4 100644 --- a/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl +++ b/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl @@ -91,9 +91,9 @@ void main(void) vec4 vertexLoc = MVP* vec4((instance_position+localcoord).xyz,1); gl_Position = vertexLoc; - ShadowCoord = DepthBiasModelViewProjectionMatrix * vec4((instance_position+localcoord).xyz,1); fragment.color = instance_color; - vert.texcoord = uvcoords; + vec4 projcoords = DepthBiasModelViewProjectionMatrix * vec4((instance_position+localcoord).xyz,1); + vert.texcoord = projcoords.xy; } diff --git a/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.h b/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.h index 20c188edb..672a83ae5 100644 --- a/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.h +++ b/examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.h @@ -79,8 +79,8 @@ static const char* useShadowMapInstancingVertexShader= \ " \n" " vec4 vertexLoc = MVP* vec4((instance_position+localcoord).xyz,1);\n" " gl_Position = vertexLoc;\n" -" ShadowCoord = DepthBiasModelViewProjectionMatrix * vec4((instance_position+localcoord).xyz,1);\n" " fragment.color = instance_color;\n" -" vert.texcoord = uvcoords;\n" +" vec4 projcoords = DepthBiasModelViewProjectionMatrix * vec4((instance_position+localcoord).xyz,1);\n" +" vert.texcoord = projcoords.xy;\n" "}\n" ; diff --git a/examples/pybullet/examples/projective_texture.py b/examples/pybullet/examples/projective_texture.py new file mode 100644 index 000000000..b2d11f425 --- /dev/null +++ b/examples/pybullet/examples/projective_texture.py @@ -0,0 +1,49 @@ +import pybullet as p +from time import sleep +from PIL import Image +import matplotlib.pyplot as plt +import numpy as np + +physicsClient = p.connect(p.GUI) + +p.setGravity(0,0,-10) +planeId = p.loadURDF("plane.urdf") +cubeStartPos = [0,0,1] +cubeStartOrientation = p.getQuaternionFromEuler([0,0,0]) +boxId = p.loadURDF("cube.urdf",cubeStartPos, cubeStartOrientation) +cubePos, cubeOrn = p.getBasePositionAndOrientation(boxId) +textureId = p.loadTexture("kcam_vga_scaled_direct.png") +p.changeVisualShape(objectUniqueId=0, linkIndex=-1, textureUniqueId=textureId) +p.changeVisualShape(objectUniqueId=1, linkIndex=-1, textureUniqueId=textureId) + +#p.resetDebugVisualizerCamera(cameraDistance=3, cameraYaw=30, cameraPitch=52, cameraTargetPosition=[10,0,0]) +fov = 70 +pixelWidth = 640 +pixelHeight = 512 +aspect = pixelWidth / pixelHeight; +nearPlane = 0.01 +farPlane = 100 +projectionMatrix = p.computeProjectionMatrixFOV(fov, aspect, nearPlane, farPlane); +viewMatrixLeft = p.computeViewMatrix(cameraEyePosition=[0.045, 3.0, 3.0], cameraTargetPosition=[0.045,0,0], cameraUpVector=[0,0,1.0]) +viewMatrixRight = p.computeViewMatrix(cameraEyePosition=[-0.045, 3.0, 3.0], cameraTargetPosition=[-0.045,0,0], cameraUpVector=[0,0,1.0]) +leftImage = p.getCameraImage(width=640,height=512,viewMatrix=viewMatrixLeft,projectionMatrix=projectionMatrix,renderer=p.ER_BULLET_HARDWARE_OPENGL) +rightImage = p.getCameraImage(width=640,height=512,viewMatrix=viewMatrixRight,projectionMatrix=projectionMatrix,renderer=p.ER_BULLET_HARDWARE_OPENGL) + +left_img = np.reshape(np.asarray(leftImage[2], dtype=np.float32), (512, 640, 4)) +left_img /= 255 +plt.imsave("left_image_new.png", left_img) +right_img = np.reshape(np.asarray(rightImage[2], dtype=np.float32), (512, 640, 4)) +right_img /= 255 +plt.imsave("right_image_new.png", right_img) + +useRealTimeSimulation = 1 + +if (useRealTimeSimulation): + p.setRealTimeSimulation(1) + +while 1: + if (useRealTimeSimulation): + p.setGravity(0,0,-10) + sleep(0.01) # Time in seconds. + else: + p.stepSimulation()