diff --git a/TIGLViewer/shaders/PhongShading-v7.6.fs b/TIGLViewer/shaders/PhongShading-v7.6.fs new file mode 100644 index 000000000..d02cb75a2 --- /dev/null +++ b/TIGLViewer/shaders/PhongShading-v7.6.fs @@ -0,0 +1,215 @@ +// Created on: 2013-10-10 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +varying vec3 View; //!< Direction to the viewer +varying vec3 Normal; //!< Vertex normal in view space +varying vec4 Position; //!< Vertex position in view space. +varying vec4 PositionWorld; //!< Vertex position in world space +varying vec4 uv; //!< Vertex uv coordinate + +uniform bool enableZebra; //!< Whether the zebra stripe mode is enabled + +vec3 Ambient; //!< Ambient contribution of light sources +vec3 Diffuse; //!< Diffuse contribution of light sources +vec3 Specular; //!< Specular contribution of light sources + +//! Computes contribution of isotropic point light source +void pointLight (in int theId, + in vec3 theNormal, + in vec3 theView, + in vec3 thePoint) +{ + vec3 aLight = occLight_Position (theId).xyz; + if (!occLight_IsHeadlight (theId)) + { + aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0)); + } + aLight -= thePoint; + + float aDist = length (aLight); + aLight = aLight * (1.0 / aDist); + + float anAtten = 1.0 / (occLight_ConstAttenuation (theId) + + occLight_LinearAttenuation (theId) * aDist); + + vec3 aHalf = normalize (aLight + theView); + + vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal; + float aNdotL = max (0.0, dot (aFaceSideNormal, aLight)); + float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf )); + + float aSpecl = 0.0; + if (aNdotL > 0.0) + { + aSpecl = pow (aNdotH, occMaterial_Shininess (gl_FrontFacing)); + } + + Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; + Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; +} + +//! Computes contribution of spotlight source +void spotLight (in int theId, + in vec3 theNormal, + in vec3 theView, + in vec3 thePoint) +{ + vec3 aLight = occLight_Position (theId).xyz; + vec3 aSpotDir = occLight_SpotDirection (theId).xyz; + if (!occLight_IsHeadlight (theId)) + { + aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0)); + aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0)); + } + aLight -= thePoint; + + float aDist = length (aLight); + aLight = aLight * (1.0 / aDist); + + aSpotDir = normalize (aSpotDir); + + // light cone + float aCosA = dot (aSpotDir, -aLight); + if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId))) + { + return; + } + + float anExponent = occLight_SpotExponent (theId); + float anAtten = 1.0 / (occLight_ConstAttenuation (theId) + + occLight_LinearAttenuation (theId) * aDist); + if (anExponent > 0.0) + { + anAtten *= pow (aCosA, anExponent * 128.0); + } + + vec3 aHalf = normalize (aLight + theView); + + vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal; + float aNdotL = max (0.0, dot (aFaceSideNormal, aLight)); + float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf )); + + float aSpecl = 0.0; + if (aNdotL > 0.0) + { + aSpecl = pow (aNdotH, occMaterial_Shininess (gl_FrontFacing)); + } + + Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; + Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; +} + +//! Computes contribution of directional light source +void directionalLight (in int theId, + in vec3 theNormal, + in vec3 theView) +{ + vec3 aLight = normalize (occLight_Position (theId).xyz); + if (!occLight_IsHeadlight (theId)) + { + aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0)); + } + + vec3 aHalf = normalize (aLight + theView); + + vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal; + float aNdotL = max (0.0, dot (aFaceSideNormal, aLight)); + float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf )); + + float aSpecl = 0.0; + if (aNdotL > 0.0) + { + aSpecl = pow (aNdotH, occMaterial_Shininess (gl_FrontFacing)); + } + + Diffuse += occLight_Diffuse (theId).rgb * aNdotL; + Specular += occLight_Specular (theId).rgb * aSpecl; +} + +//! Computes illumination from light sources +vec4 computeLighting (in vec3 theNormal, + in vec3 theView, + in vec4 thePoint) +{ + // Clear the light intensity accumulators + Ambient = occLightAmbient.rgb; + Diffuse = vec3 (0.0); + Specular = vec3 (0.0); + vec3 aPoint = thePoint.xyz / thePoint.w; + for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex) + { + int aType = occLight_Type (anIndex); + if (aType == OccLightType_Direct) + { + directionalLight (anIndex, theNormal, theView); + } + else if (aType == OccLightType_Point) + { + pointLight (anIndex, theNormal, theView, aPoint); + } + else if (aType == OccLightType_Spot) + { + spotLight (anIndex, theNormal, theView, aPoint); + } + } + + vec3 aMatAmbient = occMaterial_Ambient (gl_FrontFacing); + vec4 aMatDiffuse = occMaterial_Diffuse (gl_FrontFacing); + vec3 aMatSpecular = occMaterial_Specular(gl_FrontFacing); + vec3 aMatEmission = occMaterial_Emission(gl_FrontFacing); + vec3 aColor = Ambient * aMatAmbient.rgb + + Diffuse * aMatDiffuse.rgb + + Specular * aMatSpecular.rgb + + aMatEmission.rgb; + + float attenuation = 1.0; + if (enableZebra) + { + vec3 v = vec3(0., 0., -1.); + + // Direction of the view reflected on the surface + vec3 vReflect = 2. * (dot(Normal, v)*Normal - v); + + // normal vector of the light stripe plane + vec3 lightDir = normalize(vec3(0., 1., 0.)); + + // View projected into light plane + vec3 vProj = normalize(v - dot(v, lightDir)*lightDir); + + // x-position of the reflected view on the light plane + float posLightPlane = dot(vReflect, vProj); + + attenuation = max(min(2.0, sin(posLightPlane*30.0)*3. + 2.0), -1.0); + } + + return vec4 (aColor, aMatDiffuse.a) * vec4(attenuation, attenuation, attenuation, 1.0); +} + +//! Entry point to the Fragment Shader +void main() +{ + // process clipping planes + for (int anIndex = 0; anIndex < occClipPlaneCount; ++anIndex) + { + vec4 aClipEquation = occClipPlaneEquations[anIndex]; + if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0) + { + discard; + } + } + + vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position); + occSetFragColor (aColor); +} diff --git a/TIGLViewer/shaders/PhongShading-v7.6.vs b/TIGLViewer/shaders/PhongShading-v7.6.vs new file mode 100644 index 000000000..698bd4bde --- /dev/null +++ b/TIGLViewer/shaders/PhongShading-v7.6.vs @@ -0,0 +1,45 @@ +// Created on: 2013-10-10 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +varying vec3 View; //!< Direction to the viewer +varying vec3 Normal; //!< Vertex normal in view space +varying vec4 Position; //!< Vertex position in view space +varying vec4 PositionWorld; //!< Vertex position in world space +varying vec4 uv; //!< Vertex uv coordinates + +//! Computes the normal in view space +vec3 TransformNormal (in vec3 theNormal) +{ + vec4 aResult = occWorldViewMatrixInverseTranspose + * occModelWorldMatrixInverseTranspose + * vec4 (theNormal, 0.0); + return normalize (aResult.xyz); +} + +//! Entry point to the Vertex Shader +void main() +{ + PositionWorld = occModelWorldMatrix * occVertex; + Position = occWorldViewMatrix * PositionWorld; + Normal = TransformNormal (occNormal); + + // Note: The specified view vector is absolutely correct only for the orthogonal projection. + // For perspective projection it will be approximate, but it is in good agreement with the OpenGL calculations. + View = vec3 (0.0, 0.0, 1.0); + + // Do fixed functionality vertex transform + gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex; + uv = occTexCoord; +} diff --git a/TIGLViewer/src/TIGLViewer.qrc b/TIGLViewer/src/TIGLViewer.qrc index 8b8562cfa..cb6cac3fc 100644 --- a/TIGLViewer/src/TIGLViewer.qrc +++ b/TIGLViewer/src/TIGLViewer.qrc @@ -28,6 +28,8 @@ ../shaders/PhongShading-v6.vs ../shaders/PhongShading-v7.fs ../shaders/PhongShading-v7.vs + ../shaders/PhongShading-v7.6.fs + ../shaders/PhongShading-v7.6.vs ../gfx/error.png diff --git a/TIGLViewer/src/TIGLViewerContext.cpp b/TIGLViewer/src/TIGLViewerContext.cpp index 05fc0f5c1..4ca635b9b 100644 --- a/TIGLViewer/src/TIGLViewerContext.cpp +++ b/TIGLViewer/src/TIGLViewerContext.cpp @@ -111,7 +111,9 @@ TIGLViewerContext::TIGLViewerContext(QUndoStack* stack) void TIGLViewerContext::initShaders() { -#if OCC_VERSION_HEX >= VERSION_HEX_CODE(7,0,0) +#if OCC_VERSION_HEX >= VERSION_HEX_CODE(7,6,0) + QString shaderVersion = "v7.6"; +#elif OCC_VERSION_HEX >= VERSION_HEX_CODE(7,0,0) QString shaderVersion = "v7"; #elif OCC_VERSION_HEX >= VERSION_HEX_CODE(6,7,0) QString shaderVersion = "v6";