Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 330
- uniform mat4 projectionMatrix;
- uniform mat4 viewMatrix;
- uniform mat4 modelMatrix;
- uniform vec3 eyePos;
- in vec3 in_Position;
- in vec2 in_TextureCoord;
- in vec3 in_Normal;
- in vec4 in_Tangent;
- in float in_ModelOffset;
- in float in_TexOffset;
- out vec2 pass_TextureCoord;
- out float pass_TexOffset;
- out vec3 pass_toLightInTangentSpace;
- out vec3 pass_toCameraInTangentSpace;
- void main(void) {
- mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
- pass_TexOffset = in_TexOffset;
- pass_TextureCoord = in_TextureCoord;
- // transform to world space
- vec4 worldPosition = modelMatrix * vec4(in_Position, 1);
- vec3 worldNormal = normalize(normalMatrix * in_Normal);
- vec3 worldTangent = normalize(normalMatrix * in_Tangent.xyz);
- // calculate vectors to the camera and to the light, hardcoded for now
- vec3 worldDirectionToLight = normalize(vec3(0,10,0) - worldPosition.xyz);
- vec3 worldDirectionToCamera = normalize(eyePos - worldPosition.xyz);
- // calculate bitangent from normal and tangent
- vec3 worldBitangnent = cross(worldNormal, worldTangent) * in_Tangent.w;
- // transform direction to the light to tangent space
- pass_toLightInTangentSpace = vec3(
- dot(worldDirectionToLight, worldTangent),
- dot(worldDirectionToLight, worldBitangnent),
- dot(worldDirectionToLight, worldNormal)
- );
- // transform direction to the camera to tangent space
- pass_toCameraInTangentSpace= vec3(
- dot(worldDirectionToCamera, worldTangent),
- dot(worldDirectionToCamera, worldBitangnent),
- dot(worldDirectionToCamera, worldNormal)
- );
- // calculate screen space position of the vertex
- gl_Position = projectionMatrix * viewMatrix * worldPosition;
- }
- #version 330
- const int NUM_TEXTURES = 2;
- uniform sampler2DArray diffuseTexture;
- uniform vec3 ambientColor;
- uniform float specularIntensity;
- uniform float specularPower;
- uniform float renderNormal;
- uniform float height_scale;
- in vec2 pass_TextureCoord;
- in float pass_TexOffset;
- in vec3 pass_toLightInTangentSpace;
- in vec3 pass_toCameraInTangentSpace;
- out vec4 out_Color;
- const float parallaxScale = 0.1;
- //////////////////////////////////////////////////////
- // Implements Parallax Mapping technique
- // Returns modified texture coordinates, and last used depth
- vec2 parallaxMapping(in vec3 V, in vec2 T, out float parallaxHeight)
- {
- // determine optimal number of layers
- const float minLayers = 10;
- const float maxLayers = 15;
- float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0, 0, 1), V)));
- // height of each layer
- float layerHeight = 1.0 / numLayers;
- // current depth of the layer
- float curLayerHeight = 0;
- // shift of texture coordinates for each layer
- vec2 dtex = parallaxScale * V.xy / V.z / numLayers;
- // current texture coordinates
- vec2 currentTextureCoords = T;
- // depth from heightmap
- float heightFromTexture = texture(diffuseTexture, vec3(currentTextureCoords, pass_TexOffset+1)).a;
- // while point is above the surface
- while(heightFromTexture > curLayerHeight)
- {
- // to the next layer
- curLayerHeight += layerHeight;
- // shift of texture coordinates
- currentTextureCoords -= dtex;
- // new depth from heightmap
- heightFromTexture = texture(diffuseTexture, vec3(currentTextureCoords, pass_TexOffset+1)).a;
- }
- ///////////////////////////////////////////////////////////
- // previous texture coordinates
- vec2 prevTCoords = currentTextureCoords + dtex;
- // heights for linear interpolation
- float nextH = heightFromTexture - curLayerHeight;
- float prevH = texture(diffuseTexture, vec3(prevTCoords, pass_TexOffset+1)).a
- - curLayerHeight + layerHeight;
- // proportions for linear interpolation
- float weight = nextH / (nextH - prevH);
- // interpolation of texture coordinates
- vec2 finalTexCoords = prevTCoords * weight + currentTextureCoords * (1.0-weight);
- // interpolation of depth values
- parallaxHeight = curLayerHeight + prevH * weight + nextH * (1.0 - weight);
- // return result
- return finalTexCoords;
- }
- //////////////////////////////////////////////////////
- // Implements self-shadowing technique - hard or soft shadows
- // Returns shadow factor
- float parallaxSoftShadowMultiplier(in vec3 L, in vec2 initialTexCoord,
- in float initialHeight)
- {
- float shadowMultiplier = 1;
- const float minLayers = 15;
- const float maxLayers = 30;
- // calculate lighting only for surface oriented to the light source
- if(dot(vec3(0, 0, 1), L) > 0)
- {
- // calculate initial parameters
- float numSamplesUnderSurface = 0;
- shadowMultiplier = 0;
- float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0, 0, 1), L)));
- float layerHeight = initialHeight / numLayers;
- vec2 texStep = parallaxScale * L.xy / L.z / numLayers;
- // current parameters
- float currentLayerHeight = initialHeight - layerHeight;
- vec2 currentTextureCoords = initialTexCoord + texStep;
- float heightFromTexture = texture(diffuseTexture, vec3(currentTextureCoords, pass_TexOffset+1)).a;
- int stepIndex = 1;
- // while point is below depth 0.0 )
- while(currentLayerHeight > 0)
- {
- // if point is under the surface
- if(heightFromTexture < currentLayerHeight)
- {
- // calculate partial shadowing factor
- numSamplesUnderSurface += 1;
- float newShadowMultiplier = (currentLayerHeight - heightFromTexture) *
- (1.0 - stepIndex / numLayers);
- shadowMultiplier = max(shadowMultiplier, newShadowMultiplier);
- }
- // offset to the next layer
- stepIndex += 1;
- currentLayerHeight -= layerHeight;
- currentTextureCoords += texStep;
- heightFromTexture = texture(diffuseTexture, vec3(currentTextureCoords, pass_TexOffset+1)).a;
- }
- // Shadowing factor should be 1 if there were no points under the surface
- if(numSamplesUnderSurface < 1)
- {
- shadowMultiplier = 1;
- }
- else
- {
- shadowMultiplier = 1.0 - shadowMultiplier;
- }
- }
- return shadowMultiplier;
- }
- //////////////////////////////////////////////////////
- // Calculates lighting by Blinn-Phong model and Normal Mapping
- // Returns color of the fragment
- vec4 normalMappingLighting(in vec2 T, in vec3 L, in vec3 V, float shadowMultiplier)
- {
- // restore normal from normal map
- vec3 N = normalize(texture(diffuseTexture, vec3(T, pass_TexOffset+1)).xyz * 2 - 1);
- vec3 D = texture(diffuseTexture, vec3(T, pass_TexOffset)).rgb;
- // ambient lighting
- float iamb = 0.2;
- // diffuse lighting
- float idiff = clamp(dot(N, L), 0, 1);
- // specular lighting
- float ispec = 0;
- if(dot(N, L) > 0.2)
- {
- vec3 R = reflect(-L, N);
- ispec = pow(dot(R, V), 32) / 1.5;
- }
- vec4 resColor;
- resColor.rgb = D * (vec3(0.1, 0.1, 0.1) + (idiff + ispec) * pow(shadowMultiplier, 4));
- resColor.a = 1;
- return resColor;
- }
- /////////////////////////////////////////////
- // Entry point for Parallax Mapping shader
- void main(void)
- {
- // normalize vectors after vertex shader
- vec3 V = normalize(pass_toCameraInTangentSpace);
- vec3 L = normalize(pass_toLightInTangentSpace);
- // get new texture coordinates from Parallax Mapping
- float parallaxHeight;
- vec2 T = parallaxMapping(V, pass_TextureCoord, parallaxHeight);
- // get self-shadowing factor for elements of parallax
- float shadowMultiplier = parallaxSoftShadowMultiplier(L, T, parallaxHeight - 0.05);
- // calculate lighting
- out_Color = normalMappingLighting(T, L, V, shadowMultiplier);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement