Optimized GGX specular shader (godot 3.x)

ported from John Hale (@FilmicWorlds)

http://www.twitter.com/@filmicworlds

http://filmicworlds.com/blog/optimizing-ggx-shaders-with-dotlh/

Shader code
shader_type spatial;
render_mode ambient_light_disabled;
//render_mode skip_vertex_transform;

uniform sampler2D _albedo:hint_albedo;
varying vec4 vector_ws;
varying vec4 vector_os;

float pow_4(float x)
{
	return x*x*x*x;
}

float saturate_f(float x)
{
	return max(0,min(1,x));
	
}

float LightingFuncGGX_OPT4(vec3 N, vec3 V, vec3 L, float roughness, float F0)
{
	vec3 H = normalize(V+L);
	float nDotL = saturate_f(dot(N,L));
	float lDotH = saturate_f(dot(L,H));
	float nDotH = saturate_f(dot(N,H));

	float D = texture(_albedo, vec2(nDotH)+roughness).x;//textureLod(_albedo, vec2(nDotH),roughness).x;
	vec2 FV_helper = texture(_albedo, vec2(lDotH)+roughness).yz;//textureLod(_albedo, vec2(lDotH),roughness).yz;
	
	float FV = F0*FV_helper.x + (1.0-F0)*FV_helper.y;
	float specular = nDotL * D*FV;
	
	return specular;
}

float LightingFuncGGX_OPT4_T(vec3 N, vec3 V, vec3 L, float roughness, float F0,sampler2D _texture)
{
	vec3 H = normalize(V+L);
	float nDotL = saturate_f(dot(N,L));
	float lDotH = saturate_f(dot(L,H));
	float nDotH = saturate_f(dot(N,H));

	float D = texture(_texture, vec2(nDotH)+roughness).x;//textureLod(_albedo, vec2(nDotH),roughness).x;
	vec2 FV_helper = texture(_texture, vec2(lDotH)+roughness).yz;//textureLod(_albedo, vec2(lDotH),roughness).yz;
	
	float FV = F0*FV_helper.x + (1.0-F0)*FV_helper.y;
	float specular = nDotL * D*FV;
	
	return specular;
}


vec3 saturate_v3(vec3 value)
{
	vec3 result;
	result.x = max(0,min(1,value.x));
	result.y= max(0,min(1,value.y));
	result.z== max(0,min(1,value.z));
	return result;
}

void vertex()
{
	vector_os.xyz = VERTEX;
	vector_ws= WORLD_MATRIX* vec4(vector_os.xyz,1.0);

}



void light()

{
vec3 i = ATTENUATION;
vec3 l = LIGHT;
vec3 n = NORMAL;

vec3 viewDirection= normalize(CAMERA_MATRIX[3]-vector_ws).xyz;

float roughness=ROUGHNESS;

vec3 optimizedGGX = vec3(LightingFuncGGX_OPT4(n,viewDirection,l,roughness,dot(WORLD_MATRIX[3].xyz,LIGHT)));

SPECULAR_LIGHT += optimizedGGX.xyz;

}
Live Preview
Tags
ggx, light, lighting, pbr, Spatial
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from FP2

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments