X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FShaders%2FPhongShading.fs;h=15311c74463581385bb5c9346d92524702eae052;hp=1b0779f0269319d8505007716579518ca767d96f;hb=a1073ae267989cea79ceb5299b4f921da714616d;hpb=123813413566a4fc07c6e57a8f9fb0709bbb14ab diff --git a/src/Shaders/PhongShading.fs b/src/Shaders/PhongShading.fs old mode 100644 new mode 100755 index 1b0779f026..15311c7446 --- a/src/Shaders/PhongShading.fs +++ b/src/Shaders/PhongShading.fs @@ -1,25 +1,22 @@ // Created on: 2013-10-10 // Created by: Denis BOGOLEPOV -// Copyright (c) 2013 OPEN CASCADE SAS +// Copyright (c) 2013-2014 OPEN CASCADE SAS // -// The content of this file is subject to the Open CASCADE Technology Public -// License Version 6.5 (the "License"). You may not use the content of this file -// except in compliance with the License. Please obtain a copy of the License -// at http://www.opencascade.org and read it completely before using this file. +// This file is part of Open CASCADE Technology software library. // -// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its -// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// 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. // -// The Original Code and all software distributed under the License is -// distributed on an "AS IS" basis, without warranty of any kind, and the -// Initial Developer hereby disclaims all such warranties, including without -// limitation, any warranties of merchantability, fitness for a particular -// purpose or non-infringement. Please see the License for the specific terms -// and conditions governing the rights and limitations under the License. +// 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 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 vec3 Ambient; //!< Ambient contribution of light sources vec3 Diffuse; //!< Diffuse contribution of light sources @@ -34,7 +31,7 @@ void pointLight (in int theId, vec3 aLight = occLight_Position (theId).xyz; if (occLight_IsHeadlight (theId) == 0) { - aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0)); + aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0)); } aLight -= thePoint; @@ -46,13 +43,65 @@ void pointLight (in int theId, vec3 aHalf = normalize (aLight + theView); - float aNdotL = max (0.0, dot (theNormal, aLight)); - float aNdotH = max (0.0, dot (theNormal, aHalf )); + 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, occFrontMaterial_Shininess()); + aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); + } + + 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) == 0) + { + 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, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); } Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; @@ -67,17 +116,19 @@ void directionalLight (in int theId, vec3 aLight = normalize (occLight_Position (theId).xyz); if (occLight_IsHeadlight (theId) == 0) { - aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0)); + aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0)); } vec3 aHalf = normalize (aLight + theView); - float aNdotL = max (0.0, dot (theNormal, aLight)); - float aNdotH = max (0.0, dot (theNormal, aHalf )); + + 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, occFrontMaterial_Shininess()); + aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); } Diffuse += occLight_Diffuse (theId).rgb * aNdotL; @@ -107,19 +158,42 @@ vec4 computeLighting (in vec3 theNormal, } else if (aType == OccLightType_Spot) { - // Not implemented + spotLight (anIndex, theNormal, theView, aPoint); } } - return vec4 (Ambient, 1.0) * occFrontMaterial_Ambient() - + vec4 (Diffuse, 1.0) * occFrontMaterial_Diffuse() - + vec4 (Specular, 1.0) * occFrontMaterial_Specular(); + vec4 aMaterialAmbient = gl_FrontFacing ? occFrontMaterial_Ambient() : occBackMaterial_Ambient(); + vec4 aMaterialDiffuse = gl_FrontFacing ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse(); + vec4 aMaterialSpecular = gl_FrontFacing ? occFrontMaterial_Specular() : occBackMaterial_Specular(); + vec4 aMaterialEmission = gl_FrontFacing ? occFrontMaterial_Emission() : occBackMaterial_Emission(); + vec3 aColor = Ambient * aMaterialAmbient.rgb + + Diffuse * aMaterialDiffuse.rgb + + Specular * aMaterialSpecular.rgb + + aMaterialEmission.rgb; + return vec4 (aColor, aMaterialDiffuse.a); } //! Entry point to the Fragment Shader void main() { - gl_FragColor = computeLighting (normalize (Normal), + // 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; + } + } + + occFragColor = computeLighting (normalize (Normal), normalize (View), Position); + + if (occOitOutput != 0) + { + float aWeight = occFragColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2); + occFragCoverage.r = occFragColor.a * aWeight; + occFragColor = vec4 (occFragColor.rgb * occFragColor.a * aWeight, occFragColor.a); + } }