1 /*
2 Copyright (c) 2019-2022 Timur Gafarov
3 
4 Boost Software License - Version 1.0 - August 17th, 2003
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 */
27 module dagon.render.shaders.terrain;
28 
29 import std.stdio;
30 import std.math;
31 
32 import dlib.core.memory;
33 import dlib.core.ownership;
34 import dlib.math.vector;
35 import dlib.math.matrix;
36 import dlib.math.transformation;
37 import dlib.math.interpolation;
38 import dlib.image.color;
39 import dlib.text.str;
40 
41 import dagon.core.bindings;
42 import dagon.graphics.material;
43 import dagon.graphics.shader;
44 import dagon.graphics.state;
45 import dagon.graphics.texture;
46 import dagon.graphics.terrain;
47 
48 class TerrainGeometryShader: Shader
49 {
50     String vs, fs;
51 
52     this(Owner owner)
53     {
54         vs = Shader.load("data/__internal/shaders/Terrain/TerrainGeometry.vert.glsl");
55         fs = Shader.load("data/__internal/shaders/Terrain/TerrainGeometry.frag.glsl");
56 
57         auto prog = New!ShaderProgram(vs, fs, this);
58         super(prog, owner);
59     }
60 
61     ~this()
62     {
63         vs.free();
64         fs.free();
65     }
66 
67     override void bindParameters(GraphicsState* state)
68     {
69         Material mat = state.material;
70         
71         setParameter("modelViewMatrix", state.modelViewMatrix);
72         setParameter("projectionMatrix", state.projectionMatrix);
73         setParameter("normalMatrix", state.normalMatrix);
74         setParameter("viewMatrix", state.viewMatrix);
75         setParameter("invViewMatrix", state.invViewMatrix);
76         setParameter("prevModelViewMatrix", state.prevModelViewMatrix);
77         
78         setParameter("gbufferMask", 1.0f);
79         setParameter("blurMask", state.blurMask);
80         
81         super.bindParameters(state);
82     }
83 
84     override void unbindParameters(GraphicsState* state)
85     {
86         super.unbindParameters(state);
87     }
88 }
89 
90 class TerrainTextureLayerShader: Shader
91 {
92     String vs, fs;
93 
94     this(Owner owner)
95     {
96         vs = Shader.load("data/__internal/shaders/Terrain/TerrainTextureLayer.vert.glsl");
97         fs = Shader.load("data/__internal/shaders/Terrain/TerrainTextureLayer.frag.glsl");
98 
99         auto prog = New!ShaderProgram(vs, fs, this);
100         super(prog, owner);
101     }
102 
103     ~this()
104     {
105         vs.free();
106         fs.free();
107     }
108 
109     override void bindParameters(GraphicsState* state)
110     {
111         Material mat = state.material;
112         
113         setParameter("viewMatrix", state.viewMatrix);
114         setParameter("invViewMatrix", state.invViewMatrix);
115         setParameter("projectionMatrix", state.projectionMatrix);
116         setParameter("invProjectionMatrix", state.invProjectionMatrix);
117         setParameter("resolution", state.resolution);
118         setParameter("zNear", state.zNear);
119         setParameter("zFar", state.zFar);
120         
121         setParameter("opacity", mat.opacity);
122         setParameter("textureScale", mat.textureScale);
123         setParameter("clipThreshold", mat.alphaTestThreshold);
124         
125         // Texture 0 - normal buffer
126         glActiveTexture(GL_TEXTURE0);
127         glBindTexture(GL_TEXTURE_2D, state.normalTexture);
128         setParameter("terrainNormalBuffer", cast(int)0);
129 
130         // Texture 1 - texcoord buffer
131         glActiveTexture(GL_TEXTURE1);
132         glBindTexture(GL_TEXTURE_2D, state.texcoordTexture);
133         setParameter("terrainTexcoordBuffer", cast(int)1);
134         
135         // Texture 2 - mask
136         glActiveTexture(GL_TEXTURE2);
137         setParameter("maskTexture", cast(int)2);
138         setParameter("maskFactor", mat.maskFactor);
139         if (mat.maskTexture)
140         {
141             mat.maskTexture.bind();
142             setParameterSubroutine("layerMask", ShaderType.Fragment, "layerMaskTexture");
143         }
144         else
145         {
146             glBindTexture(GL_TEXTURE_2D, 0);
147             setParameterSubroutine("layerMask", ShaderType.Fragment, "layerMaskValue");
148         }
149         
150         // Diffuse
151         glActiveTexture(GL_TEXTURE3);
152         setParameter("diffuseTexture", cast(int)3);
153         setParameter("diffuseVector", mat.baseColorFactor);
154         if (mat.baseColorTexture)
155         {
156             mat.baseColorTexture.bind();
157             setParameterSubroutine("diffuse", ShaderType.Fragment, "diffuseColorTexture");
158         }
159         else
160         {
161             glBindTexture(GL_TEXTURE_2D, 0);
162             setParameterSubroutine("diffuse", ShaderType.Fragment, "diffuseColorValue");
163         }
164         
165         // Normal
166         glActiveTexture(GL_TEXTURE4);
167         setParameter("normalTexture", cast(int)4);
168         setParameter("normalVector", mat.normalFactor);
169         if (mat.normalTexture)
170         {
171             mat.normalTexture.bind();
172             setParameterSubroutine("normal", ShaderType.Fragment, "normalMap");
173             setParameter("generateTBN", cast(int)1);
174         }
175         else
176         {
177             glBindTexture(GL_TEXTURE_2D, 0);
178             setParameterSubroutine("normal", ShaderType.Fragment, "normalValue");
179             setParameter("generateTBN", cast(int)0);
180         }
181         
182         if (state.material.invertNormalY)
183             setParameter("normalYSign", -1.0f);
184         else
185             setParameter("normalYSign", 1.0f);
186 
187         // Height and parallax
188         int parallaxMethod = mat.parallaxMode;
189         if (parallaxMethod > ParallaxOcclusionMapping)
190             parallaxMethod = ParallaxOcclusionMapping;
191         if (parallaxMethod < 0)
192             parallaxMethod = 0;
193         
194         glActiveTexture(GL_TEXTURE5);
195         setParameter("heightTexture", cast(int)5);
196         setParameter("heightScalar", mat.heightFactor);
197         if (mat.heightTexture)
198         {
199             mat.heightTexture.bind();
200             setParameterSubroutine("height", ShaderType.Fragment, "heightMap");
201         }
202         else
203         {
204             glBindTexture(GL_TEXTURE_2D, 0);
205             setParameterSubroutine("height", ShaderType.Fragment, "heightValue");
206             parallaxMethod = ParallaxNone;
207         }
208         
209         if (parallaxMethod == ParallaxSimple)
210             setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxSimple");
211         else if (parallaxMethod == ParallaxOcclusionMapping)
212             setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxOcclusionMapping");
213         else
214             setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxNone");
215         
216         setParameter("parallaxScale", mat.parallaxScale);
217         setParameter("parallaxBias", mat.parallaxBias);
218         
219         // PBR
220         glActiveTexture(GL_TEXTURE6);
221         setParameter("roughnessMetallicTexture", cast(int)6);
222         setParameter("roughnessMetallicFactor", Vector4f(1.0f, mat.roughnessFactor, mat.metallicFactor, 0.0f));
223         if (mat.roughnessMetallicTexture)
224         {
225             mat.roughnessMetallicTexture.bind();
226             setParameterSubroutine("roughness", ShaderType.Fragment, "roughnessMap");
227             setParameterSubroutine("metallic", ShaderType.Fragment, "metallicMap");
228         }
229         else
230         {
231             glBindTexture(GL_TEXTURE_2D, 0);
232             setParameterSubroutine("roughness", ShaderType.Fragment, "roughnessValue");
233             setParameterSubroutine("metallic", ShaderType.Fragment, "metallicValue");
234         }
235         
236         // Emission
237         glActiveTexture(GL_TEXTURE7);
238         setParameter("emissionTexture", cast(int)7);
239         setParameter("emissionFactor", mat.emissionFactor);
240         if (mat.emissionTexture)
241         {
242             mat.emissionTexture.bind();
243             setParameterSubroutine("emission", ShaderType.Fragment, "emissionColorTexture");
244         }
245         else
246         {
247             glBindTexture(GL_TEXTURE_2D, 0);
248             setParameterSubroutine("emission", ShaderType.Fragment, "emissionColorValue");
249         }
250         setParameter("energy", mat.emissionEnergy);
251 
252         super.bindParameters(state);
253         
254         glActiveTexture(GL_TEXTURE0);
255     }
256 
257     override void unbindParameters(GraphicsState* state)
258     {
259         super.unbindParameters(state);
260         
261         glActiveTexture(GL_TEXTURE0);
262         glBindTexture(GL_TEXTURE_2D, 0);
263         
264         glActiveTexture(GL_TEXTURE1);
265         glBindTexture(GL_TEXTURE_2D, 0);
266         
267         glActiveTexture(GL_TEXTURE2);
268         glBindTexture(GL_TEXTURE_2D, 0);
269         
270         glActiveTexture(GL_TEXTURE3);
271         glBindTexture(GL_TEXTURE_2D, 0);
272         
273         glActiveTexture(GL_TEXTURE4);
274         glBindTexture(GL_TEXTURE_2D, 0);
275         
276         glActiveTexture(GL_TEXTURE5);
277         glBindTexture(GL_TEXTURE_2D, 0);
278         
279         glActiveTexture(GL_TEXTURE6);
280         glBindTexture(GL_TEXTURE_2D, 0);
281         
282         glActiveTexture(GL_TEXTURE7);
283         glBindTexture(GL_TEXTURE_2D, 0);
284         
285         glActiveTexture(GL_TEXTURE0);
286     }
287 }