167 lines
4.5 KiB
Plaintext
167 lines
4.5 KiB
Plaintext
![]() |
/*
|
||
|
* This file is part of the Colobot: Gold Edition source code
|
||
|
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program 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 GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see http://gnu.org/licenses
|
||
|
*/
|
||
|
|
||
![]() |
// FRAGMENT SHADER - OBJECT RENDERER
|
||
![]() |
|
||
|
uniform vec2 uni_FogRange;
|
||
|
uniform vec3 uni_FogColor;
|
||
|
|
||
![]() |
uniform vec4 uni_AlbedoColor;
|
||
|
uniform sampler2D uni_AlbedoTexture;
|
||
|
uniform sampler2D uni_DetailTexture;
|
||
|
|
||
|
uniform float uni_Roughness;
|
||
|
uniform float uni_Metalness;
|
||
![]() |
uniform float uni_AOStrength;
|
||
![]() |
uniform sampler2D uni_MaterialTexture;
|
||
|
|
||
|
uniform vec3 uni_EmissiveColor;
|
||
|
uniform sampler2D uni_EmissiveTexture;
|
||
![]() |
|
||
![]() |
uniform bool uni_TriplanarMode;
|
||
|
uniform float uni_TriplanarScale;
|
||
![]() |
|
||
![]() |
uniform float uni_AlphaScissor;
|
||
![]() |
|
||
![]() |
uniform bool uni_Recolor;
|
||
|
uniform vec3 uni_RecolorFrom;
|
||
|
uniform vec3 uni_RecolorTo;
|
||
|
uniform float uni_RecolorThreshold;
|
||
|
|
||
![]() |
in VertexData
|
||
|
{
|
||
|
vec4 Color;
|
||
|
vec2 TexCoord0;
|
||
|
vec2 TexCoord1;
|
||
|
vec3 Normal;
|
||
![]() |
vec3 VertexCoord;
|
||
|
vec3 VertexNormal;
|
||
![]() |
vec3 Position;
|
||
|
vec3 ShadowCoords[4];
|
||
|
} data;
|
||
|
|
||
|
out vec4 out_FragColor;
|
||
|
|
||
![]() |
vec3 Triplanar(vec3 position, vec3 normal)
|
||
|
{
|
||
|
vec3 weights = normal * normal;
|
||
|
|
||
![]() |
vec3 sum = texture(uni_DetailTexture, position.yz).rgb * weights.x;
|
||
|
sum += texture(uni_DetailTexture, position.zx).rgb * weights.y;
|
||
|
sum += texture(uni_DetailTexture, position.xy).rgb * weights.z;
|
||
![]() |
|
||
|
return sum;
|
||
|
}
|
||
|
|
||
![]() |
// All components are in the range [0...1], including hue.
|
||
|
vec3 rgb2hsv(vec3 c)
|
||
|
{
|
||
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||
|
|
||
|
float d = q.x - min(q.w, q.y);
|
||
|
float e = 1.0e-10;
|
||
|
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||
|
}
|
||
|
|
||
|
// All components are in the range [0...1], including hue.
|
||
|
vec3 hsv2rgb(vec3 c)
|
||
|
{
|
||
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||
|
}
|
||
|
|
||
![]() |
void main()
|
||
|
{
|
||
![]() |
vec4 albedo = data.Color * uni_AlbedoColor;
|
||
![]() |
|
||
![]() |
vec4 texColor = texture(uni_AlbedoTexture, data.TexCoord0);
|
||
|
|
||
|
if (uni_Recolor)
|
||
|
{
|
||
|
vec3 hsv = rgb2hsv(texColor.rgb);
|
||
|
|
||
|
if (abs(hsv.x - uni_RecolorFrom.x) < uni_RecolorThreshold)
|
||
|
{
|
||
|
hsv += (uni_RecolorTo - uni_RecolorFrom);
|
||
|
|
||
|
if (hsv.x < 0.0) hsv.x += 1.0;
|
||
|
if (hsv.x > 1.0) hsv.x -= 1.0;
|
||
|
}
|
||
|
|
||
|
texColor.rgb = hsv2rgb(hsv);
|
||
|
}
|
||
|
|
||
|
albedo *= texColor;
|
||
![]() |
|
||
![]() |
vec3 dirty = vec3(0.0);
|
||
|
|
||
|
if (uni_TriplanarMode)
|
||
|
{
|
||
|
dirty = Triplanar(data.VertexCoord * uni_TriplanarScale, data.VertexNormal);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
![]() |
dirty = texture(uni_DetailTexture, data.TexCoord1).rgb;
|
||
![]() |
}
|
||
|
|
||
![]() |
albedo.rgb *= dirty;
|
||
|
|
||
|
vec3 color = albedo.rgb;
|
||
![]() |
float alpha = albedo.a;
|
||
![]() |
|
||
|
if (uni_Lighting)
|
||
|
{
|
||
|
float shadow = CalculateShadow(data.ShadowCoords);
|
||
|
|
||
|
shadow = mix(0.5, 1.0, shadow);
|
||
|
|
||
|
vec3 normal = mix(-data.Normal, data.Normal, float(gl_FrontFacing));
|
||
|
|
||
![]() |
vec3 emissive = uni_EmissiveColor * texture(uni_EmissiveTexture, data.TexCoord0).rgb;
|
||
|
|
||
|
vec3 params = texture(uni_MaterialTexture, data.TexCoord0).xyz;
|
||
![]() |
|
||
![]() |
float ambientOcclusion = 1.0 + uni_AOStrength * (params.r - 1.0);
|
||
![]() |
float roughness = uni_Roughness * params.g;
|
||
|
float metalness = uni_Metalness * params.b;
|
||
![]() |
|
||
![]() |
color = CalculateLighting(
|
||
|
data.Position,
|
||
|
normal,
|
||
|
color,
|
||
|
emissive,
|
||
|
shadow,
|
||
|
ambientOcclusion,
|
||
|
roughness,
|
||
|
metalness);
|
||
![]() |
}
|
||
|
|
||
![]() |
float dist = length(uni_CameraPosition - data.Position);
|
||
![]() |
float fogAmount = clamp((dist - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x), 0.0, 1.0);
|
||
|
|
||
|
color = mix(color, uni_FogColor, fogAmount);
|
||
|
|
||
![]() |
if (alpha < uni_AlphaScissor) discard;
|
||
![]() |
|
||
![]() |
out_FragColor = vec4(color, alpha);
|
||
![]() |
}
|