593 lines
26 KiB
C
593 lines
26 KiB
C
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield
|
||
|
* Copyright (C) 2014 Pawel Ksiezopolski
|
||
|
*
|
||
|
* This library is open source and may be redistributed and/or modified under
|
||
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||
|
* (at your option) any later version. The full license is in LICENSE file
|
||
|
* included with this distribution, and on the openscenegraph.org website.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* OpenSceneGraph Public License for more details.
|
||
|
*
|
||
|
*/
|
||
|
#ifndef GPU_CULL_SHADERS
|
||
|
#define GPU_CULL_SHADERS 1
|
||
|
|
||
|
char SHADER_STATIC_CULL_VERTEX[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"uniform mat4 osg_ViewMatrixInverse;\n"
|
||
|
"\n"
|
||
|
"layout(R32I) coherent uniform iimageBuffer indirectCommand0;\n"
|
||
|
"layout(R32I) coherent uniform iimageBuffer indirectCommand1;\n"
|
||
|
"uniform int indirectCommandSize; // = sizeof(DrawArraysIndirectCommand) / sizeof(unsigned int) = 4\n"
|
||
|
"\n"
|
||
|
"layout(R32I) coherent uniform iimageBuffer getIndirectCommand( int index )\n"
|
||
|
"{\n"
|
||
|
" if(index==0) return indirectCommand0;\n"
|
||
|
" if(index==1) return indirectCommand1;\n"
|
||
|
" return indirectCommand0;\n"
|
||
|
"}\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32F) coherent uniform imageBuffer indirectTarget0;\n"
|
||
|
"layout(RGBA32F) coherent uniform imageBuffer indirectTarget1;\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32F) coherent uniform imageBuffer getIndirectTarget( int index )\n"
|
||
|
"{\n"
|
||
|
" if(index==0) return indirectTarget0;\n"
|
||
|
" if(index==1) return indirectTarget1;\n"
|
||
|
" return indirectTarget0;\n"
|
||
|
"}\n"
|
||
|
"\n"
|
||
|
"struct InstanceLOD\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 indirectTargetParams; // x=targetID, y=indexInTarget, z=offsetInTarget, w=lodMaxQuantity\n"
|
||
|
" vec4 distances; // x=minDistance, y=minFadeDistance, z=maxFadeDistance, w=maxDistance\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"const int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8;\n"
|
||
|
"\n"
|
||
|
"struct InstanceType\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 params;\n"
|
||
|
" InstanceLOD lods[OSGGPUCULL_MAXIMUM_LOD_NUMBER];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(std140) uniform instanceTypesData\n"
|
||
|
"{\n"
|
||
|
" InstanceType instanceTypes[32];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"// StaticInstance params are stored in vertex attributes\n"
|
||
|
"layout(location = 0) in vec3 VertexPosition;\n"
|
||
|
"layout(location = 10) in vec4 M0;\n"
|
||
|
"layout(location = 11) in vec4 M1;\n"
|
||
|
"layout(location = 12) in vec4 M2;\n"
|
||
|
"layout(location = 13) in vec4 M3;\n"
|
||
|
"layout(location = 14) in vec4 ExtraParams;\n"
|
||
|
"layout(location = 15) in vec4 IdParams;\n"
|
||
|
"\n"
|
||
|
"out vec4 fColor;\n"
|
||
|
"\n"
|
||
|
"bool boundingBoxInViewFrustum( in mat4 matrix, in vec3 bbMin, in vec3 bbMax )\n"
|
||
|
"{\n"
|
||
|
" vec4 BoundingBox[8];\n"
|
||
|
" BoundingBox[0] = matrix * vec4( bbMax.x, bbMax.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[1] = matrix * vec4( bbMin.x, bbMax.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[2] = matrix * vec4( bbMax.x, bbMin.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[3] = matrix * vec4( bbMin.x, bbMin.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[4] = matrix * vec4( bbMax.x, bbMax.y, bbMin.z, 1.0);\n"
|
||
|
" BoundingBox[5] = matrix * vec4( bbMin.x, bbMax.y, bbMin.z, 1.0);\n"
|
||
|
" BoundingBox[6] = matrix * vec4( bbMax.x, bbMin.y, bbMin.z, 1.0);\n"
|
||
|
" BoundingBox[7] = matrix * vec4( bbMin.x, bbMin.y, bbMin.z, 1.0);\n"
|
||
|
"\n"
|
||
|
" int outOfBound[6] = int[6]( 0, 0, 0, 0, 0, 0 );\n"
|
||
|
" for (int i=0; i<8; i++)\n"
|
||
|
" {\n"
|
||
|
" outOfBound[0] += int( BoundingBox[i].x > BoundingBox[i].w );\n"
|
||
|
" outOfBound[1] += int( BoundingBox[i].x < -BoundingBox[i].w );\n"
|
||
|
" outOfBound[2] += int( BoundingBox[i].y > BoundingBox[i].w );\n"
|
||
|
" outOfBound[3] += int( BoundingBox[i].y < -BoundingBox[i].w );\n"
|
||
|
" outOfBound[4] += int( BoundingBox[i].z > BoundingBox[i].w );\n"
|
||
|
" outOfBound[5] += int( BoundingBox[i].z < -BoundingBox[i].w );\n"
|
||
|
" }\n"
|
||
|
" return (outOfBound[0] < 8 ) && ( outOfBound[1] < 8 ) && ( outOfBound[2] < 8 ) && ( outOfBound[3] < 8 ) && ( outOfBound[4] < 8 ) && ( outOfBound[5] < 8 );\n"
|
||
|
"}\n"
|
||
|
"\n"
|
||
|
"void main(void) \n"
|
||
|
"{\n"
|
||
|
" mat4 instanceMatrix = mat4(M0,M1,M2,M3);\n"
|
||
|
" mat4 mvpoMatrix = gl_ModelViewProjectionMatrix * instanceMatrix;\n"
|
||
|
"\n"
|
||
|
" // gl_Position is created only for debugging purposes\n"
|
||
|
" gl_Position = mvpoMatrix * vec4(0.0,0.0,0.0,1.0);\n"
|
||
|
"\n"
|
||
|
" int instanceTypeIndex = int(IdParams.x);\n"
|
||
|
"\n"
|
||
|
" fColor = vec4(0.0,0.0,0.0,1.0);\n"
|
||
|
" if( boundingBoxInViewFrustum( mvpoMatrix, instanceTypes[instanceTypeIndex].bbMin.xyz, instanceTypes[instanceTypeIndex].bbMax.xyz ) )\n"
|
||
|
" {\n"
|
||
|
" fColor = vec4(1.0,0.0,0.0,1.0);\n"
|
||
|
" float distanceToObject = distance(osg_ViewMatrixInverse[3].xyz / osg_ViewMatrixInverse[3].w, instanceMatrix[3].xyz / instanceMatrix[3].w );\n"
|
||
|
" for(int i=0;i<instanceTypes[instanceTypeIndex].params.x;++i)\n"
|
||
|
" {\n"
|
||
|
" if( boundingBoxInViewFrustum( mvpoMatrix, instanceTypes[instanceTypeIndex].lods[i].bbMin.xyz, instanceTypes[instanceTypeIndex].lods[i].bbMax.xyz ) &&\n"
|
||
|
" ( distanceToObject >= instanceTypes[instanceTypeIndex].lods[i].distances.x ) && ( distanceToObject < instanceTypes[instanceTypeIndex].lods[i].distances.w ) )\n"
|
||
|
" {\n"
|
||
|
" fColor = vec4(1.0,1.0,0.0,1.0);\n"
|
||
|
" float fadeAlpha = 4.0 * ( clamp( (distanceToObject-instanceTypes[instanceTypeIndex].lods[i].distances.x)/( instanceTypes[instanceTypeIndex].lods[i].distances.y - instanceTypes[instanceTypeIndex].lods[i].distances.x), 0.0, 1.0 ) \n"
|
||
|
" + clamp( (distanceToObject- instanceTypes[instanceTypeIndex].lods[i].distances.z)/( instanceTypes[instanceTypeIndex].lods[i].distances.w - instanceTypes[instanceTypeIndex].lods[i].distances.z), 0.0, 1.0 ) );\n"
|
||
|
" int sampleMask = ( 0xF0 >> int(fadeAlpha) ) & 0xF;\n"
|
||
|
" int indirectCommandIndex = instanceTypes[instanceTypeIndex].lods[i].indirectTargetParams.x;\n"
|
||
|
" int indirectCommandAddress = instanceTypes[instanceTypeIndex].lods[i].indirectTargetParams.y;\n"
|
||
|
" int objectIndex = imageAtomicAdd( getIndirectCommand( indirectCommandIndex ), indirectCommandAddress*indirectCommandSize+1, 1 );\n"
|
||
|
" int indirectTargetAddress = 6*(instanceTypes[instanceTypeIndex].lods[i].indirectTargetParams.z + objectIndex);\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress+0, M0 );\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress+1, M1 );\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress+2, M2 );\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress+3, M3 );\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress+4, ExtraParams );\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress+5, vec4(IdParams.x,IdParams.y,float(sampleMask),0.0) );\n"
|
||
|
" }\n"
|
||
|
" }\n"
|
||
|
" }\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_STATIC_CULL_FRAGMENT[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"layout(location = 0, index = 0) out vec4 FragmentColor;\n"
|
||
|
"\n"
|
||
|
"in vec4 fColor;\n"
|
||
|
"\n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
" FragmentColor = fColor;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_STATIC_DRAW_0_VERTEX[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) in vec4 VertexPosition;\n"
|
||
|
"layout(location = 2) in vec3 VertexNormal;\n"
|
||
|
"layout(location = 3) in vec4 VertexColor;\n"
|
||
|
"layout(location = 8) in vec2 VertexTexCoord0;\n"
|
||
|
"layout(location = 9) in vec3 VertexTexCoord1;\n"
|
||
|
"\n"
|
||
|
"struct InstanceLOD\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 indirectTargetParams; // x=targetID, y=indexInTarget, z=offsetInTarget, w=lodMaxQuantity\n"
|
||
|
" vec4 distances; // x=minDistance, y=minFadeDistance, z=maxFadeDistance, w=maxDistance\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"const int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8;\n"
|
||
|
"\n"
|
||
|
"struct InstanceType\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 params;\n"
|
||
|
" InstanceLOD lods[OSGGPUCULL_MAXIMUM_LOD_NUMBER];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(std140) uniform instanceTypesData\n"
|
||
|
"{\n"
|
||
|
" InstanceType instanceTypes[32];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32F) coherent uniform imageBuffer indirectTarget;\n"
|
||
|
"\n"
|
||
|
"out vec3 ecPosition3;\n"
|
||
|
"out vec3 ecNormal;\n"
|
||
|
"out vec2 TexCoord;\n"
|
||
|
"out vec4 color;\n"
|
||
|
"flat out int sMask;\n"
|
||
|
" \n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
" // every vertex has its type coded on VertexTexCoord1.x,\n"
|
||
|
" // and its lodNumber coded in VertexTexCoord1.y\n"
|
||
|
" int instanceTypeIndex = int(VertexTexCoord1.x);\n"
|
||
|
" int instanceLodNumber = int(VertexTexCoord1.y);\n"
|
||
|
" int indirectTargetAddress = 6*(instanceTypes[instanceTypeIndex].lods[instanceLodNumber].indirectTargetParams.z + gl_InstanceID);\n"
|
||
|
" mat4 instanceMatrix = mat4(\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 0),\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 1),\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 2),\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 3) );\n"
|
||
|
" vec4 extraParams = imageLoad(indirectTarget, indirectTargetAddress + 4);\n"
|
||
|
" vec4 idParams = imageLoad(indirectTarget, indirectTargetAddress + 5);\n"
|
||
|
"\n"
|
||
|
" sMask = int(idParams.z);\n"
|
||
|
"\n"
|
||
|
" mat4 mvMatrix = gl_ModelViewMatrix * instanceMatrix;\n"
|
||
|
" \n"
|
||
|
" // Do fixed functionality vertex transform\n"
|
||
|
" vec4 ecPos = mvMatrix * vec4(VertexPosition.xyz,1.0);\n"
|
||
|
" gl_Position = gl_ProjectionMatrix * ecPos;\n"
|
||
|
"\n"
|
||
|
" ecPosition3 = ecPos.xyz / ecPos.w;\n"
|
||
|
" ecNormal = normalize( mat3(mvMatrix) * VertexNormal.xyz );\n"
|
||
|
" \n"
|
||
|
" TexCoord = VertexTexCoord0.xy;\n"
|
||
|
" color.xyz = VertexColor.xyz * extraParams.x;\n"
|
||
|
" color.a = VertexColor.a;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_STATIC_DRAW_0_FRAGMENT[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"in vec3 ecPosition3;\n"
|
||
|
"in vec3 ecNormal;\n"
|
||
|
"in vec2 TexCoord;\n"
|
||
|
"in vec4 color;\n"
|
||
|
"\n"
|
||
|
"flat in int sMask;\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) out vec4 FragColor;\n"
|
||
|
"\n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
"// simple fragment shader that calculates ambient + diffuse lighting with osg::LightSource\n"
|
||
|
" vec3 lightDir = normalize(vec3(gl_LightSource[0].position));\n"
|
||
|
" vec3 normal = normalize(ecNormal);\n"
|
||
|
" float NdotL = max(dot(normal, lightDir), 0.0);\n"
|
||
|
" FragColor = NdotL * color * gl_LightSource[0].diffuse + color * gl_LightSource[0].ambient;\n"
|
||
|
" gl_SampleMask[0] = sMask;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_STATIC_DRAW_1_VERTEX[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) in vec4 VertexPosition;\n"
|
||
|
"layout(location = 2) in vec3 VertexNormal;\n"
|
||
|
"layout(location = 3) in vec4 VertexColor;\n"
|
||
|
"layout(location = 8) in vec2 VertexTexCoord0;\n"
|
||
|
"layout(location = 9) in vec3 VertexTexCoord1;\n"
|
||
|
"\n"
|
||
|
"struct InstanceLOD\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 indirectTargetParams; // x=targetID, y=indexInTarget, z=offsetInTarget, w=lodMaxQuantity\n"
|
||
|
" vec4 distances; // x=minDistance, y=minFadeDistance, z=maxFadeDistance, w=maxDistance\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"const int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8;\n"
|
||
|
"\n"
|
||
|
"struct InstanceType\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 params;\n"
|
||
|
" InstanceLOD lods[OSGGPUCULL_MAXIMUM_LOD_NUMBER];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(std140) uniform instanceTypesData\n"
|
||
|
"{\n"
|
||
|
" InstanceType instanceTypes[32];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32F) coherent uniform imageBuffer indirectTarget;\n"
|
||
|
"\n"
|
||
|
"uniform vec2 windDirection;\n"
|
||
|
"uniform float osg_FrameTime;\n"
|
||
|
"\n"
|
||
|
"out vec3 ecPosition3;\n"
|
||
|
"out vec3 ecNormal;\n"
|
||
|
"out vec2 TexCoord;\n"
|
||
|
"out vec4 color;\n"
|
||
|
"flat out int sMask;\n"
|
||
|
" \n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
" // every vertex has its type coded on VertexTexCoord1.x,\n"
|
||
|
" // and its lodNumber coded in VertexTexCoord1.y\n"
|
||
|
" int instanceTypeIndex = int(VertexTexCoord1.x);\n"
|
||
|
" int instanceLodNumber = int(VertexTexCoord1.y);\n"
|
||
|
" int indirectTargetAddress = 6*(instanceTypes[instanceTypeIndex].lods[instanceLodNumber].indirectTargetParams.z + gl_InstanceID);\n"
|
||
|
" mat4 instanceMatrix = mat4(\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 0),\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 1),\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 2),\n"
|
||
|
" imageLoad(indirectTarget, indirectTargetAddress + 3) );\n"
|
||
|
" vec4 extraParams = imageLoad(indirectTarget, indirectTargetAddress + 4);\n"
|
||
|
" vec4 idParams = imageLoad(indirectTarget, indirectTargetAddress + 5);\n"
|
||
|
"\n"
|
||
|
" sMask = int(idParams.z);\n"
|
||
|
"\n"
|
||
|
" // simple tree waving in the wind. Amplitude, frequency and offset are coded in extraParams\n"
|
||
|
" vec4 mPos = instanceMatrix * vec4(VertexPosition.xyz,1.0);\n"
|
||
|
" float wavingAmplitute = VertexPosition.z * extraParams.y;\n"
|
||
|
" mPos.xy += windDirection * wavingAmplitute * sin( extraParams.z*osg_FrameTime + extraParams.w );\n"
|
||
|
"\n"
|
||
|
" mat4 mvMatrix = gl_ModelViewMatrix * instanceMatrix;\n"
|
||
|
" \n"
|
||
|
" // Do fixed functionality vertex transform\n"
|
||
|
" vec4 ecPos = osg_ModelViewMatrix * mPos;\n"
|
||
|
" gl_Position = gl_ProjectionMatrix * ecPos;\n"
|
||
|
"\n"
|
||
|
" ecPosition3 = ecPos.xyz / ecPos.w;\n"
|
||
|
" ecNormal = normalize( mat3(mvMatrix) * VertexNormal.xyz );\n"
|
||
|
" \n"
|
||
|
" TexCoord = VertexTexCoord0.xy;\n"
|
||
|
" color.xyz = VertexColor.xyz * extraParams.x;\n"
|
||
|
" color.a = VertexColor.a;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_STATIC_DRAW_1_FRAGMENT[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"in vec3 ecPosition3;\n"
|
||
|
"in vec3 ecNormal;\n"
|
||
|
"in vec2 TexCoord;\n"
|
||
|
"in vec4 color;\n"
|
||
|
"\n"
|
||
|
"flat in int sMask;\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) out vec4 FragColor;\n"
|
||
|
"\n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
"// simple fragment shader that calculates ambient + diffuse lighting with osg::LightSource\n"
|
||
|
" vec3 lightDir = normalize(vec3(gl_LightSource[0].position));\n"
|
||
|
" vec3 normal = normalize(ecNormal);\n"
|
||
|
" float NdotL = max(dot(normal, lightDir), 0.0);\n"
|
||
|
" FragColor = NdotL * color * gl_LightSource[0].diffuse + color * gl_LightSource[0].ambient;\n"
|
||
|
" gl_SampleMask[0] = sMask;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_DYNAMIC_CULL_VERTEX[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"uniform mat4 osg_ViewMatrixInverse;\n"
|
||
|
"\n"
|
||
|
"uniform samplerBuffer dynamicInstancesData;\n"
|
||
|
"uniform int dynamicInstancesDataSize; // = sizeof(DynamicInstance) / sizeof(osg::Vec4f)\n"
|
||
|
"\n"
|
||
|
"layout(R32I) coherent uniform iimageBuffer indirectCommand0;\n"
|
||
|
"uniform int indirectCommandSize; // = sizeof(DrawArraysIndirectCommand) / sizeof(unsigned int) = 4\n"
|
||
|
"\n"
|
||
|
"layout(R32I) coherent uniform iimageBuffer getIndirectCommand( int index )\n"
|
||
|
"{\n"
|
||
|
" if(index==0) return indirectCommand0;\n"
|
||
|
"}\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32I) coherent uniform iimageBuffer indirectTarget0;\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32I) coherent uniform iimageBuffer getIndirectTarget( int index )\n"
|
||
|
"{\n"
|
||
|
" if(index==0) return indirectTarget0;\n"
|
||
|
"}\n"
|
||
|
"\n"
|
||
|
"struct InstanceLOD\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 indirectTargetParams; // x=targetID, y=indexInTarget, z=offsetInTarget, w=lodMaxQuantity\n"
|
||
|
" vec4 distances; // x=minDistance, y=minFadeDistance, z=maxFadeDistance, w=maxDistance\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"const int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8;\n"
|
||
|
"\n"
|
||
|
"struct InstanceType\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 params;\n"
|
||
|
" InstanceLOD lods[OSGGPUCULL_MAXIMUM_LOD_NUMBER];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(std140) uniform instanceTypesData\n"
|
||
|
"{\n"
|
||
|
" InstanceType instanceTypes[32];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) in vec3 VertexPosition; // xyz - used only for debugging purposes\n"
|
||
|
"layout(location = 10) in vec4 InstanceID; // typeid, id - points to the data in dynamicInstancesData buffer\n"
|
||
|
"\n"
|
||
|
"bool boundingBoxInViewFrustum( in mat4 matrix, in vec3 bbMin, in vec3 bbMax )\n"
|
||
|
"{\n"
|
||
|
" vec4 BoundingBox[8];\n"
|
||
|
" BoundingBox[0] = matrix * vec4( bbMax.x, bbMax.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[1] = matrix * vec4( bbMin.x, bbMax.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[2] = matrix * vec4( bbMax.x, bbMin.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[3] = matrix * vec4( bbMin.x, bbMin.y, bbMax.z, 1.0);\n"
|
||
|
" BoundingBox[4] = matrix * vec4( bbMax.x, bbMax.y, bbMin.z, 1.0);\n"
|
||
|
" BoundingBox[5] = matrix * vec4( bbMin.x, bbMax.y, bbMin.z, 1.0);\n"
|
||
|
" BoundingBox[6] = matrix * vec4( bbMax.x, bbMin.y, bbMin.z, 1.0);\n"
|
||
|
" BoundingBox[7] = matrix * vec4( bbMin.x, bbMin.y, bbMin.z, 1.0);\n"
|
||
|
"\n"
|
||
|
" int outOfBound[6] = int[6]( 0, 0, 0, 0, 0, 0 );\n"
|
||
|
" for (int i=0; i<8; i++)\n"
|
||
|
" {\n"
|
||
|
" outOfBound[0] += int( BoundingBox[i].x > BoundingBox[i].w );\n"
|
||
|
" outOfBound[1] += int( BoundingBox[i].x < -BoundingBox[i].w );\n"
|
||
|
" outOfBound[2] += int( BoundingBox[i].y > BoundingBox[i].w );\n"
|
||
|
" outOfBound[3] += int( BoundingBox[i].y < -BoundingBox[i].w );\n"
|
||
|
" outOfBound[4] += int( BoundingBox[i].z > BoundingBox[i].w );\n"
|
||
|
" outOfBound[5] += int( BoundingBox[i].z < -BoundingBox[i].w );\n"
|
||
|
" }\n"
|
||
|
" return (outOfBound[0] < 8 ) && ( outOfBound[1] < 8 ) && ( outOfBound[2] < 8 ) && ( outOfBound[3] < 8 ) && ( outOfBound[4] < 8 ) && ( outOfBound[5] < 8 );\n"
|
||
|
"}\n"
|
||
|
"\n"
|
||
|
"void main(void) \n"
|
||
|
"{\n"
|
||
|
" // get object matrices\n"
|
||
|
" int instanceIndex = int(InstanceID.y);\n"
|
||
|
" int instanceAddress = instanceIndex * dynamicInstancesDataSize;\n"
|
||
|
" mat4 instanceMatrix = mat4 (\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress),\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress + 1),\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress + 2),\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress + 3) );\n"
|
||
|
" mat4 mvpoMatrix = gl_ModelViewProjectionMatrix * instanceMatrix;\n"
|
||
|
"\n"
|
||
|
" // gl_Position is created only for debugging purposes\n"
|
||
|
" gl_Position = mvpoMatrix * vec4(0.0,0.0,0.0,1.0);\n"
|
||
|
"\n"
|
||
|
" int instanceTypeIndex = int(InstanceID.x);\n"
|
||
|
"\n"
|
||
|
" if( boundingBoxInViewFrustum( mvpoMatrix, instanceTypes[instanceTypeIndex].bbMin.xyz, instanceTypes[instanceTypeIndex].bbMax.xyz ) )\n"
|
||
|
" {\n"
|
||
|
" float distanceToObject = distance(osg_ViewMatrixInverse[3].xyz / osg_ViewMatrixInverse[3].w, instanceMatrix[3].xyz / instanceMatrix[3].w );\n"
|
||
|
" for(int i=0;i<instanceTypes[instanceTypeIndex].params.x;++i)\n"
|
||
|
" {\n"
|
||
|
" if( boundingBoxInViewFrustum( mvpoMatrix, instanceTypes[instanceTypeIndex].lods[i].bbMin.xyz, instanceTypes[instanceTypeIndex].lods[i].bbMax.xyz ) &&\n"
|
||
|
" ( distanceToObject >= instanceTypes[instanceTypeIndex].lods[i].distances.x ) && ( distanceToObject < instanceTypes[instanceTypeIndex].lods[i].distances.w ) )\n"
|
||
|
" {\n"
|
||
|
" float fadeAlpha = 4.0 * ( clamp( (distanceToObject-instanceTypes[instanceTypeIndex].lods[i].distances.x)/( instanceTypes[instanceTypeIndex].lods[i].distances.y - instanceTypes[instanceTypeIndex].lods[i].distances.x), 0.0, 1.0 ) \n"
|
||
|
" + clamp( (distanceToObject- instanceTypes[instanceTypeIndex].lods[i].distances.z)/( instanceTypes[instanceTypeIndex].lods[i].distances.w - instanceTypes[instanceTypeIndex].lods[i].distances.z), 0.0, 1.0 ) );\n"
|
||
|
" int sampleMask = ( 0xF0 >> int(fadeAlpha) ) & 0xF;\n"
|
||
|
" int indirectCommandIndex = instanceTypes[instanceTypeIndex].lods[i].indirectTargetParams.x;\n"
|
||
|
" int indirectCommandAddress = instanceTypes[instanceTypeIndex].lods[i].indirectTargetParams.y;\n"
|
||
|
" int objectIndex = imageAtomicAdd( getIndirectCommand( indirectCommandIndex ), indirectCommandAddress*indirectCommandSize+1, 1 );\n"
|
||
|
" int indirectTargetAddress = instanceTypes[instanceTypeIndex].lods[i].indirectTargetParams.z + objectIndex;\n"
|
||
|
" ivec4 indirectCommandData = ivec4( instanceTypeIndex, instanceIndex, sampleMask, 0 );\n"
|
||
|
" imageStore( getIndirectTarget(indirectCommandIndex), indirectTargetAddress, indirectCommandData );\n"
|
||
|
" }\n"
|
||
|
" }\n"
|
||
|
" }\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_DYNAMIC_CULL_FRAGMENT[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"layout(location = 0, index = 0) out vec4 FragmentColor;\n"
|
||
|
"\n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
" FragmentColor = vec4(1.0,1.0,0.1,1.0);\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_DYNAMIC_DRAW_0_VERTEX[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"uniform samplerBuffer dynamicInstancesData;\n"
|
||
|
"uniform int dynamicInstancesDataSize; // = sizeof(DynamicInstance) / sizeof(osg::Vec4f)\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) in vec4 VertexPosition;\n"
|
||
|
"layout(location = 2) in vec3 VertexNormal;\n"
|
||
|
"layout(location = 3) in vec4 VertexColor;\n"
|
||
|
"layout(location = 8) in vec2 VertexTexCoord0;\n"
|
||
|
"layout(location = 9) in vec3 VertexTexCoord1;\n"
|
||
|
"\n"
|
||
|
"struct InstanceLOD\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 indirectTargetParams; // x=targetID, y=indexInTarget, z=offsetInTarget, w=lodMaxQuantity\n"
|
||
|
" vec4 distances; // x=minDistance, y=minFadeDistance, z=maxFadeDistance, w=maxDistance\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"const int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8;\n"
|
||
|
"\n"
|
||
|
"struct InstanceType\n"
|
||
|
"{\n"
|
||
|
" vec4 bbMin;\n"
|
||
|
" vec4 bbMax;\n"
|
||
|
" ivec4 params;\n"
|
||
|
" InstanceLOD lods[OSGGPUCULL_MAXIMUM_LOD_NUMBER];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(std140) uniform instanceTypesData\n"
|
||
|
"{\n"
|
||
|
" InstanceType instanceTypes[32];\n"
|
||
|
"};\n"
|
||
|
"\n"
|
||
|
"layout(RGBA32I) coherent uniform iimageBuffer indirectTarget;\n"
|
||
|
"\n"
|
||
|
"out vec3 ecPosition3;\n"
|
||
|
"out vec3 ecNormal;\n"
|
||
|
"out vec2 TexCoord;\n"
|
||
|
"out vec4 color;\n"
|
||
|
"flat out int sMask;\n"
|
||
|
" \n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
" // every vertex has its type coded on VertexTexCoord1.x,\n"
|
||
|
" // its lodNumber coded in VertexTexCoord1.y\n"
|
||
|
" // and bone index coded in VertexTexCoord1.z\n"
|
||
|
" int instanceTypeIndex = int(VertexTexCoord1.x);\n"
|
||
|
" int instanceLodNumber = int(VertexTexCoord1.y);\n"
|
||
|
" int boneIndex = int(VertexTexCoord1.z);\n"
|
||
|
" int indirectTargetAddress = instanceTypes[instanceTypeIndex].lods[instanceLodNumber].indirectTargetParams.z + gl_InstanceID;\n"
|
||
|
"\n"
|
||
|
" // if we know instance type, lod number and gl_InstanceID, we can reconstruct all instance data\n"
|
||
|
" ivec4 indirectCommandData = imageLoad(indirectTarget, indirectTargetAddress);\n"
|
||
|
" // now its time to read instance matrix and other additional params\n"
|
||
|
" int instanceAddress = indirectCommandData.y * dynamicInstancesDataSize;\n"
|
||
|
" mat4 instanceMatrix = mat4 (\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress),\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress + 1),\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress + 2),\n"
|
||
|
" texelFetch(dynamicInstancesData, instanceAddress + 3) );\n"
|
||
|
"\n"
|
||
|
" vec4 instanceExtraParams = texelFetch(dynamicInstancesData, instanceAddress + 4);\n"
|
||
|
" // we also need boneMatrix to animate an object\n"
|
||
|
" int boneAddress = instanceAddress + 6 + 4*boneIndex;\n"
|
||
|
" mat4 boneMatrix = mat4 (\n"
|
||
|
" texelFetch(dynamicInstancesData, boneAddress),\n"
|
||
|
" texelFetch(dynamicInstancesData, boneAddress + 1),\n"
|
||
|
" texelFetch(dynamicInstancesData, boneAddress + 2),\n"
|
||
|
" texelFetch(dynamicInstancesData, boneAddress + 3) );\n"
|
||
|
"\n"
|
||
|
" sMask = indirectCommandData.z;\n"
|
||
|
"\n"
|
||
|
" mat4 mvMatrix = gl_ModelViewMatrix * instanceMatrix * boneMatrix;\n"
|
||
|
" \n"
|
||
|
" // Do fixed functionality vertex transform\n"
|
||
|
" vec4 ecPos = mvMatrix * vec4(VertexPosition.xyz,1.0);\n"
|
||
|
" gl_Position = gl_ProjectionMatrix * ecPos;\n"
|
||
|
"\n"
|
||
|
" ecPosition3 = ecPos.xyz / ecPos.w;\n"
|
||
|
" ecNormal = normalize( mat3(mvMatrix) * VertexNormal.xyz );\n"
|
||
|
" \n"
|
||
|
" TexCoord = VertexTexCoord0.xy;\n"
|
||
|
" color.xyz = VertexColor.xyz * instanceExtraParams.x;\n"
|
||
|
" color.a = VertexColor.a;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
char SHADER_DYNAMIC_DRAW_0_FRAGMENT[] =
|
||
|
"#version 420 compatibility\n"
|
||
|
"\n"
|
||
|
"in vec3 ecPosition3;\n"
|
||
|
"in vec3 ecNormal;\n"
|
||
|
"in vec2 TexCoord;\n"
|
||
|
"in vec4 color;\n"
|
||
|
"\n"
|
||
|
"flat in int sMask;\n"
|
||
|
"\n"
|
||
|
"layout(location = 0) out vec4 FragColor;\n"
|
||
|
"\n"
|
||
|
"void main()\n"
|
||
|
"{\n"
|
||
|
"// simple fragment shader that calculates ambient + diffuse lighting with osg::LightSource\n"
|
||
|
" vec3 lightDir = normalize(vec3(gl_LightSource[0].position));\n"
|
||
|
" vec3 normal = normalize(ecNormal);\n"
|
||
|
" float NdotL = max(dot(normal, lightDir), 0.0);\n"
|
||
|
" FragColor = NdotL * color * gl_LightSource[0].diffuse + color * gl_LightSource[0].ambient;\n"
|
||
|
" gl_SampleMask[0] = sMask;\n"
|
||
|
"}\n";
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|