I'm making 2 shaders (a .frag file) and i get a error message saying "ERROR: 0:83: '' : syntax error: incorrect preprocessor directive". and when i press ok it doesn't show and make models not appear and i think it make other shaders not work. Weirdly only images show but not the models. why does this happen?
Shader 1:
#version 120
#define PI 3.14159265
varying vec3 position;
varying vec3 normal;
varying vec4 color;
varying vec2 textureCoord;
varying vec2 imageCoord;
uniform float time;
uniform float beat;
uniform vec2 resolution;
uniform vec2 textureSize;
uniform vec2 imageSize;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 perspectiveMatrix;
uniform mat4 textureMatrix;
uniform sampler2D sampler0;
uniform sampler2D sampler1;
vec2 img2tex( vec2 v ) { return v / textureSize * imageSize; }
float amount = 0.3;
float random(float x)
{
return fract(sin(x) * 10000.);
}
float noise(vec2 p)
{
return random(p.x + p.y * 10000.);
}
vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }
float smoothNoise(vec2 p)
{
vec2 interp = smoothstep(0., 1., fract(p));
float s = mix(noise(sw(p)), noise(se(p)), interp.x);
float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
return mix(s, n, interp.y);
}
float fractalNoise(vec2 p)
{
float x = 0.;
x += smoothNoise(p );
x += smoothNoise(p * 2. ) / 2.;
x += smoothNoise(p * 4. ) / 4.;
x += smoothNoise(p * 8. ) / 8.;
x += smoothNoise(p * 16.) / 16.;
x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
return x;
}
float movingNoise(vec2 p)
{
float x = fractalNoise(p + time);
float y = fractalNoise(p - time);
return fractalNoise(p + vec2(x, y));
}
float nestedNoise(vec2 p)
{
float x = movingNoise(p);
float y = movingNoise(p + 100.);
return movingNoise(p + vec2(x, y));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / imageSize.xy;
float n = nestedNoise(uv * 6.) * 1.0;
float offset = mix(0.0, 2.0, amount);
#if NORM_FOCUS
vec2 offsetVector = normalize(vec2(0.5, 0.5) - uv) * (n * offset);
#else
vec2 offsetVector = (vec2(0.5, 0.5) - uv) * (n * offset);
#endif
fragColor = texture2D(sampler0, img2tex(uv) + offsetVector);
}
void main()
{
mainImage(gl_FragColor.rgba, gl_FragCoord.xy);
}
Shader 2:
#version 120
#define PI 3.14159265
varying vec3 position;
varying vec3 normal;
varying vec4 color;
varying vec2 textureCoord;
varying vec2 imageCoord;
uniform float time;
uniform float beat;
uniform vec2 resolution;
uniform vec2 textureSize;
uniform vec2 imageSize;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 perspectiveMatrix;
uniform mat4 textureMatrix;
uniform sampler2D sampler0;
uniform sampler2D sampler1;
vec2 img2tex( vec2 v ) { return v / textureSize * imageSize; }
float amount = 0.9;
float random(float x)
{
return fract(sin(x) * 10000.);
}
float noise(vec2 p)
{
return random(p.x + p.y * 10000.);
}
vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }
float smoothNoise(vec2 p)
{
vec2 interp = smoothstep(0., 1., fract(p));
float s = mix(noise(sw(p)), noise(se(p)), interp.x);
float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
return mix(s, n, interp.y);
}
float fractalNoise(vec2 p)
{
float x = 0.;
x += smoothNoise(p );
x += smoothNoise(p * 2. ) / 2.;
x += smoothNoise(p * 4. ) / 4.;
x += smoothNoise(p * 8. ) / 8.;
x += smoothNoise(p * 16.) / 16.;
x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
return x;
}
float movingNoise(vec2 p)
{
float x = fractalNoise(p + time);
float y = fractalNoise(p - time);
return fractalNoise(p + vec2(x, y));
}
float nestedNoise(vec2 p)
{
float x = movingNoise(p);
float y = movingNoise(p + 100.);
return movingNoise(p + vec2(x, y));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / imageSize.xy;
float n = nestedNoise(uv * 6.) * 1.0;
float offset = mix(0.0, 2.0, amount);
#if NORM_FOCUS
vec2 offsetVector = normalize(vec2(0.5, 0.5) - uv) * (n * offset);
#else
vec2 offsetVector = (vec2(0.5, 0.5) - uv) * (n * offset);
#endif
fragColor = texture2D(sampler0, img2tex(uv) + offsetVector);
}
void main()
{
mainImage(gl_FragColor.rgba, gl_FragCoord.xy);
}
i expected it to work but it didn't.
You have this in your first fragment shader:
#if NORM_FOCUS // line 83
vec2 offsetVector = normalize(vec2(0.5, 0.5) - uv) * (n * offset);
#else
vec2 offsetVector = (vec2(0.5, 0.5) - uv) * (n * offset);
#endif
In the absence of any other code I'm not seeing NORM_FOCUS being #defined anywhere, which runs afoul of the following (GLSL 1.20 Specification, page 7):
Expressions following #if and #elif are restricted to expressions operating on literal integer constants, plus identifiers consumed by the defined operator.
So either #define NORM_FOCUS to something or switch to #ifdef NORM_FOCUS.
Related
I want to create a similar background with a shader to these images:
:
These are just blurred blobs with colors, distributed across the whole page:
Here's my current progress: https://codesandbox.io/s/lucid-bas-wvlzl9?file=/src/components/Background/Background.tsx
Vertex shader:
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
Fragment shader:
precision highp float;
uniform float uTime;
uniform float uAmplitude;
uniform float uFrequency;
varying vec2 vUv;
uniform vec2 uResolution;
vec4 Sphere(vec2 position, float radius)
{
// float dist = radius / distance(vUv, position);
// float strength = 0.01 / distance(vUv, position);
float strength = 0.1 / distance(vec2(vUv.x, (vUv.y - 0.5) * 8. + 0.5), vec2(0.));
return vec4(strength * strength);
}
void main()
{
vec2 uv = vUv;
vec4 pixel = vec4(0.0, 0.0, 0.0, 0.0);
vec2 positions[4];
positions[0] = vec2(.5, .5);
// positions[1] = vec2(sin(uTime * 3.0) * 0.5, (cos(uTime * 1.3) * 0.6) + vUv.y);
// positions[2] = vec2(sin(uTime * 2.1) * 0.1, (cos(uTime * 1.9) * 0.8) + vUv.y);
// positions[3] = vec2(sin(uTime * 1.1) * 1.1, (cos(uTime * 2.6) * 0.7) + vUv.y);
for (int i = 0; i < 2; i++)
pixel += Sphere(positions[i], 0.22);
pixel = pixel * pixel;
gl_FragColor = pixel;
}
For each blob, you can multiply it's color by a a noise function and then a 2D gaussian curve centered in a random point. Then add all the blobs together. I only added the ones of the adjacent cells to make it scrollable and the numbers in the for loops might be increased for bigger blobs.
here is my code :
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
const float blobSize = 0.125;
const float cellSize = .75;
const float noiseScale = .375;
const float background = .125;
const float blobsLuminosity = .75;
const float blobsSaturation = .5;
vec2 random2(vec2 st){
st = vec2( dot(st,vec2(127.1,311.7)),
dot(st,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(st)*43758.5453123);
}
// Gradient Noise by Inigo Quilez - iq/2013
// https://www.shadertoy.com/view/XdXGW8
float noise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
vec2 u = f*f*(3.0-2.0*f);
return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y)*.5+.5;
}
float gaussFunction(vec2 st, vec2 p, float r) {
return exp(-dot(st-p, st-p)/2./r/r);
}
// Function from IƱigo Quiles
// https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb( in vec3 c ){
vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
6.0)-3.0)-1.0,
0.0,
1.0 );
rgb = rgb*rgb*(3.0-2.0*rgb);
return c.z * mix( vec3(1.0), rgb, c.y);
}
vec3 hash32(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
p3 += dot(p3, p3.yxz+33.33);
return fract((p3.xxy+p3.yzz)*p3.zyx);
}
vec3 blobs(vec2 st){
vec2 i = floor(st/cellSize);
vec3 c = vec3(0.);
for(int x = -1; x <= 1; x++)
for(int y = -1; y <= 1; y++){
vec3 h = hash32(i+vec2(x, y));
c += hsb2rgb(vec3(h.z, blobsSaturation, blobsLuminosity)) * gaussFunction(st/cellSize, i + vec2(x, y) + h.xy, blobSize) * smoothstep(0., 1., noise(noiseScale*st/cellSize / blobSize));
//c += hsb2rgb(vec3(h.z, blobsSaturation, blobsLuminosity)) * gaussFunction(st/cellSize, i + vec2(x, y) + h.xy, blobSize) * noise(noiseScale*st/cellSize / blobSize);
}
return c + vec3(background);
}
float map(float x, float a, float b, float c, float d){
return (x-a)/(b-a)*(d-c)+c;
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color = vec3(0.0);
color = vec3(blobs(st - u_mouse/u_resolution.xy*4.));
gl_FragColor = vec4(color,1.0);
}
made in this shader editor.
I am working on shadows for a Minecraft shader, and im stuck at trying to resolve the following error.
21:51:27.725
[Shaders] Error compiling fragment shader: /shaders/composite.fsh
21:51:27.726
[Shaders] Shader info log: /shaders/composite.fsh
0(84) : error C7623: implicit narrowing of type from "vec4" to "float"
21:51:27.727
[Shaders] Error linking program: 10 (composite)
I know the error is caused by incompatible types, but I'm still not sure how to solve it, so any help is appreciated.
#version 120
const int shadowMapResolution = 2048;
const float shadowDistance = 128;
const float shadowMapBias = 0.85;
const int noiseTextureResolution = 256;
#define SHADOWMAP_BIAS 0.85
uniform sampler2D colortex0;
uniform sampler2D shadowtex0;
uniform sampler2D shadowcolor0;
uniform sampler2D depthtex1;
uniform sampler2D noisetex;
uniform vec3 cameraPosition;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferModelView;
uniform mat4 shadowProjection;
uniform mat4 gbufferProjection;
uniform mat4 gbufferProjectionInverse;
uniform mat4 shadowModelView;
uniform float viewWidth;
uniform float viewHeight;
varying vec4 texcoord;
float depth = 0.5;
vec4 getCameraPosition(in vec2 coord)
{
float getdepth = depth;
vec4 positionNdcSpace = vec4(coord.s * 2.0 - 1.0, coord.t * 2.0 - 1.0, 2.0 * getdepth - 1.0, 1.0);
vec4 positionCameraSpace = gbufferProjectionInverse * positionNdcSpace;
return positionCameraSpace / positionCameraSpace.w;
}
vec4 getWorldSpacePosition(in vec2 coord)
{
vec4 cameraPos = getCameraPosition(coord);
vec4 worldPos = gbufferModelViewInverse * cameraPos;
worldPos.xyz += cameraPosition;
return worldPos;
}
vec3 getShadowSpacePosition(in vec2 coord)
{
vec4 worldSpacePos = getWorldSpacePosition(coord);
worldSpacePos.xyz -= cameraPosition;
vec4 shadowSpacePos = shadowModelView * worldSpacePos;
shadowSpacePos = shadowProjection * shadowSpacePos;
return shadowSpacePos.xyz * 0.5 + 0.5;
}
mat2 getRotationMatrix(in vec2 coord)
{
float rotationAmount = texture2D(
noisetex,
coord * vec2(
viewWidth / noiseTextureResolution,
viewHeight / noiseTextureResolution
)
).r;
return mat2(
cos(rotationAmount), -sin(rotationAmount),
sin(rotationAmount), cos(rotationAmount)
);
}
vec3 getShadows(in vec2 coord)
{
vec3 shadowCoord = getShadowSpacePosition(coord);
mat2 rotationMatrix = getRotationMatrix(coord);
vec3 shadowCol = vec3(0.0);
for (int i = 0; i < 32; i++)
{
vec2 offset = vec2(32 / shadowMapResolution);
offset = rotationMatrix * offset;
float shadowMapSample = texture2D(shadowtex0, shadowCoord.st + offset);
float visibility = step(shadowCoord.z - shadowMapSample, 0.001);
vec3 dayCol = vec3(1.0);
vec3 colorSample = texture2D(shadowcolor0, shadowCoord.st + offset).rgb;
shadowCol += mix(colorSample, dayCol, visibility);
}
return vec3(shadowCol) / 32;
}
vec3 calculateLighting(in vec3 color)
{
vec3 sunLight = getShadows(texcoord.st);
vec3 ambientLight = vec3(0.5, 0.7, 1.0) * 0.5;
return color * (sunLight + ambientLight);
}
void main()
{
depth = texture2D(depthtex1, texcoord.st).r;
vec3 color = texture2D(colortex0, texcoord.st).rbg;
color = calculateLighting(color);
gl_FragData[0] = vec4(color, 1.0);
gl_FragData[1] = vec4(depth);
}
The problem is that texture2D returns a vec4, but you are treating as a float. Read the red component instead
float shadowMapSample = texture2D(shadowtex0, shadowCoord.st + offset).r;
When I implemented SSR I encountered the problem of artifacts. Below I present the code and screenshots.
Fragment SSR shader:
#version 330 core
uniform sampler2D normalMap; // in view space
uniform sampler2D colorMap;
uniform sampler2D reflectionStrengthMap;
uniform sampler2D positionMap; // in view space
uniform mat4 projection;
uniform vec3 skyColor = vec3(0.1, 0, 0.5);
in vec2 texCoord;
layout (location = 0) out vec4 fragColor;
const int binarySearchCount = 10;
const int rayMarchCount = 30;
const float step = 0.05;
const float LLimiter = 0.2;
const float minRayStep = 0.2;
vec3 getPosition(in vec2 texCoord) {
return texture(positionMap, texCoord).xyz;
}
vec2 binarySearch(inout vec3 dir, inout vec3 hitCoord, inout float dDepth) {
float depth;
vec4 projectedCoord;
for(int i = 0; i < binarySearchCount; i++) {
projectedCoord = projection * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
depth = getPosition(projectedCoord.xy).z;
dDepth = hitCoord.z - depth;
dir *= 0.5;
if(dDepth > 0.0)
hitCoord += dir;
else
hitCoord -= dir;
}
projectedCoord = projection * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
return vec2(projectedCoord.xy);
}
vec2 rayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) {
dir *= step;
for (int i = 0; i < rayMarchCount; i++) {
hitCoord += dir;
vec4 projectedCoord = projection * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
float depth = getPosition(projectedCoord.xy).z;
dDepth = hitCoord.z - depth;
if((dir.z - dDepth) < 1.2 && dDepth <= 0.0) return binarySearch(dir, hitCoord, dDepth);
}
return vec2(-1.0);
}
void main() {
float reflectionStrength = texture(reflectionStrengthMap, texCoord).r;
if (reflectionStrength == 0) {
fragColor = texture(colorMap, texCoord);
return;
}
vec3 normal = texture(normalMap, texCoord).xyz;
vec3 viewPos = getPosition(texCoord);
// Reflection vector
vec3 reflected = normalize(reflect(normalize(viewPos), normalize(normal)));
// Ray cast
vec3 hitPos = viewPos;
float dDepth;
vec2 coords = rayCast(reflected * max(-viewPos.z, minRayStep), hitPos, dDepth);
float L = length(getPosition(coords) - viewPos);
L = clamp(L * LLimiter, 0, 1);
float error = 1 - L;
vec3 color = texture(colorMap, coords.xy).rgb * error;
if (coords.xy != vec2(-1.0)) {
fragColor = mix(texture(colorMap, texCoord), vec4(color, 1.0), reflectionStrength);
return;
}
fragColor = mix(texture(colorMap, texCoord), vec4(skyColor, 1.0), reflectionStrength);
}
Result without blackout (without * error):
Result with blackout:
Note: blue is filled specifically to see artifacts
And one more question, what is the best way to add fresnel without harming scene?
I want to generate a OBJ file from a code, which using GLSL file to generate mesh, now I can get the vertex information from the code, but how can I extract the triangle information from the .geom.glsl file and export it into a OBJ file?
Also, is there any helper function do to so? if not, how should I write the code to get the points and triangle information from the geom.glsl file?
Here attached the geom.glsl:
#version 400 core
#extension GL_EXT_geometry_shader4 : enable
layout(lines, invocations = 1) in;
layout(triangle_strip, max_vertices = 100) out;
uniform mat4 matLightView;
uniform mat4 matViewProjection;
uniform vec3 lightPos;
uniform vec3 camPos;
uniform int isExplicit;
in vec4 VertPosition[];
in vec4 VertColor[];
in vec3 VertNormal[];
in vec3 VertTexture[];
in float VertLengthTotal[];
in float VertLengthFromBeginning[];
out vec3 GeomNormal;
out vec2 GeomTexCoords;
out float GeomDiffuse;
out float GeomThickness;
out vec4 texCoordA;
out vec4 texCoordB;
const float PI2 = 2 * 3.141592654;
void main()
{
// for(int i=0; i<gl_VerticesIn-1; ++i)
for (int i = 0; i<gl_in.length ()-1; ++i)
{
//Reading Data
vec4 posS = VertPosition[i];
vec4 posT = VertPosition[i+1];
vec3 vS = VertColor[i].xyz;
vec3 vT = VertColor[i+1].xyz;
vec3 tS = VertTexture[i].xyz;
vec3 tT = VertTexture[i+1].xyz;
float thickS = VertColor[i].w;
float thickT = VertColor[i+1].w;
//Computing
vec3 v11 = normalize(vS);
vec3 v12 = normalize(cross(vS, tS));
vec3 v21 = normalize(vT);
vec3 v22 = normalize(cross(vT, tT));
float rS = max(0.0001, thickS);
float rT = max(0.0001, thickT);
int pS = 10;
int pT = 10;
int forMax = 16;
//Light Pos
vec4 lPos = normalize(vec4(-lightPos.x, -lightPos.y, -lightPos.z, 1));
vec3 L = normalize(lPos.xyz);
for(int k=0; k<=forMax; ++k)
{
float angle = k * (PI2 / forMax);
vec3 newPS = posS.xyz + (v11 * sin(angle) + v12 * cos(angle)) * rS;
vec3 newPT = posT.xyz + (v21 * sin(angle) + v22 * cos(angle)) * rT;
float scale = 1.0f;
float texX = float(k) / float(forMax);
float edgeLength = length(posS - posT);
float sTexY = (VertLengthFromBeginning[i] * scale);
float tTexY = (VertLengthFromBeginning[i+1] * scale);
//Source Vertex
vec3 N = normalize(posS.xyz - newPS);
texCoordB = matLightView * vec4(newPS, 1);
GeomNormal = N;
GeomThickness = rS;
GeomDiffuse = rS < 0.0005 ? 0.0f : max(dot(N, L), 0.0);
GeomTexCoords = vec2(texX, sTexY);
gl_Position = matViewProjection * vec4(newPS, 1);
EmitVertex();
//Target Vertex
N = normalize(posT.xyz - newPT);
texCoordB = matLightView * vec4(newPT, 1);
GeomNormal = N;
GeomThickness = rT;
GeomDiffuse = rT < 0.0005 ? 0.0f : max(dot(N, L), 0.0);
GeomTexCoords = vec2(texX, tTexY);
gl_Position = matViewProjection * vec4(newPT, 1);
EmitVertex();
}
}
EndPrimitive();
}
And the vert.glsl:
#version 400 core
#define VERT_POSITION 0
#define VERT_NORMAL 1
#define VERT_COLOR 2
#define VERT_TEXTURE 3
layout(location = VERT_POSITION) in vec4 Position;
layout(location = VERT_NORMAL) in vec4 Normal;
layout(location = VERT_COLOR) in vec4 Color;
layout(location = VERT_TEXTURE) in vec4 Texture;
out vec4 VertPosition;
out vec3 VertNormal;
out vec3 VertTexture;
out vec4 VertColor;
out float VertLengthFromBeginning;
out float VertLengthTotal;
uniform mat4 matModel;
void main()
{
VertPosition = matModel * Position;
VertNormal = Normal.xyz; // Direction
VertColor = Color; // V from PTF, VertColor.w = thick
VertTexture = Texture.xyz; // Tangent
VertLengthFromBeginning = Normal.w; // Global Texture Coordinates
VertLengthTotal = Texture.w; // total length of chain
}
Lots of Thanks!!
I have been writing a shading language that is meant to simplify writing GLSL. Because of this, I can't really rely on line numbers given by the GLSL compiler. I therefore can't find what this error is trying to say. What does it mean first of all, and then how can I fix it?
Error code:
0:8(18): error: syntax error, unexpected NEW_IDENTIFIER, expecting '{'
I believe that this just means there is a syntax error with the generated GLSL, but I can't find one. What does this error message actually mean?
-- EDIT --
Sorry for not providing code, I wanted to know what the error meant so I could provide the relevant areas of code.
Generated vertex shader:
#version 120
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
attribute vec3 tangent;
varying vec2 fragTexCoords;
varying vec3 worldPos;
varying vec4 shadowMapCoords;
varying mat3 tbnMatrix;
uniform mat4 modelMatrix;
uniform mat4 MVPMatrix;
uniform mat4 lightMatrix;
void main() {
gl_Position = MVPMatrix * vec4(position, 1);
fragTexCoords = texCoord;
shadowMapCoords = lightMatrix * vec4(position, 1);
worldPos = (modelMatrix * vec4(position, 1)).xyz;
vec3 n = normalize((modelMatrix * vec4(normal, 0)).xyz);
vec3 t = normalize((modelMatrix * vec4(tangent, 0)).xyz);
t = normalize(t - dot(t, n) * n);
vec3 biTangent = cross(t, n);
tbnMatrix = mat3(t, biTangent, n);
}
And the generated fragment shader:
#version 120
varying vec2 fragTexCoords;
varying vec3 worldPos;
varying vec4 shadowMapCoords;
varying mat3 tbnMatrix;
uniform Material material;
uniform Light light;
uniform vec3 eyePos;
uniform sampler2D shadowMap;
uniform float shadowVarianceMin;
uniform float shadowLightBleedReduction;
bool inRange(float value) {
return value >= 0 && value <= 1;
}
float linStep(float low, float high, float v) {
return clamp((v - low) / (high - low), 0, 1);
}
vec2 calcParallaxTexCoords(sampler2D dispMap, mat3 tbnMatrix, vec3 directionToEye, vec2 texCoords, float scale, float bias) {
return texCoords.xy + (directionToEye * tbnMatrix).xy * (texture2D(dispMap, texCoords.xy).r * scale + bias);
}
float sampleShadowMap(sampler2D shadowMap, vec2 coords, float compare) {
return step(compare, texture2D(shadowMap, coords.xy).r);
}
float sampleVarianceShadowMap(sampler2D shadowMap, vec2 coords, float compare, float varianceMin, float lightBleedReduction) {
vec2 moments = texture2D(shadowMap, coords.xy).xy;
float p = step(compare, moments.x);
float variance = max(moments.y - moments.x * moments.x, varianceMin);
float d = compare - moments.x;
float pMax = linStep(lightBleedReduction, 1, variance / (variance + d * d));
return min(max(p, pMax), 1);
}
struct Light {
vec3 color;
float intensity;
vec3 direction;
};
struct Material {
float roughness;
float fresnelReflectance;
sampler2D diffuseTexture;
sampler2D normalMap;
sampler2D dispMap;
float dispMapScale;
float dispMapBias;
};
vec3 calcLight(Light light, Material material, vec3 surfaceNormal, vec3 eyePos, vec3 diffuseColor, vec3 specularColor) {
vec3 halfVector = normalize(light.direction + eyePos);
float NdotL = clamp(dot(surfaceNormal, light.direction), 0.0, 1.0);
float NdotH = clamp(dot(surfaceNormal, halfVector), 0.0, 1.0);
float NdotV = clamp(dot(surfaceNormal, eyePos), 0.0, 1.0);
float VdotH = clamp(dot(eyePos, halfVector), 0.0, 1.0);
float rSq = material.roughness * material.roughness;
// ----- Fresnel term -----
float fresnel = pow(1 - VdotH, 5.0);
fresnel *= 1 - material.fresnelReflectance;
fresnel += material.fresnelReflectance;
// ----- Geometric attenuation term -----
float geoNum = 2.0 * NdotV;
float geoB = (geoNum * NdotV) / VdotH;
float geoC = (geoNum * NdotL) / VdotH;
float geo = min(1.0, min(geoB, geoC));
// ----- Roughness term -----
float roughnessA = rSq * pow(NdotH, 4.0);
float roughnessB = (NdotH * NdotH - 1.0) / (rSq * NdotH * NdotH);
float roughness = 1.0 / roughnessA * exp(roughnessB);
// ----- Cook-Torrance calculation -----
vec3 specular = vec3(fresnel * roughness * geo) / (NdotV * NdotL);
return max(0.0, NdotL) * (specularColor * specular + diffuseColor);
}
float calcShadowAmount(sampler2D shadowMap, vec4 initialShadowMapCoords) {
vec3 shadowMapCoords = (initialShadowMapCoords.xyz / initialShadowMapCoords.w);
if (inRange(shadowMapCoords.x) && inRange(shadowMapCoords.y) && inRange(shadowMapCoords.z)) {
return sampleVarianceShadowMap(shadowMap, shadowMapCoords.xy, shadowMapCoords.z, shadowVarianceMin, shadowLightBleedReduction);
} else {
return 1.0;
}
}
float calcBasicShadowAmount(sampler2D shadowMap, vec4 initialShadowMapCoords) {
vec3 shadowMapCoords = (initialShadowMapCoords.xyz / initialShadowMapCoords.w);
return sampleShadowMap(shadowMap, shadowMapCoords.xy, shadowMapCoords.z);
}
void main() {
vec3 directionToEye = normalize(eyePos - worldPos);
vec2 texCoords = calcParallaxTexCoords(dispMap, tbnMatrix, directionToEye, fragTexCoords, dispMapScale, dispMapBias);
vec3 normal = normalize(tbnMatrix * (255.0 / 128.0 * texture2D(normalMap, texCoords).xyz - 1));
gl_FragColor = calcLight(light, material, normal, eyePos, texture2D(diffuse, texCoords), vec3(1, 1, 1));
}
GLSL error reporting conventions are vendor-specific and thus difficult to parse. However, in this case 0:8(18): error: syntax error, unexpected NEW_IDENTIFIER, expecting '{' refers to line 8, character 18.
If you look at your fragment shader, on line 8 you have the following:
uniform Material material;
^ char. 18
The problem here is that you have not yet defined the structure of Material.
You will need to move these structs to precede your uniforms:
struct Light {
vec3 color;
float intensity;
vec3 direction;
};
struct Material {
float roughness;
float fresnelReflectance;
sampler2D diffuseTexture;
sampler2D normalMap;
sampler2D dispMap;
float dispMapScale;
float dispMapBias;
};