Custom Minecraft Shader Bugs - opengl
I copied some files from a few shaders, and it works out for the most part, but I sometimes get graphical glitches like this where faces of grass blocks are completely transparent:
I believe my gbuffers_terrain.fsh or gbuffers_terrain.vsh is what is causing the problem.
gbuffers_terrain.fsh:
#version 120
#extension GL_ARB_shader_texture_lod : enable
/* DRAWBUFFERS:0247 */
/*
RRe36's Shaders, derived from Chocapic13 v4
Place two leading Slashes in front of the following '#define' lines in order to disable an option.
IMPORTANT: Placing Slashes in front of lines like '#define FILTER_LEVEL 15.0' will cause errors!
*/
//-------- Adjustable Variables --------//
//---- Normal Mapping ----//
#define NORMAL_MAPPING
#define NORMAL_MAP_MAX_ANGLE 1.0
//---- End of Normal Mapping ----//
//---- Parallax Displacement aka. POM ----//
//#define POM
#define POM_MAP_RES 128.0
#define POM_DEPTH (1.0/20.0)
const float MAX_OCCLUSION_DISTANCE = 32.0;
const float MIX_OCCLUSION_DISTANCE = 28.0;
const int MAX_OCCLUSION_POINTS = 12;
//---- End of Parallax Displacement ----//
//---- Lightmaps ----//
#define MIN_LIGHTAMOUNT 0.1 //affect the minecraft lightmap (not torches)
#define MINELIGHTMAP_EXP 2.0 //affect the minecraft lightmap (not torches)
//---- End of Lightmaps ----//
//-------- End of Adjustable Variables --------//
/* Here, intervalMult might need to be tweaked per texture pack.
The first two numbers determine how many samples are taken per fragment. They should always be the equal to eachother.
The third number divided by one of the first two numbers is inversely proportional to the range of the height-map. */
const vec3 intervalMult = vec3(1.0, 1.0, 1.0/POM_DEPTH)/POM_MAP_RES * 1.0;
const int RGBA16 = 3;
const int RGB16 = 2;
const int RGB8 = 1;
const int gnormalFormat = RGB16;
const int compositeFormat = RGBA16;
const int gaux2Format = RGBA16;
const int gcolorFormat = RGB8;
const int GL_EXP = 2048;
const int GL_LINEAR = 9729;
const float bump_distance = 64.0; //bump render distance: tiny = 32, short = 64, normal = 128, far = 256
const float pom_distance = 32.0; //POM render distance: tiny = 32, short = 64, normal = 128, far = 256
const float fademult = 0.1;
varying vec2 lmcoord;
varying vec4 color;
varying float translucent;
varying vec4 vtexcoordam; // .st for add, .pq for mul
varying vec4 vtexcoord;
varying float dist;
varying vec3 tangent;
varying vec3 normal;
varying vec3 binormal;
varying vec3 viewVector;
uniform sampler2D texture;
uniform sampler2D normals;
uniform sampler2D specular;
uniform vec3 sunPosition;
uniform vec3 moonPosition;
uniform int fogMode;
uniform int worldTime;
uniform float wetness;
uniform float rainStrength;
float totalspec = 0.0;
float wetx = clamp(wetness, 0.0f, 1.0)/1.0;
const float mincoord = 1.0/4096.0;
const float maxcoord = 1.0-mincoord;
vec2 dcdx = dFdx(vtexcoord.st*vtexcoordam.pq);
vec2 dcdy = dFdy(vtexcoord.st*vtexcoordam.pq);
vec4 readTexture(in vec2 coord){
return texture2DGradARB(texture,fract(coord)*vtexcoordam.pq+vtexcoordam.st,dcdx,dcdy);
}
vec4 readNormal(in vec2 coord){
return texture2DGradARB(normals,fract(coord)*vtexcoordam.pq+vtexcoordam.st,dcdx,dcdy);
}
float normalmap_intensity = NORMAL_MAP_MAX_ANGLE-((NORMAL_MAP_MAX_ANGLE*rainStrength)*0.95);
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
void main() {
vec2 adjustedTexCoord = vtexcoord.st*vtexcoordam.pq+vtexcoordam.st;
#ifdef POM
if (dist < MAX_OCCLUSION_DISTANCE) {
if ( viewVector.z < 0.0 && readNormal(vtexcoord.st).a < 0.99 && readNormal(vtexcoord.st).a > 0.01)
{
vec3 interval = viewVector.xyz * intervalMult;
vec3 coord = vec3(vtexcoord.st, 1.0);
for (int loopCount = 0;
(loopCount < MAX_OCCLUSION_POINTS) && (readNormal(coord.st).a < coord.p);
++loopCount) {
coord = coord+interval;
}
// Don't wrap around top of tall grass/flower
if (coord.t < mincoord) {
if (readTexture(vec2(coord.s,mincoord)).a == 0.0) {
coord.t = mincoord;
discard;
}
}
adjustedTexCoord = mix(fract(coord.st)*vtexcoordam.pq+vtexcoordam.st , adjustedTexCoord , max(dist-MIX_OCCLUSION_DISTANCE,0.0)/(MAX_OCCLUSION_DISTANCE-MIX_OCCLUSION_DISTANCE));
}
}
#endif
vec3 lightVector;
vec3 specularity = texture2DGradARB(specular, adjustedTexCoord.st, dcdx, dcdy).rgb;
float atten = 1.0-(specularity.b)*0.86;
vec4 frag2 = vec4(normal, 1.0f);
vec3 bump = texture2DGradARB(normals, adjustedTexCoord.st, dcdx, dcdy).rgb*2.0-1.0;
float bumpmult = normalmap_intensity*(1.0-wetness*lmcoord.t*0.65)*atten;
bump = bump * vec3(bumpmult, bumpmult, bumpmult) + vec3(0.0f, 0.0f, 1.0f - bumpmult);
mat3 tbnMatrix = mat3(tangent.x, binormal.x, normal.x,
tangent.y, binormal.y, normal.y,
tangent.z, binormal.z, normal.z);
frag2 = vec4(normalize(bump * tbnMatrix) * 0.5 + 0.5, 1.0);
float dirtest = 0.4;
if (worldTime < 12700 || worldTime > 23250) {
lightVector = normalize(sunPosition);
}
else {
lightVector = normalize(moonPosition);
}
dirtest = mix(1.0-0.8*step(dot(frag2.xyz*2.0-1.0,lightVector),-0.02),0.4,float(translucent > 0.01));
/* DRAWBUFFERS:0246 */
gl_FragData[0] = texture2DGradARB(texture, adjustedTexCoord.st, dcdx, dcdy) * color;
gl_FragData[1] = frag2;
gl_FragData[2] = vec4(lmcoord.t, dirtest, lmcoord.s, 1.0);
gl_FragData[3] = texture2DGradARB(specular, adjustedTexCoord.st, dcdx, dcdy);
}
My gbuffers_terrain.vsh:
#version 120
/*
RRe36's Shaders, derived from Chocapic13 v4
Place two leading Slashes in front of the following '#define' lines in order to disable an option.
IMPORTANT: Placing Slashes in front of lines like '#define FILTER_LEVEL 15.0' will cause errors!
*/
//-------- Adjustable Variables --------//
//---- Waving Effects ----//
#define WAVING_LEAVES
#define WAVING_VINES
#define WAVING_GRASS
#define WAVING_WHEAT
#define WAVING_FLOWERS
#define WAVING_FIRE
#define WAVING_LAVA
#define WAVING_LILYPAD
#define WAVING_TALLGRASS
#define WAVING_REEDS
//---- End of Waving Effects ----//
//---- Entity IDs ----//
#define ENTITY_LEAVES 18.0
#define ENTITY_VINES 106.0
#define ENTITY_TALLGRASS 31.0
#define ENTITY_DANDELION 37.0
#define ENTITY_ROSE 38.0
#define ENTITY_WHEAT 59.0
#define ENTITY_LILYPAD 111.0
#define ENTITY_FIRE 51.0
#define ENTITY_LAVAFLOWING 10.0
#define ENTITY_LAVASTILL 11.0
#define ENTITY_SAPLING 6.0
//---- End of Entity IDs ----//
//---- World Effects -----//
//#define WORLD_CURVATURE // will cause bug at high shadowdistances: looks like a dark circle around you
const float WORLD_RADIUS = 6000.0; //Increase for a stronger rounded world
const float WORLD_RADIUS_SQUARED = 15000000.0;
//---- End of World Effects ----//
//-------- End of Adjustable Variables --------//
const float PI = 3.1415927;
varying vec4 color;
varying vec2 lmcoord;
varying float translucent;
varying vec4 vtexcoordam; // .st for add, .pq for mul
varying vec4 vtexcoord;
varying float dist;
varying vec3 tangent;
varying vec3 normal;
varying vec3 binormal;
varying vec3 viewVector;
attribute vec4 mc_Entity;
attribute vec4 mc_midTexCoord;
uniform vec3 cameraPosition;
uniform mat4 gbufferModelView;
uniform mat4 gbufferModelViewInverse;
uniform int worldTime;
uniform float frameTimeCounter;
uniform float rainStrength;
float timefract = worldTime;
//Calculate Time of Day
float TimeSunrise = ((clamp(timefract, 23000.0, 24000.0) - 23000.0) / 1000.0) + (1.0 - (clamp(timefract, 0.0, 4000.0)/4000.0));
float TimeNoon = ((clamp(timefract, 0.0, 4000.0)) / 4000.0) - ((clamp(timefract, 8000.0, 12000.0) - 8000.0) / 4000.0);
float TimeSunset = ((clamp(timefract, 8000.0, 12000.0) - 8000.0) / 4000.0) - ((clamp(timefract, 12000.0, 12750.0) - 12000.0) / 750.0);
float TimeMidnight = ((clamp(timefract, 12000.0, 12750.0) - 12000.0) / 750.0) - ((clamp(timefract, 23000.0, 24000.0) - 23000.0) / 1000.0);
float animationTime = worldTime/20.0f;
float pi2wt = PI*2*(frameTimeCounter*24 + (rainStrength*2));
vec3 calcWave(in vec3 pos, in float fm, in float mm, in float ma, in float f0, in float f1, in float f2, in float f3, in float f4, in float f5) {
vec3 ret;
float magnitude,d0,d1,d2,d3;
magnitude = sin(pi2wt*fm + pos.x*0.5 + pos.z*0.5 + pos.y*0.5) * mm + ma;
d0 = sin(pi2wt*f0)*(rainStrength*2);
d1 = sin(pi2wt*f1)*(rainStrength*1.75);
d2 = sin(pi2wt*f2)*(rainStrength*1.5);
ret.x = sin(pi2wt*f3 + d0 + d1 - pos.x + pos.z + pos.y) * magnitude;
ret.z = sin(pi2wt*f4 + d1 + d2 + pos.x - pos.z + pos.y) * magnitude;
ret.y = sin(pi2wt*f5 + d2 + d0 + pos.z + pos.y - pos.y) * magnitude;
return ret;
}
vec3 calcMove(in vec3 pos, in float f0, in float f1, in float f2, in float f3, in float f4, in float f5, in vec3 amp1, in vec3 amp2) {
vec3 move1 = calcWave(pos , 0.0027, 0.0400, 0.0400, 0.0127, 0.0089, 0.0114, 0.0063, 0.0224, 0.0015) * amp1;
vec3 move2 = calcWave(pos+move1, 0.0348, 0.0400, 0.0400, f0, f1, f2, f3, f4, f5) * amp2;
return move1+move2;
}
vec3 calcWaterMove(in vec3 pos) {
float fy = fract(pos.y + 0.001);
if (fy > 0.002) {
float wave = 0.05 * sin(2 * PI * (worldTime / 86.0 + pos.x / 7.0 + pos.z / 13.0))
+ 0.05 * sin(2 * PI * (worldTime / 60.0 + pos.x / 11.0 + pos.z / 5.0));
return vec3(0, clamp(wave, -fy, 1.0-fy), 0);
}
else {
return vec3(0);
}
}
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
//////////////////////////////main//////////////////////////////
void main() {
vec2 texcoord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st;
vec2 midcoord = (gl_TextureMatrix[0] * mc_midTexCoord).st;
vec2 texcoordminusmid = texcoord-midcoord;
vtexcoordam.pq = abs(texcoordminusmid)*2;
vtexcoordam.st = min(texcoord,midcoord-texcoordminusmid);
vtexcoord.st = sign(texcoordminusmid)*0.5+0.5;
translucent = 0.0f;
float istopv = 0.0;
if (gl_MultiTexCoord0.t < mc_midTexCoord.t) istopv = 1.0;
/* un-rotate */
vec4 position = gbufferModelViewInverse * gl_ModelViewMatrix * gl_Vertex;
vec3 worldpos = position.xyz + cameraPosition;
//initialize per-entity waving parameters
float parm0,parm1,parm2,parm3,parm4,parm5 = rainStrength*4;
vec3 ampl1,ampl2;
ampl1 = vec3(0.0);
ampl2 = vec3(0.0);
#ifdef WAVING_LEAVES
if (( mc_Entity.x == ENTITY_LEAVES || mc_Entity.x == 161 )) {
parm0 = 0.0040;
parm1 = 0.0064;
parm2 = 0.0043;
parm3 = 0.0035;
parm4 = 0.0037;
parm5 = 0.0041;
ampl1 = vec3(1.0,0.2,1.0) + rainStrength/4;
ampl2 = vec3(0.5,0.1,0.5) + rainStrength/4;
}
#endif
#ifdef WAVING_VINES
if ( mc_Entity.x == ENTITY_VINES ) {
parm0 = 0.0040;
parm1 = 0.0064;
parm2 = 0.0043;
parm3 = 0.0035;
parm4 = 0.0037;
parm5 = 0.0041;
ampl1 = vec3(1.0,0.2,1.0);
ampl2 = vec3(0.5,0.1,0.5);
}
#endif
#ifdef WAVING_REEDS
if ( mc_Entity.x == 83 ) {
parm0 = 0.0024;
parm1 = 0.0020;
parm2 = 0.0016;
parm3 = 0.0010;
parm4 = 0.0009;
parm5 = 0.0002;
ampl1 = vec3(0.25,0.05,0.25) + rainStrength/5;
ampl2 = vec3(0.125,0.025,0.125) + rainStrength/5;
}
#endif
if (istopv > 0.9) {
#ifdef WAVING_GRASS
if ( mc_Entity.x == ENTITY_TALLGRASS || mc_Entity.x == ENTITY_SAPLING) {
parm0 = 0.0041;
parm1 = 0.0070;
parm2 = 0.0044;
parm3 = 0.0038;
parm4 = 0.0063;
parm5 = 0.0;
ampl1 = vec3(0.8,0.0,0.8) + 0.2 + rainStrength/3;
ampl2 = vec3(0.4,0.0,0.4) + 0.2 + rainStrength/3;
}
#endif
#ifdef WAVING_FLOWERS
if ((mc_Entity.x == ENTITY_DANDELION || mc_Entity.x == ENTITY_ROSE)) {
parm0 = 0.0041;
parm1 = 0.005;
parm2 = 0.0044;
parm3 = 0.0038;
parm4 = 0.0240;
parm5 = 0.0;
ampl1 = vec3(0.8,0.0,0.8) + rainStrength/3;
ampl2 = vec3(0.4,0.0,0.4) + rainStrength/3;
}
#endif
#ifdef WAVING_WHEAT
if ( mc_Entity.x == ENTITY_WHEAT || mc_Entity.x == 141 || mc_Entity.x == 142) {
parm0 = 0.0041;
parm1 = 0.0070;
parm2 = 0.0044;
parm3 = 0.0240;
parm4 = 0.0063;
parm5 = 0.0;
ampl1 = vec3(0.6,0.0,0.8) + rainStrength/3;
ampl2 = vec3(0.4,0.0,0.5) + rainStrength/3;
}
#endif
#ifdef WAVING_FIRE
if ( mc_Entity.x == ENTITY_FIRE) {
parm0 = 0.0105;
parm1 = 0.0096;
parm2 = 0.0087;
parm3 = 0.0063;
parm4 = 0.0097;
parm5 = 0.0156;
ampl1 = vec3(1.2,0.4,1.2) + rainStrength*1.8;
ampl2 = vec3(0.8,0.8,0.8) + rainStrength*1.8;
}
#endif
}
float movemult = 0.0;
#ifdef WAVING_LAVA
if ( mc_Entity.x == ENTITY_LAVAFLOWING || mc_Entity.x == ENTITY_LAVASTILL ) movemult = 0.25;
#endif
#ifdef WAVING_LILYPAD
if ( mc_Entity.x == ENTITY_LILYPAD ) movemult = 1.0 + (rainStrength*0.5);
#endif
#ifdef WAVING_TALLGRASS
if ( mc_Entity.x == 175) {
parm0 = 0.0031;
parm1 = 0.004;
parm2 = 0.0034;
parm3 = 0.0028;
parm4 = 0.0163;
parm5 = 0.0;
ampl1 = vec3(0.4,0.0,0.4);
ampl2 = vec3(0.2,0.0,0.2);
}
#endif
#ifdef WORLD_CURVATURE
if (gl_Color.a != 0.8) {
float distanceSquared = position.x * position.x + position.z * position.z;
position.y -= WORLD_RADIUS - sqrt(max(1.0 - distanceSquared / WORLD_RADIUS_SQUARED, 0.0)) * WORLD_RADIUS;
}
#endif
position.xyz += calcWaterMove(worldpos.xyz) * movemult;
position.xyz += calcMove(worldpos.xyz, parm0, parm1, parm2, parm3, parm4, parm5, ampl1, ampl2);
if ( mc_Entity.x == 37 || mc_Entity.x == 31 || mc_Entity.x == 175 || mc_Entity.x == 59 || mc_Entity.x == 141 || mc_Entity.x == 142 || mc_Entity.x == 31 )
translucent = 1.0;
/* re-rotate */
/* projectify */
gl_Position = gl_ProjectionMatrix * gbufferModelView * position;
color = gl_Color;
lmcoord = (gl_TextureMatrix[1] * gl_MultiTexCoord1).xy;
normal = normalize(gl_NormalMatrix * gl_Normal);
tangent = vec3(0.0);
binormal = vec3(0.0);
normal = normalize(gl_NormalMatrix * gl_Normal);
if (gl_Normal.x > 0.5) {
// 1.0, 0.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.x < -0.5) {
// -1.0, 0.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.y > 0.5) {
// 0.0, 1.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
} else if (gl_Normal.y < -0.5) {
// 0.0, -1.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
} else if (gl_Normal.z > 0.5) {
// 0.0, 0.0, 1.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.z < -0.5) {
// 0.0, 0.0, -1.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
}
mat3 tbnMatrix = mat3(tangent.x, binormal.x, normal.x,
tangent.y, binormal.y, normal.y,
tangent.z, binormal.z, normal.z);
viewVector = ( gl_ModelViewMatrix * gl_Vertex).xyz;
viewVector = normalize(tbnMatrix * viewVector);
dist = 0.0;
dist = length(gbufferModelView *gbufferModelViewInverse * gl_ModelViewMatrix * gl_Vertex);
}
My composite.fsh:
#version 120
//------------------------------------
//datLax' OnlyWater v2.0
//
//If you have questions, suggestions or bugs you want to report, please comment on my minecraftforum.net thread:
//http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2381727-shader-pack-datlax-onlywater-only-water
//
//This code is free to use,
//but don't forget to give credits! :)
//------------------------------------
uniform sampler2D gcolor;
uniform sampler2D depthtex0;
uniform sampler2D gaux1;
varying vec4 texcoord;
varying vec3 ambient_color;
varying float TimeMidnight;
uniform int worldTime;
uniform mat4 gbufferProjection;
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferModelViewInverse;
uniform float near;
uniform float far;
uniform float viewWidth;
uniform float viewHeight;
float ld(float depth) {
return (2.0 * near) / (far + near - depth * (far - near));
}
vec3 aux = texture2D(gaux1, texcoord.st).rgb;
float land = aux.b;
float torch_lightmap = aux.b;
float sky_lightmap = aux.g;
float landx = 1.0-step(land, 0.01);
float iswater = 0.0;
float pixeldepth = texture2D(depthtex0,texcoord.xy).x;
float pw = 1.0/ viewWidth;
float ph = 1.0/ viewHeight;
float callwaves(vec2 pos) {
float wsize = 2.9;
float wspeed = 0.025f;
float rs0 = abs(sin((worldTime*wspeed/5.0) + (pos.s*wsize) * 20.0)+0.2);
float rs1 = abs(sin((worldTime*wspeed/7.0) + (pos.t*wsize) * 27.0));
float rs2 = abs(sin((worldTime*wspeed/2.0) + (pos.t*wsize) * 60.0 - sin(pos.s*wsize) * 13.0)+0.4);
float rs3 = abs(sin((worldTime*wspeed/1.0) - (pos.s*wsize) * 20.0 + cos(pos.t*wsize) * 83.0)+0.1);
float wsize2 = 1.7;
float wspeed2 = 0.017f;
float rs0a = abs(sin((worldTime*wspeed2/4.0) + (pos.s*wsize2) * 24.0));
float rs1a = abs(sin((worldTime*wspeed2/11.0) + (pos.t*wsize2) * 77.0 )+0.3);
float rs2a = abs(sin((worldTime*wspeed2/6.0) + (pos.s*wsize2) * 50.0 - (pos.t*wsize2) * 23.0)+0.12);
float rs3a = abs(sin((worldTime*wspeed2/14.0) - (pos.t*wsize2) * 4.0 + (pos.s*wsize2) * 98.0));
float wsize3 = 0.3;
float wspeed3 = 0.03f;
float rs0b = abs(sin((worldTime*wspeed3/4.0) + (pos.s*wsize3) * 14.0));
float rs1b = abs(sin((worldTime*wspeed3/11.0) + (pos.t*wsize3) * 37.0));
float rs2b = abs(sin((worldTime*wspeed3/6.0) + (pos.t*wsize3) * 47.0 - cos(pos.s*wsize3) * 33.0 + rs0a + rs0b));
float rs3b = abs(sin((worldTime*wspeed3/14.0) - (pos.s*wsize3) * 13.0 + sin(pos.t*wsize3) * 98.0 + rs0 + rs1));
float waves = (rs1 * rs0 + rs2 * rs3)/2.0f;
float waves2 = (rs0a * rs1a + rs2a * rs3a)/2.0f;
float waves3 = (rs0b + rs1b + rs2b + rs3b)*0.25;
return (waves + waves2 + waves3)/3.0f;
}
//----------------MAIN------------------
void main() {
if(aux.g > 0.01 && aux.g < 0.07) {
iswater = 1.0;
}
vec4 fragposition = gbufferProjectionInverse * vec4(texcoord.s * 2.0f - 1.0f, texcoord.t * 2.0f - 1.0f, 2.0f * pixeldepth - 1.0f, 1.0f);
fragposition /= fragposition.w;
float dist = length(fragposition.xyz);
vec4 worldposition = vec4(0.0);
worldposition = gbufferModelViewInverse * fragposition;
vec3 color = texture2D(gcolor, texcoord.st).rgb;
const float rspread = 0.30f;
float wave = 0.0;
if (iswater == 1.0) {
wave = callwaves(worldposition.xz*0.02)*2.0-1.0;
wave = wave;
const float wnormalclamp = 0.05f;
float rdepth = pixeldepth;
float waves = wave;
float wnormal_x1 = texture2D(depthtex0, texcoord.st + vec2(pw, 0.0f)).x - texture2D(depthtex0, texcoord.st).x;
float wnormal_x2 = texture2D(depthtex0, texcoord.st).x - texture2D(depthtex0, texcoord.st + vec2(-pw, 0.0f)).x;
float wnormal_x = 0.0f;
if(abs(wnormal_x1) > abs(wnormal_x2)){
wnormal_x = wnormal_x2;
} else {
wnormal_x = wnormal_x1;
}
wnormal_x /= 1.0f - rdepth;
wnormal_x = clamp(wnormal_x, -wnormalclamp, wnormalclamp);
wnormal_x *= rspread;
float wnormal_y1 = texture2D(depthtex0, texcoord.st + vec2(0.0f, ph)).x - texture2D(depthtex0, texcoord.st).x;
float wnormal_y2 = texture2D(depthtex0, texcoord.st).x - texture2D(depthtex0, texcoord.st + vec2(0.0f, -ph)).x;
float wnormal_y;
if(abs(wnormal_y1) > abs(wnormal_y2)){
wnormal_y = wnormal_y2;
} else {
wnormal_y = wnormal_y1;
}
wnormal_y /= 1.0f - rdepth;
wnormal_y = clamp(wnormal_y, -wnormalclamp, wnormalclamp);
wnormal_y *= rspread;
//Calculate distance of objects behind water
float refractdist = 0.2 * 10.0f;
//Perform refraction
float refractamount = 500.1154f*0.35f*refractdist;
float refractamount2 = 0.0214f*0.05f*refractdist;
float refractamount3 = 0.214f*0.15f*refractdist;
float waberration = 0.105;
vec3 refracted = vec3(0.0f);
float refractedmask = 0.0;
float bigWaveRefract = 0.0;
float bigWaveRefractScale = 0.0;
vec2 bigRefract = vec2(wnormal_x*bigWaveRefract, wnormal_y*bigWaveRefract);
vec2 refractcoord_r = texcoord.st;
vec2 refractcoord_g = texcoord.st;
vec2 refractcoord_b = texcoord.st;
for (int i = 0; i < 1; ++i) {
refractcoord_r = texcoord.st * (1.0f + waves*refractamount3) - (waves*refractamount3/2.0f) + vec2( waves*refractamount2 + (-wnormal_x*0.4f) - bigRefract.x, waves*refractamount2 + (-wnormal_y*0.4f) - bigRefract.y) * (waberration * 2.0f + 1.0f);
refractcoord_r = refractcoord_r * vec2(1.0f - abs(wnormal_x) * bigWaveRefractScale, 1.0f - abs(wnormal_y) * bigWaveRefractScale) + vec2(abs(wnormal_x) * bigWaveRefractScale * 0.5f, abs(wnormal_y) * bigWaveRefractScale * 0.5f);
refractcoord_r.s = clamp(refractcoord_r.s, 0.001f, 0.999f);
refractcoord_r.t = clamp(refractcoord_r.t, 0.001f, 0.999f);
if (refractcoord_r.s > 1.0 || refractcoord_r.s < 0.0 || refractcoord_r.t > 1.0 || refractcoord_r.t < 0.0) {
break;
}
refracted.rgb = texture2D(gcolor, refractcoord_r).rgb;
refractedmask = texture2D(gaux1, refractcoord_r).g;
if(refractedmask > 0.01 && refractedmask < 0.07) {
refractedmask = 1.0;
}else refractedmask = 0.0;
}
color.rgb = mix(color.rgb, refracted.rgb, vec3(refractedmask));
}
wave = wave*0.5+0.5;
if (iswater > 0.9){
wave += 0.02;
}else{
wave = 0.0;
}
if (landx == 1.0) {
//vec3 torchcolor = vec3(1.0, 0.675, 0.415);
vec3 torchcolor = vec3(0.8, 0.7, 0.3);
vec3 torchlight_lightmap = torch_lightmap * torchcolor;
color = color * torchlight_lightmap * TimeMidnight + color * ambient_color;
}
/* DRAWBUFFERS:3 */
gl_FragData[0] = vec4(color, 1.0);
/* DRAWBUFFERS:NNN3N5 */
gl_FragData[5] = vec4(0.0, wave, 0.0, 0.0);
gl_FragData[3] = vec4(color, land);
}
My composite.vsh:
#version 120
//------------------------------------
//datLax' OnlyWater v2.0
//
//If you have questions, suggestions or bugs you want to report, please comment on my minecraftforum.net thread:
//http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2381727-shader-pack-datlax-onlywater-only-water
//
//This code is free to use,
//but don't forget to give credits! :)
//------------------------------------
varying vec4 texcoord;
varying float TimeMidnight;
varying float TimeSunset;
varying float TimeNoon;
varying float TimeSunrise;
varying vec3 ambient_color;
uniform int worldTime;
void main() {
gl_Position = ftransform();
texcoord = gl_MultiTexCoord0;
float timefract = float(worldTime);
TimeSunrise = ((clamp(timefract, 23000.0, 24000.0) - 23000.0) / 1000.0) + (1.0-(clamp(timefract, 0.0, 6000.0)/6000.0));
TimeNoon = ((clamp(timefract, 0.0, 6000.0)) / 6000.0) - ((clamp(timefract, 6000.0, 12000.0) - 6000.0) / 6000.0);
TimeSunset = ((clamp(timefract, 6000.0, 12000.0) - 6000.0) / 6000.0) - ((clamp(timefract, 12000.0, 12750.0) - 12000.0) / 750.0);
TimeMidnight = ((clamp(timefract, 12000.0, 12750.0) - 12000.0) / 750.0) - ((clamp(timefract, 23000.0, 24000.0) - 23000.0) / 1000.0);
vec3 sunrise_amb;
sunrise_amb.r = TimeSunrise;
sunrise_amb.g = TimeSunrise;
sunrise_amb.b = TimeSunrise;
vec3 noon_amb;
noon_amb.r = TimeNoon;
noon_amb.g = TimeNoon;
noon_amb.b = TimeNoon;
vec3 sunset_amb;
sunset_amb.r = 0.95*TimeSunset;
sunset_amb.g = 0.95*TimeSunset;
sunset_amb.b = 0.95*TimeSunset;
vec3 midnight_amb;
midnight_amb.r = 0.45*TimeMidnight;
midnight_amb.g = 0.45*TimeMidnight;
midnight_amb.b = 0.7*TimeMidnight;
ambient_color.r = sunrise_amb.r + noon_amb.r + sunset_amb.r + midnight_amb.r;
ambient_color.g = sunrise_amb.g + noon_amb.g + sunset_amb.g + midnight_amb.g;
ambient_color.b = sunrise_amb.b + noon_amb.b + sunset_amb.b + midnight_amb.b;
}
I am using a 128x128 resource pack, and I don't know much about shaders. Why are faces of grass blocks flickering, and is there a way to fix this? Also, when recording from OBS screen capture, the video turns out flashing. Reminder: I pulled gbuffers_terrain from a completely different shaderpack.
Specs:
OS: Ubuntu 16.04 LTS 64-bit
RAM: 8GB
CPU: Intel® Core™ i5-4460 CPU # 3.20GHz × 4
GPU: Intel® Haswell Desktop
OpenGL:
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Haswell Desktop
OpenGL core profile version string: 3.3 (Core Profile) Mesa 12.1.0-devel
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 12.1.0-devel
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 12.1.0-devel
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:
Related
Compute Normals After Vertex Deformation?
I am coding a vertex and a fragment shader trying to distort the surface of some water and then computing blinn-phong lighting on the surface. I am able to successfully compute the deformed matrices with a simple noise function, but how can I find the distorted normals? Since it isn't a linear transformation I am stuck, could anyone help? Here are the relevant files: vertex shader: #version 150 uniform mat4 u_Model; uniform mat4 u_ModelInvTr; uniform mat4 u_ViewProj; uniform vec4 u_Color; uniform int u_Time; in vec4 vs_Pos; // The array of vertex positions passed to the shader in vec4 vs_Nor; // The array of vertex normals passed to the shader in vec4 vs_Col; // The array of vertex colors passed to the shader. in vec2 vs_UV; // UV coords for texture to pass thru to fragment shader in float vs_Anim; // 0.f or 1.f To pass thru to fragment shader in float vs_T2O; out vec4 fs_Pos; out vec4 fs_Nor; out vec4 fs_LightVec; out vec4 fs_Col; out vec2 fs_UVs; out float fs_Anim; out float fs_dimVal; out float fs_T2O; uniform vec4 u_CamPos; out vec4 fs_CamPos; const vec4 lightDir = normalize(vec4(0.0, 1.f, 0.0, 0)); mat4 rotationMatrix(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); float c = cos(angle); float oc = 1.0 - c; return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0); } vec4 rotateLightVec(float deg, vec4 LV) { mat4 R = rotationMatrix(vec3(0,0,1), deg); return R * LV; } float random1(vec3 p) { return fract(sin(dot(p, vec3(127.1, 311.7, 191.999)))*43758.5453); } vec3 random2( vec3 p ) { return fract( sin( vec3(dot(p, vec3(127.1, 311.7, 58.24)), dot(p, vec3(269.5, 183.3, 657.3)), dot(p, vec3(420.69, 69.420, 469.20))) ) * 43758.5453); } void main() { fs_Col = vs_Col; fs_UVs = vs_UV; fs_Anim = vs_Anim; fs_T2O = vs_T2O; mat3 invTranspose = mat3(u_ModelInvTr); fs_Nor = vec4(invTranspose * vec3(vs_Nor), 0); vec4 modelposition = u_Model * vs_Pos; if (vs_Anim != 0) { // if we want to animate this surface // check region in texture to decide which animatable type is drawn bool lava = fs_UVs.x >= 13.f/16.f && fs_UVs.y < 2.f/16.f; bool water = !lava && fs_UVs.x >= 13.f/16.f && fs_UVs.y <= 4.f/16.f; if (water) { // define an oscillating time so that model can transition back and forth float t = (cos(u_Time * 0.05) + 1)/2; // u_Time increments by 1 every frame. Domain [0,1] vec3 temp = random2(vec3(modelposition.x, modelposition.y, modelposition.z)); // range [0, 1] temp = (temp - 0.5)/25; // [0, 1/scalar] modelposition.x = mix(modelposition.x - temp.x, modelposition.x + temp.x, t); modelposition.y = mix(modelposition.y - temp.y, modelposition.y + 3*temp.y, t); modelposition.z = mix(modelposition.z - temp.z, modelposition.z + temp.z, t); } else if (lava) { // define an oscillating time so that model can transition back and forth float t = (cos(u_Time * 0.01) + 1)/2; // u_Time increments by 1 every frame. Domain [0,1] vec3 temp = random2(vec3(modelposition.x, modelposition.y, modelposition.z)); // range [0, 1] temp = (temp - 0.5)/25; // [0, 1/scalar] modelposition.x = mix(modelposition.x - temp.x, modelposition.x + temp.x, t); modelposition.y = mix(modelposition.y - temp.y, modelposition.y + 3*temp.y, t); modelposition.z = mix(modelposition.z - temp.z, modelposition.z + temp.z, t); } } fs_dimVal = random1(modelposition.xyz/100.f); fs_LightVec = rotateLightVec(0.001 * u_Time, lightDir); // Compute the direction in which the light source lies fs_CamPos = u_CamPos; // uniform handle for the camera position instead of the inverse fs_Pos = modelposition; gl_Position = u_ViewProj * modelposition;// gl_Position is a built-in variable of OpenGL which is // used to render the final positions of the geometry's vertices } fragment shader: #version 330 uniform vec4 u_Color; // The color with which to render this instance of geometry. uniform sampler2D textureSampler; uniform int u_Time; uniform mat4 u_ViewProj; uniform mat4 u_Model; in vec4 fs_Pos; in vec4 fs_Nor; in vec4 fs_LightVec; in vec4 fs_Col; in vec2 fs_UVs; in float fs_Anim; in float fs_T2O; in float fs_dimVal; out vec4 out_Col; in vec4 fs_CamPos; float random1(vec3 p) { return fract(sin(dot(p,vec3(127.1, 311.7, 191.999))) *43758.5453); } float random1b(vec3 p) { return fract(sin(dot(p,vec3(169.1, 355.7, 195.999))) *95751.5453); } float mySmoothStep(float a, float b, float t) { t = smoothstep(0, 1, t); return mix(a, b, t); } float cubicTriMix(vec3 p) { vec3 pFract = fract(p); float llb = random1(floor(p) + vec3(0,0,0)); float lrb = random1(floor(p) + vec3(1,0,0)); float ulb = random1(floor(p) + vec3(0,1,0)); float urb = random1(floor(p) + vec3(1,1,0)); float llf = random1(floor(p) + vec3(0,0,1)); float lrf = random1(floor(p) + vec3(1,0,1)); float ulf = random1(floor(p) + vec3(0,1,1)); float urf = random1(floor(p) + vec3(1,1,1)); float mixLoBack = mySmoothStep(llb, lrb, pFract.x); float mixHiBack = mySmoothStep(ulb, urb, pFract.x); float mixLoFront = mySmoothStep(llf, lrf, pFract.x); float mixHiFront = mySmoothStep(ulf, urf, pFract.x); float mixLo = mySmoothStep(mixLoBack, mixLoFront, pFract.z); float mixHi = mySmoothStep(mixHiBack, mixHiFront, pFract.z); return mySmoothStep(mixLo, mixHi, pFract.y); } float fbm(vec3 p) { float amp = 0.5; float freq = 4.0; float sum = 0.0; for(int i = 0; i < 8; i++) { sum += cubicTriMix(p * freq) * amp; amp *= 0.5; freq *= 2.0; } return sum; } void main() { vec4 diffuseColor = texture(textureSampler, fs_UVs); bool apply_lambert = true; float specularIntensity = 0; if (fs_Anim != 0) { // check region in texture to decide which animatable type is drawn bool lava = fs_UVs.x >= 13.f/16.f && fs_UVs.y < 2.f/16.f; bool water = !lava && fs_UVs.x >= 13.f/16.f && fs_UVs.y < 4.f/16.f; if (lava) { // slowly gyrate texture and lighten and darken with random dimVal from vert shader vec2 movingUVs = vec2(fs_UVs.x + fs_Anim * 0.065/16 * sin(0.01*u_Time), fs_UVs.y - fs_Anim * 0.065/16 * sin(0.01*u_Time + 3.14159/2)); diffuseColor = texture(textureSampler, movingUVs); vec4 warmerColor = diffuseColor + vec4(0.3, 0.3, 0, 0); vec4 coolerColor = diffuseColor - vec4(0.1, 0.1, 0, 0); diffuseColor = mix(warmerColor, coolerColor, 0.5 + fs_dimVal * 0.65*sin(0.02*u_Time)); apply_lambert = false; } else if (water) { // blend between 3 different points in texture to create a wavy subtle change over time vec2 offsetUVs = vec2(fs_UVs.x - 0.5f/16.f, fs_UVs.y - 0.5f/16.f); diffuseColor = texture(textureSampler, fs_UVs); vec4 altColor = texture(textureSampler, offsetUVs); altColor.x += fs_dimVal * pow(altColor.x+.15, 5); altColor.y += fs_dimVal * pow(altColor.y+.15, 5); altColor.z += 0.5 * fs_dimVal * pow(altColor.z+.15, 5); diffuseColor = mix(diffuseColor, altColor, 0.5 + 0.35*sin(0.05*u_Time)); offsetUVs -= 0.25f/16.f; vec4 newColor = texture(textureSampler, offsetUVs); diffuseColor = mix(diffuseColor, newColor, 0.5 + 0.5*sin(0.025*u_Time)) + fs_dimVal * vec4(0.025); diffuseColor.a = 0.7; // ---------------------------------------------------- // Blinn-Phong Shading // ---------------------------------------------------- vec4 lightDir = normalize(fs_LightVec - fs_Pos); vec4 viewDir = normalize(fs_CamPos - fs_Pos); vec4 halfVec = normalize(lightDir + viewDir); float shininess = 400.f; float specularIntensity = max(pow(dot(halfVec, normalize(fs_Nor)), shininess), 0); } } // Calculate the diffuse term for Lambert shading float diffuseTerm = dot(normalize(fs_Nor), normalize(fs_LightVec)); // Avoid negative lighting values diffuseTerm = clamp(diffuseTerm, 0, 1); float ambientTerm = 0.3; float lightIntensity = diffuseTerm + ambientTerm; //Add a small float value to the color multiplier //to simulate ambient lighting. This ensures that faces that are not //lit by our point light are not completely black. vec3 col = diffuseColor.rgb; // Compute final shaded color if (apply_lambert) { col = col * lightIntensity + col * specularIntensity; } // & Check the rare, special case where we draw face between two diff transparent blocks as opaque if (fs_T2O != 0) { out_Col = vec4(col, 1.f); } else { out_Col = vec4(col, diffuseColor.a); } // distance fog! vec4 fogColor = vec4(0.6, 0.75, 0.9, 1.0); float FC = gl_FragCoord.z / gl_FragCoord.w / 124.f; float falloff = clamp(1.05 - exp(-1.05f * (FC - 0.9f)), 0.f, 1.f); out_Col = mix(out_Col, fogColor, falloff); } I tried implementing blinn-phong in the fragment shader, but I think it is wrong simple from the wrong normals. I think this can be done with some sort of tangent and cross product solution, but how can I know the tangent of the surface given we only know the vertex position? I am not using unity, just bare c++ and most of the answers I am finding online are for java or unity which I do not understand.`
Blobs shader GLSL
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.
Why shadows are not rendered when PBR directional light is applied?
I've got a problem with rendering hard shadows in a PBR pipeline. I believe there is something wrong with PBR calculations because with a Blinn-Phong lighting model everything looks fine. These are lightning calculations - basic PBR struct DirectionalLight { vec3 direction; }; layout(std140, binding = 2) uniform Scene { DirectionalLight directionalLight; vec3 viewPosition; } u_scene; layout(std140, binding = 4) uniform Material { vec4 baseColor; float roughness; float metalness; } u_material; const float PI = 3.14159265359; const float epsilon = 0.00001; int lightCount = 1; vec3 CalculateDirectionalLight(vec3 N, vec3 V, float NdotV, vec3 F0) { vec3 result; for(int i = 0; i < lightCount; ++i) { vec3 L = normalize(-u_scene.directionalLight.direction); float NdotL = max(0.0f, dot(N, L)); vec3 H = normalize(V + L); float NdotH = max(0.0f, dot(N, H)); vec3 F = FresnelSchlickRoughness(max(0.0f, dot(H, V)), F0, u_material.roughness); float D = NDFGGX(NdotH, u_material.roughness); float G = GeometrySmith(NdotL, NdotV, u_material.roughness); vec3 kd = (1.0f - F) * (1.0f - u_material.metalness); vec3 diffuse = kd * u_material.baseColor.rgb; vec3 nominator = F * G * D; float denominator = max(epsilon, 4.0f * NdotV * NdotL); vec3 specular = nominator / denominator; specular = clamp(specular, vec3(0.0f), vec3(10.0f)); result += (diffuse + specular) /* u_material.radiance */ * NdotL; } return result; } float NDFGGX(float NdotH, float roughness) { float alpha = roughness * roughness; float alphaSq = alpha * alpha; float denom = (NdotH * NdotH) * (alphaSq - 1.0) + 1.0; return alphaSq / (PI * denom * denom); } float GeometrySchlickGGX(float Ndot, float k) { float nom = Ndot; float denom = Ndot * (1.0 - k) + k; return nom / denom; } float GeometrySmith(float NdotL, float NdotV, float roughness) { float r = (roughness + 1.0f); float k = (r * r) / 8.0f; float ggx2 = GeometrySchlickGGX(NdotV, k); float ggx1 = GeometrySchlickGGX(NdotL, k); return ggx1 * ggx2; } vec3 FresnelSchlick(float cosTheta, vec3 F0) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) { return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0); } shadow functions layout(binding = 2) uniform sampler2D u_shadowMap; float ShadowFade = 1.0; float GetShadowBias() { const float MINIMUM_SHADOW_BIAS = 0.002; float bias = max(MINIMUM_SHADOW_BIAS * (1.0 - dot(normalize(v_normal), -normalize(u_scene.directionalLight.direction))), MINIMUM_SHADOW_BIAS); return bias; } float HardShadows_DirectionalLight(vec4 fragPosLightSpace) { vec3 shadowCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; float bias = GetShadowBias(); float shadowMapDepth = texture(u_shadowMap, vec2(shadowCoords.xy * 0.5 + 0.5)).r; return step(shadowCoords.z, shadowMapDepth + bias) * ShadowFade; } and the main function void main() { vec3 F0 = vec3(0.04f); F0 = mix(F0, u_material.baseColor.rgb, u_material.metalness); vec3 N = normalize(v_normal); vec3 V = normalize(u_scene.viewPosition - v_position); float NdotV = max(0.0f, dot(N, V)); //v_positionFromLight is calculated in a vertex shader like this: //v_positionFromLight = u_lightViewProjection * vec4(v_position, 1.0f); //where v_position is modelMatrix * a_position; //where a_position is a input position of a vertex float shadow = HardShadows_DirectionalLight(v_positionFromLight); vec3 ambient = u_material.baseColor.rgb * 0.3f; vec3 lightContribution = ambient + CalculateDirectionalLight(N, V, NdotV, F0) * shadow; f_color = vec4(lightContribution, 1.0); } and this is how the scene looks like - there should be visible shadows, but there aren't: I've tested 2 things. First - Blinn-Phong lighting model - shadows render just fine. Second - output shadow calculations without PBR lightning like this: void main() { float shadow = HardShadows_DirectionalLight(v_positionFromLight); vec3 ambient = u_material.baseColor.rgb * 0.3f; f_color = vec4(ambient * shadow, 1.0f); } and it also works (besides that they're not placed in a good spot, but that is another topic): Why this PBR model does not work with shadows? How can I fix it?
How to adjust Color Properly in a Noise Pattern?
I am trying to write a noise pattern that resembles wood in GLSL. Here is my current code: #ifdef GL_ES precision mediump float; #endif uniform vec2 u_resolution; float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.545312); } float noise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); vec2 u = f*f*(3.0-2.0*f); return mix( mix( random(i + vec2(0.0,0.0) ), random(i + vec2(1.0,0.0) ), u.x), mix( random(i + vec2(0.0,1.0) ), random(i + vec2(1.0,1.0) ), u.x), u.y); } mat2 rotate2d(float angle) { return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); } float lines(in vec2 pos, float b){ float scale = 10.0; pos *= scale; return smoothstep(0.0, 0.5+b * 0.5, abs((sin(pos.x*3.1415)+b*2.0))*0.5); } vec3 c1 = vec3(0.134,0.109,0.705); vec3 c2 = vec3(0.000,0.411,0.665); void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 pos = st.yx*vec2(11.0, 3.0); vec3 color = vec3(1.0); float pattern = pos.x; color = mix(c1, c2, pattern); // Add noise pos = rotate2d(noise(pos)) * pos; // Draw lines pattern = lines(pos, 0.7); gl_FragColor = vec4(pattern, color); } In its current state it makes my pattern look reddish-pink with some weird gradient showing up at the bottom. I want to make the pink areas brown while my pattern stays black. Can someone show how to adjust my color variables to do this?
The color channels are red, green, blue. Hence, red is the first component: vec3 c1 = vec3(0.705,0.109,0.134); vec3 c2 = vec3(0.665,0.411,0.000); You need to mix the colors after pattern is set: void main() { // [...] // Draw lines pattern = lines(pos, 0.7); color = mix(c1, c2, pattern); gl_FragColor = vec4(color, 1.0); } See the result when you use a dark brown and a light broun: vec3 c1 = vec3(50.0, 40.0, 30.0) / 255.0; vec3 c2 = vec3(200.0, 150.0, 100.0) / 255.0; #ifdef GL_ES precision mediump float; #endif uniform vec2 u_resolution; float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.545312); } float noise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); vec2 u = f*f*(3.0-2.0*f); return mix( mix( random(i + vec2(0.0,0.0) ), random(i + vec2(1.0,0.0) ), u.x), mix( random(i + vec2(0.0,1.0) ), random(i + vec2(1.0,1.0) ), u.x), u.y); } mat2 rotate2d(float angle) { return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); } float lines(in vec2 pos, float b){ float scale = 10.0; pos *= scale; return smoothstep(0.0, 0.5+b * 0.5, abs((sin(pos.x*3.1415)+b*2.0))*0.5); } vec3 c1 = vec3(50.0, 40.0, 30.0) / 255.0; vec3 c2 = vec3(200.0, 150.0, 100.0) / 255.0; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 pos = st.yx*vec2(11.0, 3.0); // Add noise pos = rotate2d(noise(pos)) * pos; // Draw lines float pattern = lines(pos, 0.7); vec3 color = mix(c1, c2, pattern); gl_FragColor = vec4(color, 1.0); }
Shader for a spotlight
How can I get this shader to have a smooth edge on the spot light instead of a hard one? In addition, the shader has to cope with a variable value of GL_SPOT_CUTOFF. Note that not all the lights are spot lights -- GL_LIGHT0 is a point light. varying vec3 N; varying vec3 v; #define MAX_LIGHTS 2 void main (void) { vec4 finalColour; float spotEffect; for (int i=0; i<MAX_LIGHTS; i++) { vec3 L = normalize(gl_LightSource[i].position.xyz - v); vec3 E = normalize(-v); vec3 R = normalize(-reflect(L,N)); spotEffect = dot(normalize(gl_LightSource[i].spotDirection), normalize(-L)); if (spotEffect > gl_LightSource[i].spotCosCutoff) { vec4 Iamb = gl_FrontLightProduct[i].ambient; vec4 Idiff = gl_FrontLightProduct[i].diffuse * max(dot(N,L), 0.0); Idiff = clamp(Idiff, 0.0, 1.0); vec4 Ispec = gl_FrontLightProduct[i].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); Ispec = clamp(Ispec, 0.0, 1.0); finalColour += Iamb + Idiff + Ispec; } } gl_FragColor = gl_FrontLightModelProduct.sceneColor + finalColour; } The scene looks like this:
This shader from http://www.ozone3d.net/tutorials/glsl_lighting_phong_p3.php produces the soft edges to the spotlight you are after. [Pixel_Shader] varying vec3 normal, lightDir, eyeVec; const float cos_outer_cone_angle = 0.8; // 36 degrees void main (void) { vec4 final_color = (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) + (gl_LightSource[0].ambient * gl_FrontMaterial.ambient); vec3 L = normalize(lightDir); vec3 D = normalize(gl_LightSource[0].spotDirection); float cos_cur_angle = dot(-L, D); float cos_inner_cone_angle = gl_LightSource[0].spotCosCutoff; float cos_inner_minus_outer_angle = cos_inner_cone_angle - cos_outer_cone_angle; //**************************************************** // Don't need dynamic branching at all, precompute // falloff(i will call it spot) float spot = 0.0; spot = clamp((cos_cur_angle - cos_outer_cone_angle) / cos_inner_minus_outer_angle, 0.0, 1.0); //**************************************************** vec3 N = normalize(normal); float lambertTerm = max( dot(N,L), 0.0); if(lambertTerm > 0.0) { final_color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * lambertTerm * spot; vec3 E = normalize(eyeVec); vec3 R = reflect(-L, N); float specular = pow( max(dot(R, E), 0.0), gl_FrontMaterial.shininess ); final_color += gl_LightSource[0].specular * gl_FrontMaterial.specular * specular * spot; } gl_FragColor = final_color;