Posts: 268Member

I want to write a custom light shader for water(so that light reflects off of the surface in little specks), but I haven't been able to find anything on light shaders. All I have is this:

``````DIFFUSE_LIGHT += dot(NORMAL, LIGHT) * ATTENUATION * ALBEDO;
``````

The default light shader would be a good place to start. Does anyone know where to learn about light shaders, or where I can find the default light shader?
Thanks.

I guess you have already looked at the following?

You might also want to look at some openGL/GLSL tutorials and cross reference with this:

• Posts: 769Moderator

Along with what @Megalomaniak has suggested, you can inspiration directly from Godot's shader code. More specifically here.

• Posts: 268Member

I don't know if I've seen the second page, very useful. I do have some questions:

• LIGHT is a vector. Is it the direction of the light?
• ATTENUATION is also a vector, what does that mean?
• Is NORMAL just the normal, or normal + normal map?
• How might specular light be calculated?
• Posts: 268Member

In the shader code @SIsilicon28 linked, I found the part where specular light is calculated(blinn):

``````    float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float blinn = pow(cNdotH, shininess) * cNdotL;
blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
float intensity = blinn;

specular_light += light_color * intensity * specular_blob_intensity * attenuation;
``````
• Posts: 769Moderator
edited May 2020

Judging from a glance, I believe that's
phong based specular.

• Posts: 268Member

I did some research on specular shaders, and I got this:

``````void light() {
DIFFUSE_LIGHT += dot(NORMAL, LIGHT) * ATTENUATION * ALBEDO;
vec3 H = normalize(VIEW + LIGHT);
float NdotH = max(0, dot(NORMAL, H));
float specular = pow(NdotH, specular_power) * specular_strength * ATTENUATION.x;
SPECULAR_LIGHT += specular * specular_color.rgb;
}
``````

I don't know why ATTENUATION is a vec3, so I used ATTENUATION.x.

If I set specular_power to a high value(10,000) and specular color to a high value(5,5,5), then I get closer to the effect I want:

I want it to look glittery, kind of the same way water glitters in the real world. Tell me if you have any suggestions.

• Posts: 268Member

Actually, I think it looks a little better with specular disabled entirely. I think it will look good enough if I make it a little glossier. I found

float fresnel = sqrt(1.0 - dot(NORMAL, VIEW));

can be used for a fresnel effect. Is there a way to adapt this to work with normal maps?

• Posts: 268Member
• Posts: 268Member

Additive bloom gives the correct result:

I like additive bloom better anyway, it just needs to be way softer than softlight. Fire shaders can look really nice with additive bloom, too.

• Posts: 268Member

``````void light() {
DIFFUSE_LIGHT += max(dot(NORMAL, LIGHT),0.0) * ATTENUATION * ALBEDO * LIGHT_COLOR;
vec3 H = normalize(VIEW + LIGHT);
float NdotH = max(0, dot(NORMAL, H));
float specular = pow(NdotH, specular_power) * specular_strength * ATTENUATION.x;
SPECULAR_LIGHT += specular*LIGHT_COLOR;
}
``````

First, I multiply both diffuse and specular light by LIGHT_COLOR.
Also,

``````dot(NORMAL, LIGHT)
``````

should be

``````max(dot(NORMAL, LIGHT),0.0)
``````

otherwise, if a light is behind the surface, it will get darker.