Last active
November 21, 2020 05:53
-
-
Save yearofthewhopper/5a1c3974ec20bd47fc46ec14ea64d535 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// adam ferris found it: | |
#import <lights> | |
struct PhongMaterialParameters { | |
vec3 emission; | |
vec3 ambientFactor; | |
vec3 diffuseFactor; | |
vec3 specularFactor; | |
float shininess; | |
float occlusion; | |
}; | |
vec3 applyPhong( | |
std::LightData light, | |
vec3 normal, | |
vec3 view, | |
PhongMaterialParameters material) { | |
vec3 reflected = -reflect(light.toLightDirection, normal); | |
float LdotN = dot(light.toLightDirection, normal); | |
float RdotV = max(dot(reflected, view), 0.0); | |
float diffuseFactor = max(LdotN, 0.0); | |
vec3 diffuse = material.diffuseFactor * (light.intensity * diffuseFactor); | |
float specularFactor = pow(RdotV, material.shininess) * step(0.0, LdotN); // do not light backface | |
vec3 specular = material.specularFactor * (light.intensity * specularFactor); | |
return material.occlusion * diffuse + specular; | |
} | |
// A material that uses the Phong shading model. | |
// | |
// @param [default=0.0, min=0.0, max=100.0] smoothness | |
void main( optional <std::Texture2d> diffuseTexture, | |
optional <std::Texture2d> normalTexture, | |
optional <std::Texture2d> specularTexture, | |
optional <std::Texture2d> emissiveTexture, | |
float smoothness, | |
out vec4 Position, | |
out vec4 Color) { | |
float shininess = mix(1.0, 100.0, pow(smoothness * 0.01, 2.0)); // non-linear mapping from [0,100] to [1,100] | |
// Attributes | |
vec2 uv = std::getVertexTexCoord(); | |
vec4 n = normalTexture.sample(uv).valueOr(vec4(std::getVertexNormal(),0.0)); | |
vec3 sampledNormal = normalize(std::getTangentFrame() * n.xyz * 2.0 - 1.0); | |
vec3 localNormal = sampledNormal; | |
vec4 localPosition = std::getVertexPosition(); | |
// Material parameters | |
vec4 diffuseAndOpacity = diffuseTexture.sample(uv).valueOr(vec4(1.0)); | |
vec4 specularAndShininess = specularTexture.sample(uv).valueOr(vec4(1.0)); | |
PhongMaterialParameters material; | |
material.emission = emissiveTexture.sample(uv).rgb.valueOr(vec3(0.0)); | |
material.ambientFactor = diffuseAndOpacity.rgb; | |
material.diffuseFactor = diffuseAndOpacity.rgb; | |
material.specularFactor = specularAndShininess.rgb; | |
material.shininess = clamp(specularAndShininess.a * shininess, 1.0, 100.0); | |
material.occlusion = 1.0; | |
// Screen-space position | |
Position = std::getModelViewProjectionMatrix() * localPosition; | |
// Camera-space normal, position, and view | |
vec3 csNormal = normalize(fragment(std::getNormalMatrix() * localNormal)); | |
vec4 csPosition = fragment(std::getModelViewMatrix() * localPosition); | |
vec3 csView = normalize(-csPosition.xyz); // csCamera is at vec3(0,0,0) | |
// color | |
vec3 color = material.emission + material.ambientFactor * std::getAmbientLight().rgb; | |
if (std::getActiveLightCount() > 0) color += applyPhong(std::getLightData0(csPosition.xyz), csNormal, csView, material); | |
if (std::getActiveLightCount() > 1) color += applyPhong(std::getLightData1(csPosition.xyz), csNormal, csView, material); | |
if (std::getActiveLightCount() > 2) color += applyPhong(std::getLightData2(csPosition.xyz), csNormal, csView, material); | |
if (std::getActiveLightCount() > 3) color += applyPhong(std::getLightData3(csPosition.xyz), csNormal, csView, material); | |
Color = vec4(color, diffuseAndOpacity.a); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment