Code of rippleShader.frag file:
// attibutes from vertShader.vert
varying vec4 vColor;
varying vec2 vTexCoord;
// uniforms
uniform sampler2D uTexture;
uniform float uTime;
void main() {
float coef = sin(gl_FragCoord.y * 0.1 + 1 * uTime);
vTexCoord.y += coef * 0.03;
gl_FragColor = vColor * texture2D(uTexture, vTexCoord);
}
Code of vertShader.vert file:
#version 110
//varying "out" variables to be used in the fragment shader
varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
vColor = gl_Color;
vTexCoord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Please accept my apologies, i can't post the image now. But when i run the program the a error promt as follow:
The error messages means, that you are not allowed to assign any value to the variable vTexCoord, because it is an input to the fragment shader.
Change your code somehow like this:
void main() {
float coef = sin(gl_FragCoord.y * 0.1 + 1.0 * uTime);
vec2 texC = vec2(vTexCoord.x, vTexCoord.y + coef * 0.03);
gl_FragColor = vColor * texture2D(uTexture, texC);
}
Note, you get the warning message, because you used an integral constant value (1), instead of an floating point value (1.0).
Related
I am getting the following error in the fragment shader. I'm confused because the variable wasn't declared uniform.
To compile the shaders, I'm using SFML's loadFromFile() function.
My .frag shader
varying vec4 vColor;
varying vec2 vTexCoord;
uniform sampler2D uTexture;
uniform float uTime;
void main() {
float coef = sin(gl_FragCoord.y * 0.1 + 1.0 * uTime);
vTexCoord.y += coef * 0.03;
gl_FragColor = vColor * texture2D(uTexture, vTexCoord);
My .vert shader
varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
vColor = gl_Color;
vTexCoord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Error message:
0:10(2): error: assignment to read-only variable 'vTexCoord'
varying variable in a fragment shader are read-only, varying in a fragment shader means the vertex shader can pass different value through this variable to the fragment shader in contrast with uniform var which will get the same value. You need to introduce a local variable in your fragment shader main(), set its value as you want and use this local var to sample your texture.
Varying variables are read-only. The definition of a varying variable is here- https://thebookofshaders.com/glossary/?search=varying . But read-only does not mean the variables cannot be copied. Check Memory Qualifiers here- https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)#Vertex_shader_i
varying vec4 vColor;
varying vec2 vTexCoord;
uniform sampler2D uTexture;
uniform float uTime;
void main() {
float coef = sin(gl_FragCoord.y * 0.1 + 1.0 * uTime);
vec2 c = vTexCoord; // assigned co-ordinates to a new variable here
c.y += coef * 0.03;
gl_FragColor = vColor * texture2D(uTexture, c); // implemented new variable here
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;
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;
};
I'm attempting to port shaders from #version 110 to 150. I'm aware that when moving from 110 to 150 the global gl_ properties are deprecated and therefore all those properties will have to be specified manually in the shader. Then the specified properties have to be set through C++ via calls to OpenGL through glGetAttribLocation.
I'm a little unsure how to handle things such as gl_MultiTexCoord0 and gl_TexCoord.
Here of just one of the shaders I'm attempting to port from #version 110 to 150:
// blinn_phong.glsl
[vert]
#version 110
varying vec3 normal;
void main()
{
normal = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
[frag]
#version 110
uniform sampler2D colorMap;
uniform float materialAlpha;
varying vec3 normal;
void main()
{
vec3 n = normalize(normal);
float nDotL = max(0.0, dot(n, gl_LightSource[0].position.xyz));
float nDotH = max(0.0, dot(normal, vec3(gl_LightSource[0].halfVector)));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);
vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL;
vec4 specular = gl_FrontLightProduct[0].specular * power;
vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;
gl_FragColor = color * texture2D(colorMap, gl_TexCoord[0].st);
gl_FragColor.a = materialAlpha;
}
Can anyone provide some good resources to help with porting between these versions?
You will have to setup your own uniforms, attributes, varyings and fragment shader outputs. The code will become similar to:
[vert]
#version 150 core
uniform mat3 in_NormalMatrix;
uniform mat4 in_ModelViewProjectionMatrix;
in vec3 in_Normal;
in vec4 in_Vertex;
in vec2 in_MultiTexCoord;
out vec3 normal;
out vec2 texcoord;
void main()
{
normal = normalize(in_NormalMatrix * in_Normal);
gl_Position = in_ModelViewProjectionMatrix * in_Vertex;
texcoord = in_MultiTexCoord;
}
[frag]
#version 150
uniform sampler2D colorMap;
uniform float materialAlpha;
struct sLightSource
{
vec3 position;
vec3 halfVector;
...
}
uniform sLightSource u_LightSource;
in vec3 normal;
in vec2 texcoord;
out vec4 out_FragColor;
void main()
{
vec3 n = normalize(normal);
float nDotL = max(0.0, dot(n, u_LightSource.position.xyz));
float nDotH = max(0.0, dot(normal, vec3(u_LightSource.halfVector)));
...
out_FragColor = color * texture(colorMap, texcoord);
out_FragColor.a = materialAlpha;
}
P.S. This book has an entire chapter dedicated to this kind of transformations between different GLSL shader versions.
I was designing a shader for multi-lights, and a function that handles the light creation.
The lights are saved inside a struct uniform array and the quantity of lights in an int uniform called 'light_quantity'.
This is the function that creates the light:
int Game::AllocLight(LIGHT_TYPE mylight,float radius,glm::vec3 position,glm::vec3 direction,glm::vec4 ambient,glm::vec4 specular,glm::vec4 diffuse,bool status,int in_pos){
if(number_lights + 1 > MAX_LIGHTS || in_pos > MAX_LIGHTS){
return -1;
}
int newindex;
if(in_pos==-1){
newindex = number_lights++;
}else{
newindex=in_pos;
}
std::string as = std::to_string((unsigned long long)newindex);
// LightBase name
string light_base_name = "lights_a[" + as + "]";
GLint renderit_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".renderit")).c_str());
GLint ambient_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".ambient_light")).c_str());
GLint diffuse_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".diffuse_light")).c_str());
GLint specular_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".specular_light")).c_str());
GLint radius_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".radius")).c_str());
GLint position_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".light_position")).c_str());
GLint direction_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".light_direction")).c_str());
GLint type_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".light_type")).c_str());
int light_type;
switch(mylight){
case POINT_TYPE:
light_type=1;
break;
case DIRECTIONAL_TYPE:
light_type=2;
break;
case AREA_TYPE:
light_type=3;
break;
case SUN_TYPE:
light_type=4;
break;
}
glUniform1i(renderit_uniform,status);
glUniform4f(ambient_uniform,ambient.w,ambient.x,ambient.y,ambient.z);
glUniform4f(diffuse_uniform,diffuse.w,diffuse.x,diffuse.y,diffuse.z);
glUniform4f(specular_uniform,specular.w,specular.x,specular.y,specular.z);
glUniform1f(radius_uniform,radius);
glUniform3f(position_uniform,position.x,position.y,position.z);
glUniform3f(direction_uniform,direction.x,direction.y,direction.z);
glUniform1i(type_uniform,light_type);
glUniform1i(glGetUniformLocation(main_program.GetId(),"light_quantity"),number_lights);
return newindex;
}
MAX_LIGHTS: A macro defined with #defined, it's an int...
The problem is, that the uniforms are not getting defined as they are supposed to.
Here is my fragment shader (the vertex shader is not important in this problem, I think...)
#version 330 core
struct LightBase{
int renderit;
vec4 ambient_light;
vec4 specular_light;
vec4 diffuse_light;
float radius;
vec3 light_position;
vec3 light_direction;
int light_type;
};
struct MaterialBase{
vec4 ambient_affect;
vec4 specular_affect;
vec4 diffuse_affect;
float shining;
float mirror;
int light_affect;
};
in vec3 VertexPos;
in vec3 Normal;
uniform int light_quantity;
uniform LightBase lights_a[50];
uniform MaterialBase material;
uniform float usingTex;
uniform sampler2D texturemap;
in vec2 UVs;
in vec4 Colors;
out vec4 color;
void main(){
vec4 texture_u = texture(texturemap,UVs).rgba * usingTex;
vec4 color_u = Colors * (1.0f-usingTex);
vec4 final_color = color_u+texture_u;
for(int i=0;i<light_quantity;i++){
//if(lights_a[i].renderit==1){ // This is commented for test if the "light_quantity" is getting defined.
//if(lights_a[i].light_type==1){ // This is commented for test if the "light_quantity" is getting defined.
// Point Type
float attenuation = max(0.0,1.0-dot(lights_a[i].light_direction,lights_a[i].light_direction));
vec3 L = normalize(lights_a[i].light_direction);
vec3 N = normalize(Normal);
vec3 V = normalize(-VertexPos);
vec3 R = normalize(-reflect(L,N));
float nDotL = max(0.0,dot(N,L));
float rDotV = max(0.0,dot(R,V));
vec4 ambient_result = lights_a[i].ambient_light * material.ambient_affect * attenuation;
vec4 diffuse_result = lights_a[i].diffuse_light * material.diffuse_affect * nDotL * attenuation;
vec4 specular_result = lights_a[i].specular_light * material.specular_affect * pow(rDotV,material.shining) * attenuation;
vec4 this_colour = (ambient_result + diffuse_result + specular_result) * final_color;
final_color = vec4(0,0,0,0); // this_colour; // vec4(0,0,0,0) for test if the "light_quantity" is getting defined.
//} // This is commented for test if the "light_quantity" is getting defined.
//} // This is commented for test if the "light_quantity" is getting defined.
}
color = final_color;
}
Any Idea about why is this happening? I already tested a lot of times and I arrived to the conclution that the problems are the uniforms, what's happening? Are the uniforms that are not working?