0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / Shaders / PhongShading.fs
CommitLineData
392ac980 1// Created on: 2013-10-10
2// Created by: Denis BOGOLEPOV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
392ac980 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
392ac980 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
392ac980 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
392ac980 15
5495fa7e 16varying vec3 View; //!< Direction to the viewer
17varying vec3 Normal; //!< Vertex normal in view space
18varying vec4 Position; //!< Vertex position in view space.
19varying vec4 PositionWorld; //!< Vertex position in world space
392ac980 20
12381341 21vec3 Ambient; //!< Ambient contribution of light sources
22vec3 Diffuse; //!< Diffuse contribution of light sources
23vec3 Specular; //!< Specular contribution of light sources
392ac980 24
12381341 25//! Computes contribution of isotropic point light source
26void pointLight (in int theId,
392ac980 27 in vec3 theNormal,
28 in vec3 theView,
29 in vec3 thePoint)
30{
12381341 31 vec3 aLight = occLight_Position (theId).xyz;
67312b79 32 if (!occLight_IsHeadlight (theId))
392ac980 33 {
5f4bd4d4 34 aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
392ac980 35 }
36 aLight -= thePoint;
37
38 float aDist = length (aLight);
39 aLight = aLight * (1.0 / aDist);
12381341 40
41 float anAtten = 1.0 / (occLight_ConstAttenuation (theId)
42 + occLight_LinearAttenuation (theId) * aDist);
392ac980 43
44 vec3 aHalf = normalize (aLight + theView);
45
c90e941f 46 vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
47 float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
48 float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
392ac980 49
50 float aSpecl = 0.0;
51 if (aNdotL > 0.0)
52 {
c90e941f 53 aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
392ac980 54 }
12381341 55
56 Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;
57 Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
392ac980 58}
59
816d03ee 60//! Computes contribution of spotlight source
61void spotLight (in int theId,
62 in vec3 theNormal,
63 in vec3 theView,
64 in vec3 thePoint)
65{
66 vec3 aLight = occLight_Position (theId).xyz;
67 vec3 aSpotDir = occLight_SpotDirection (theId).xyz;
68 if (occLight_IsHeadlight (theId) == 0)
69 {
5f4bd4d4 70 aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
71 aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));
816d03ee 72 }
73 aLight -= thePoint;
74
75 float aDist = length (aLight);
76 aLight = aLight * (1.0 / aDist);
77
78 aSpotDir = normalize (aSpotDir);
79
80 // light cone
81 float aCosA = dot (aSpotDir, -aLight);
82 if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))
83 {
84 return;
85 }
86
87 float anExponent = occLight_SpotExponent (theId);
88 float anAtten = 1.0 / (occLight_ConstAttenuation (theId)
89 + occLight_LinearAttenuation (theId) * aDist);
90 if (anExponent > 0.0)
91 {
92 anAtten *= pow (aCosA, anExponent * 128.0);
93 }
94
95 vec3 aHalf = normalize (aLight + theView);
96
97 vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
98 float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
99 float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
100
101 float aSpecl = 0.0;
102 if (aNdotL > 0.0)
103 {
104 aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
105 }
106
107 Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;
108 Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
109}
110
12381341 111//! Computes contribution of directional light source
112void directionalLight (in int theId,
392ac980 113 in vec3 theNormal,
114 in vec3 theView)
115{
12381341 116 vec3 aLight = normalize (occLight_Position (theId).xyz);
117 if (occLight_IsHeadlight (theId) == 0)
392ac980 118 {
5f4bd4d4 119 aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));
392ac980 120 }
12381341 121
392ac980 122 vec3 aHalf = normalize (aLight + theView);
c90e941f 123
124 vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
125 float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
126 float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
392ac980 127
128 float aSpecl = 0.0;
392ac980 129 if (aNdotL > 0.0)
130 {
c90e941f 131 aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
392ac980 132 }
133
12381341 134 Diffuse += occLight_Diffuse (theId).rgb * aNdotL;
135 Specular += occLight_Specular (theId).rgb * aSpecl;
392ac980 136}
137
12381341 138//! Computes illumination from light sources
139vec4 computeLighting (in vec3 theNormal,
392ac980 140 in vec3 theView,
141 in vec4 thePoint)
142{
143 // Clear the light intensity accumulators
12381341 144 Ambient = occLightAmbient.rgb;
392ac980 145 Diffuse = vec3 (0.0);
146 Specular = vec3 (0.0);
392ac980 147 vec3 aPoint = thePoint.xyz / thePoint.w;
816d03ee 148 for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
392ac980 149 {
12381341 150 int aType = occLight_Type (anIndex);
151 if (aType == OccLightType_Direct)
392ac980 152 {
12381341 153 directionalLight (anIndex, theNormal, theView);
154 }
155 else if (aType == OccLightType_Point)
156 {
157 pointLight (anIndex, theNormal, theView, aPoint);
158 }
159 else if (aType == OccLightType_Spot)
160 {
816d03ee 161 spotLight (anIndex, theNormal, theView, aPoint);
392ac980 162 }
392ac980 163 }
12381341 164
c90e941f 165 vec4 aMaterialAmbient = gl_FrontFacing ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();
166 vec4 aMaterialDiffuse = gl_FrontFacing ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();
167 vec4 aMaterialSpecular = gl_FrontFacing ? occFrontMaterial_Specular() : occBackMaterial_Specular();
0e330c8c 168 vec4 aMaterialEmission = gl_FrontFacing ? occFrontMaterial_Emission() : occBackMaterial_Emission();
a1073ae2 169 vec3 aColor = Ambient * aMaterialAmbient.rgb
170 + Diffuse * aMaterialDiffuse.rgb
171 + Specular * aMaterialSpecular.rgb
172 + aMaterialEmission.rgb;
173 return vec4 (aColor, aMaterialDiffuse.a);
392ac980 174}
175
12381341 176//! Entry point to the Fragment Shader
392ac980 177void main()
178{
5495fa7e 179 // process clipping planes
180 for (int anIndex = 0; anIndex < occClipPlaneCount; ++anIndex)
181 {
182 vec4 aClipEquation = occClipPlaneEquations[anIndex];
89a929ea 183 if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)
5495fa7e 184 {
89a929ea 185 discard;
5495fa7e 186 }
187 }
188
b17e5bae 189 vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position);
190 occSetFragColor (aColor);
392ac980 191}