1/* Beta-0.4.7: MOSAIC default displacement shader for Blender integration */
2
3#define DISPLACE_UTILITIES 1
4#include "MOSAICfunctions.h"
5
6displacement
7MOSAICdisplace(
8    uniform float Mid                   = 0.5;
9    uniform float DispFac               = 1.0;
10	uniform float GlobUF_X0[2]			= {0, 0};
11	uniform string DispUS_X0[10]			= {"", "", "", "", "", "", "", "", "", ""};
12	varying float DispVF_X0[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
13	varying float DispVF_X1[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
14	varying float DispVF_X2[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
15	varying float DispVF_X3[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
16	varying float DispVF_X4[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
17	varying float DispVF_X5[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
18	varying float DispVF_X6[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
19	varying float DispVF_X7[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
20	varying float DispVF_X8[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
21	varying float DispVF_X9[27]			= {16.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0};
22 varying float                       s1 = 0, t1 = 0, s2 = 0, t2 = 0, s3 = 0, t3 = 0, s4 = 0, t4 = 0, s5 = 0, t5 = 0, s6 = 0, t6 = 0, s7 = 0, t7 = 0, s8 = 0, t8 = 0; // Texture uv layers
23    varying float                       v0 = 1, v1 = 1, v2 = 1, v3 = 1, v4 = 1, v5 = 1, v6 = 1, v7 = 1, v8 = 1, v9 = 1; // Vertex groups
24    varying float Ms                    = -1;   //Material index number from mesh (for multipass and layered shading)
25    uniform string Mx                   = "";   //TexFace image names from mesh (if enabled in exporter)
26    output varying point __displacein   = 0;    // Input parameter for layered shading
27    output varying point __displaceout  = 0;)   // Output parameter for layered shading
28{
29    // Only shade a surface element belonging to the current material index unless disabled
30    if (GlobUF_X0[MAT_UF_SETMODE] == 0 || Ms == -1 || GlobUF_X0[MAT_UF_SETINDEX] == Ms)
31    {
32        //// Lets setup general purpose variables...
33        uniform string Name             = "";
34        uniform float                   a = 0, i = 0, channels = 3, isDisp = 0, isNor = 0;
35        varying float                   sAdj, tAdj, p1, p2, p3, p4, p5, p6, p7, mask = 1;
36        varying color                   Cp1, Cp2;
37        float stLayers[16]              = {s, t, s1, t1, s2, t2, s3, t3, s4, t4, s5, t5, s6, t6, s7, t7};
38        float vGroups[10]               = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9};
39        normal Un                       = N;
40
41        //// Lets grab any user attributes from RIB
42        float displacelayer             = 0;
43        attribute("user:displace_layer", displacelayer);
44
45        // These are the material channels defined in Blender's material system per texture for blending
46        color                           Nor = color(0), NorFac = color(0), Disp = color(0);
47
48        //// Cycle through all texture layers and blend to each material channels
49        for (i = 0; i < GLOB_TEX_CHANNELS; i += 1)
50        {
51            Name                        = DispUS_X0[i];
52
53            // Make sure theres a texture before we process it!
54            if (Name != "")
55            {
56                // Lets initialize shared variables...
57                float disp_paras[DISP_VF_PARALEN];
58                uniform float tex_channels  = 0;
59                textureinfo(Name, "channels", tex_channels);
60
61                // Lets load up a temporary array of the current textures parameters
62                for (a = 0; a < DISP_VF_PARALEN; a += 1)
63                {
64                    if (i == 0)         disp_paras[a] = DispVF_X0[a];
65                    else if (i == 1)    disp_paras[a] = DispVF_X1[a];
66                    else if (i == 2)    disp_paras[a] = DispVF_X2[a];
67                    else if (i == 3)    disp_paras[a] = DispVF_X3[a];
68                    else if (i == 4)    disp_paras[a] = DispVF_X4[a];
69                    else if (i == 5)    disp_paras[a] = DispVF_X5[a];
70                    else if (i == 6)    disp_paras[a] = DispVF_X6[a];
71                    else if (i == 7)    disp_paras[a] = DispVF_X7[a];
72                    else if (i == 8)    disp_paras[a] = DispVF_X8[a];
73                    else if (i == 9)    disp_paras[a] = DispVF_X9[a];
74                }
75
76                float stLayer           = disp_paras[DISP_VF_STLAYER];
77                float stCoor            = disp_paras[DISP_VF_STCOOR];
78                float gIndex            = disp_paras[DISP_VF_VERTGRP];
79                float vertGrp           = 1;
80                float midLevel          = Mid;
81
82                // Use vertex group value if specified...
83                if (gIndex != -1 && gIndex < 10)
84                    vertGrp             = vGroups[gIndex];
85
86                // Use mid level value if specified...
87                if (disp_paras[DISP_VF_MID] != -1)
88                    midLevel            = disp_paras[DISP_VF_MID];
89
90                // Adjust offset and size of st coordinates...
91                p1                      = disp_paras[DISP_VF_OFSX];
92                p2                      = disp_paras[DISP_VF_OFSY];
93                p3                      = disp_paras[DISP_VF_SIZEX];
94                p4                      = disp_paras[DISP_VF_SIZEY];
95                // Is this texture using "sticky" coordinates?
96                if (stCoor == 256)
97                {
98                    sAdj                = s8;
99                    tAdj                = t8;
100                }
101                // Is this texture using a UV layer?
102                else if (stCoor == 16)
103                {
104                    sAdj                = stLayers[stLayer*2];
105                    tAdj                = stLayers[stLayer*2+1];
106                }
107                // If using a coordinate mode not supported just use standard st
108                else
109                {
110                    sAdj                = s;
111                    tAdj                = t;
112                }
113                // Rotate and mirror texture?
114                if (disp_paras[DISP_VF_ROT90] != 0)
115                {
116                    uniform float rot   = radians(-90);
117                    sAdj                -= 0.5;
118                    tAdj                -= 0.5;
119                    p1                  = (cos(rot)*sAdj-sin(rot)*tAdj)+0.5;
120                    p2                  = (sin(rot)*sAdj+cos(rot)*tAdj)+0.5;
121                    sAdj                = 1-p1;
122                    tAdj                = p2;
123                }
124                stAdjust(sAdj, tAdj, p1, p2, p3, p4);
125
126                // Get and adjust color value from texture...
127                uniform float alpha_channel = tex_channels-1;
128                p1                      = disp_paras[DISP_VF_FILTER];
129                if (tex_channels < 3)
130                    Cp1                 = color(float texture(Name[0], sAdj, tAdj, "blur", p1));
131                else
132                    Cp1                 = color texture(Name, sAdj, tAdj, "blur", p1);
133                p6                      = comp(ctransform("hsv", Cp1), 2);
134
135                // Get and adjust alpha value from texture...
136                if (disp_paras[DISP_VF_USEALPHA] != 0 && (tex_channels == 2 || tex_channels == 4))
137                    p1                  = float texture(Name[alpha_channel], sAdj, tAdj, "blur", p1, "fill", 1);
138                else
139                    p1                  = 1;
140                if (disp_paras[DISP_VF_NEGALPHA] != 0)
141                    p1                  = 1-p1;
142                if (disp_paras[DISP_VF_CALCALPHA] != 0)
143                    p1                  *= p6;
144                if (disp_paras[TEX_VF_STENCIL] != 0)
145                    mask                *= p1;
146                p1                      *= mask;
147
148                // Alter texture colors before blending...
149                Cp2                 = color(disp_paras[DISP_VF_TEXR], disp_paras[DISP_VF_TEXG], disp_paras[DISP_VF_TEXB]);
150                Cp1                 *= Cp2;
151                if (disp_paras[DISP_VF_CONTR] != 1)
152                    Cp1             = (Cp1-0.5*Cp2)*disp_paras[DISP_VF_CONTR]+0.5*Cp2;
153                if (disp_paras[DISP_VF_BRIGHT] != 1)
154                    Cp1             = clamp(Cp1+Cp2*(disp_paras[DISP_VF_BRIGHT]-1), color(0), color(2));
155                if (disp_paras[DISP_VF_NEG] != 0)
156                    Cp1                 = color(1)-Cp1;
157
158                // Lets start blending texture according to assigned channel
159                p2                      = disp_paras[DISP_VF_BLENDMODE];
160                p3                      = disp_paras[DISP_VF_NORFAC]*p1;
161                p4                      = disp_paras[DISP_VF_DISPFAC]*p1;
162                if (disp_paras[DISP_VF_ISNOR] != 0)
163                {
164                    isNor               = 1;
165                    p7                  = disp_paras[DISP_VF_ISNOR];
166                    Nor                 = colorblend(Nor, Cp1, 7, 1, p7);
167                    NorFac              = colorblend(NorFac, color(p7), p2, p3, p7);
168                }
169                if (disp_paras[DISP_VF_ISDISP] != 0)
170                {
171                    isDisp              = 1;
172                    p7                  = disp_paras[DISP_VF_ISDISP];
173                    Disp                = colorblend(Disp, (Cp1-midLevel)*vertGrp, p2, p4, p7);
174                }
175            }
176        }
177
178        //Are we using a displacement texture map?
179        if (isDisp != 0)
180        {
181            float Amp                   = comp(ctransform("hsv", Disp), 2)*DispFac;
182            P                           += normalize(Un)*Amp;
183            Un                          = calculatenormal(P);
184        }
185        //Are we using a normal texture map?
186        if (isNor != 0)
187        {
188            normal Nref                 = normalize(Un);
189            vector dPds                 = normalize(Deriv(P, s));
190            vector dPdt                 = normalize(Deriv(P, t));
191            vector Nvector              = vector(Nor)*2-vector(1);
192            vector Ntransformed         = vector(comp(Nvector, 0)*comp(dPds, 0)+comp(Nvector, 1)*comp(dPdt, 0)+comp(Nvector, 2)*comp(Nref, 0),
193                                                 comp(Nvector, 0)*comp(dPds, 1)+comp(Nvector, 1)*comp(dPdt, 1)+comp(Nvector, 2)*comp(Nref, 1),
194                                                 comp(Nvector, 0)*comp(dPds, 2)+comp(Nvector, 1)*comp(dPdt, 2)+comp(Nvector, 2)*comp(Nref, 2));
195            N                           = mix(Un, normal normalize(Ntransformed), comp(ctransform("hsv", NorFac), 2)/25.0);
196        }
197        else N                          = Un;
198    }
199    //// If multipass material mode clear surface elements not in this material set
200    else if (GlobUF_X0[MAT_UF_SETMODE] == 1)
201    {
202        N                               = 0;
203        P                               = 0;
204    }
205}
206