diff --git a/Docs/src/high-level-programs.md b/Docs/src/high-level-programs.md index 0428bbebef3..af5f048e77a 100644 --- a/Docs/src/high-level-programs.md +++ b/Docs/src/high-level-programs.md @@ -129,6 +129,14 @@ refer to the following table for the location indices and names to use: @note uv6 and uv7 share attributes with tangent and binormal respectively so cannot both be present. +## Buffers in Mesh Shaders {#GLSL-Mesh-Shaders} + +With mesh shaders the input assembly stage is skipped and hence the vertex attributes are not available. Instead, %Ogre will bind the vertex buffers as SSBOs to a binding point defined by the Ogre::VertexBufferBinding index. + +In the shader you can access the buffer as follows: + +@snippet Samples/Media/materials/programs/GLSL400/MeshProgram.glsl vertexbuffer + ## Binding Texture Samplers {#GLSL-Texture-Samplers} To bind samplers to texture unit indices from the material scripts, you can either use the explicit binding with GL4.2+ or @@ -206,15 +214,15 @@ The available varyings are: The following features are only available when using the legacy OpenGL profile. Notably they are not available with GL3+ or GLES2. -### Accessing OpenGL state +### OpenGL state GLSL can access most of the GL states directly so you do not need to pass these states through [param\_named\_auto](#param_005fnamed_005fauto) in the material script. This includes lights, material state, and all the matrices used in the openGL state i.e. model view matrix, worldview projection matrix etc. -### Access to built-in attributes +### Built-in attributes GLSL natively supports automatic binding of the most common incoming per-vertex attributes (e.g. `gl_Vertex`, `gl_Normal`, `gl_MultiTexCoord0` etc) as described in section 7.3 of the GLSL manual. There are some drivers that do not behave correctly when mixing built-in vertex attributes like `gl_Normal` and custom vertex attributes, so for maximum compatibility you should use all custom attributes -### Geometry shader specification +### Geometry shader in/ out GLSL allows the same shader to run on different types of geometry primitives. In order to properly link the shaders together, you have to specify which primitives it will receive as input, which primitives it will emit and how many vertices a single run of the shader can generate. The GLSL geometry\_program definition requires three additional parameters @param input\_operation\_type diff --git a/Samples/Media/materials/programs/GLSL400/MeshProgram.glsl b/Samples/Media/materials/programs/GLSL400/MeshProgram.glsl index ab08b2d8fb7..0f3e2008d73 100644 --- a/Samples/Media/materials/programs/GLSL400/MeshProgram.glsl +++ b/Samples/Media/materials/programs/GLSL400/MeshProgram.glsl @@ -17,6 +17,41 @@ layout(location=0) out PerVertexData vec3 color; } v_out[]; +#ifdef VULKAN +layout(binding=0, row_major) uniform OgreUniforms +{ + mat4 MVP; + float t; +}; + +// SSBOs cannot be used with Vulkan yet +float data[] = { + -100, -100, 0, // pos + 0,0,1, // normal + 0,1, // texcoord + 100, -100, 0, + 0,0,1, + 1,1, + 100, 100, 0, + 0,0,1, + 1,0, + -100, 100, 0 , + 0,0,1, + 0,0 +}; +#else +// UBOs cannot be used with gl_spirv yet +layout(location=0) uniform mat4 MVP; +layout(location=4) uniform float t; + +//![vertexbuffer] +// buffer at index 0, which is expected to contain float data +layout(binding = 0) buffer VertexDataIn +{ + float data[]; +}; +//![vertexbuffer] +#endif void main() { @@ -24,28 +59,24 @@ void main() float frac = gl_WorkGroupID.x / 6.0; - float xmin = -1.0 + frac * 2.0; - float xmax = xmin + 2.0 / (7.0); - - gl_MeshVerticesEXT[0].gl_Position = vec4(xmin, -0.5, 0.0, 1.0); // Upper Left - gl_MeshVerticesEXT[1].gl_Position = vec4(xmax, -0.5, 0.0, 1.0); // Upper Right - gl_MeshVerticesEXT[2].gl_Position = vec4(xmin, 0.5, 0.0, 1.0); // Bottom Left - gl_MeshVerticesEXT[3].gl_Position = vec4(xmax, 0.5, 0.0, 1.0); // Bottom Right + for (int i = 0; i < 4; i++) + { + vec4 pos = vec4(data[i * 8 + 0], data[i * 8 + 1], data[i * 8 + 2], 1); + pos.x = pos.x + 250.0 * gl_WorkGroupID.x - 625.0; - v_out[0].color = vec3(1.0, 0.0, 0.0); - v_out[1].color = vec3(0.0, 1.0, 0.0); - v_out[2].color = vec3(0.0, 0.0, 1.0); - v_out[3].color = vec3(1.0, 1.0, 0.0); + gl_MeshVerticesEXT[i].gl_Position = MVP * pos; + v_out[i].color = vec3(data[i * 8 + 6], data[i * 8 + 7], sin(mod((t + frac) * 3.14, 3.14))); + } #ifdef VULKAN gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2); - gl_PrimitiveTriangleIndicesEXT[1] = uvec3(2, 1, 3); + gl_PrimitiveTriangleIndicesEXT[1] = uvec3(0, 2, 3); #else gl_PrimitiveIndicesNV[0] = 0; gl_PrimitiveIndicesNV[1] = 1; gl_PrimitiveIndicesNV[2] = 2; - gl_PrimitiveIndicesNV[3] = 2; - gl_PrimitiveIndicesNV[4] = 1; + gl_PrimitiveIndicesNV[3] = 0; + gl_PrimitiveIndicesNV[4] = 2; gl_PrimitiveIndicesNV[5] = 3; #endif } \ No newline at end of file diff --git a/Samples/Media/materials/scripts/AdvancedGLSL.material b/Samples/Media/materials/scripts/AdvancedGLSL.material index d55bb44d672..fdf2a704c35 100644 --- a/Samples/Media/materials/scripts/AdvancedGLSL.material +++ b/Samples/Media/materials/scripts/AdvancedGLSL.material @@ -36,6 +36,12 @@ fragment_program Ogre/MeshShaderFp glslang mesh_program Ogre/MeshShader glslang { source MeshProgram.glsl + + default_params + { + param_named_auto MVP worldviewproj_matrix + param_named_auto t time_0_1 1.5 + } } material Example/MeshShader