OpenGL ES on iOS

The paper

In this paper, I recorded my study of coordinate system and matrix transformation process, deepen learning is convenient for follow-up query, may be some description is not accurate, or the content is not enough, please correct, learn together.

The light source classification

In basic lighting, I learned the effect of light on objects, which is equivalent to the material of objects. This time, I mainly talked about the light source in real life

Parallel light

When a source is infinitely far away, light from it can be approximated as parallel light (such as the sun); The light rays are going in the same direction.

 floatAmbientStrength = 0.3; // Environmental factorsfloatSpecularStrength = 2.0;floatReflectance = 256.0; // paraLightDir = normalize(vec3(-0.2,-1.0,-0.3)); Vec3 ambient = ambientStrength * texture(texture,outTexCoord).rgb; // vec3 norm = normalize(outNormal); vec3 lightDir = normalize(lightPo - FragPo); // The unit vector from the current vertex to the light sourcefloatThe diff = Max (dot (norm, paraLightDir), 0.0); vec3 diffuse = diff * lightColor*texture(Texture,outTexCoord).rgb; Vec3 viewDir = normalize(viewpo-fragpo); vec3 reflectDir = reflect(-paraLightDir,outNormal);floatThe class = pow (Max (dot (viewDir, reflectDir), 0.0), the reflectance); vec3 specular = specularStrength * spec * texture(specularTexture,outTexCoord).rgb; // The light fadesfloatConstantPara = 1.0 f;floatLinearPara = 0.09 f;floatQuadraticPara = 0.032 f;float LFDistance = length(lightPo - FragPo);
    floatLightWeakPara = 1.0/(constantPara + linearPara *LFDistance + quadraticPara * (LFDistance*LFDistance)); vec3 res = ambient + diffuse + specular; FragColor = vec4 (res, 1.0);Copy the code

A point source

Point light source is a relatively normal light source, light from the light source scattered, light vector is equal to the light source to the object vector.

    floatAmbientStrength = 0.3; // Environmental factorsfloatSpecularStrength = 2.0;floatReflectance = 256.0;floatConstantPara = 1.0 f; / / normally onfloatLinearPara = 0.09 f; // Linear partial factorfloatQuadraticPara = 0.032 f; Vec3 ambient = ambientStrength * texture(texture,outTexCoord).rgb; // vec3 norm = normalize(outNormal); vec3 lightDir = normalize(lightPo - FragPo); // The unit vector from the current vertex to the light source // point light sourcefloatThe diff = Max (dot (norm, lightDir), 0.0); Vec3 diffuse = diff * lightColor*texture(texture,outTexCoord).rgb; Vec3 viewDir = normalize(viewpo-fragpo); vec3 reflectDir = reflect(-lightDir,outNormal);floatThe class = pow (Max (dot (viewDir, reflectDir), 0.0), the reflectance); vec3 specular = specularStrength * spec * texture(specularTexture,outTexCoord).rgb;float LFDistance = length(lightPo - FragPo);
    floatLightWeakPara = 1.0/(constantPara + linearPara *LFDistance + quadraticPara * (LFDistance*LFDistance)); vec3 res = (ambient + diffuse + specular)*lightWeakPara; FragColor = vec4 (res, 1.0);Copy the code

Concentrated source

The concentrator works like a flashlight, like a point light source directed toward a specified area

When using a spotlight source, you need to specify the orientation of the spotlight toward the SpotDir and the cutting Angle ϕ. When the Angle between the light source’s pointing vector and the SpotDir is greater than ϕ, the light cannot reach it.

But the boundary between light and dark is too stark to be realistic

In this case, we need to smooth out the transition edges, and then we need to introduce two parameters, the inner cone Angle and the outer cone Angle. The outer cone Angle is the light cutting Angle, and the inner cone Angle does not need smoothing effect, between the inner cone Angle and the outer cone Angle need smoothing. The following code

/(Some complex calculation operations should be done by THE CPU, improve efficiency, the same amount of external transmission is also recommended to avoid repeated calculation)float inCutOff = cos (radians (10.0 f)); // Inner cone Angle cos valuefloatOutCutOff = cos (radians (15.0 f)); Vec3 spotDir = vec3(-1.2f,-1.0f,-2.0f); // Focus orientationfloattheta = dot(lightDir,normalize(-spotDir)); // The vector of the light source pointing to the object and the cosine of the concentrating directionfloat epsilon  = inCutOff - outCutOff; // Clamp (a,b,c); If b<a<c the function returns a if not, the minimum return value is b and the maximum return value is c // (theta-outcutoff)/epsilon If the Angle of Theta is less than the inner cone Angle >=1 and the Angle of Theta is greater than the outer cone Angle <=0 In this way the light changes smoothly between the inner and outer cone angles.floatIntensity = clamp((theta - outCutOff)/ Epsilon,0.0,1.0);Copy the code

Weak light

In reality, the light emitted by the light source will decay with the increase of the distance, and it is not linear attenuation, which is manifested in that the attenuation is faster in the distance near the light source, and slower in the distance from the light source. This formula is often used to simulate light attenuation.

Constant term usually stay for 1.0, its main function is to guarantee the denominator never be smaller than 1, otherwise in some distance and it can increase the strength, it’s definitely not what we want A will and the distance value multiplication, will reduce the intensity of secondary items in a linear fashion and is multiplied by the square of the distance, let the light in the form of quadratic regressive reduce intensity. The quadratic term matters a lot less than the first term when the distance is small, but it matters a lot more when the distance is large

    float LFDistance = length(lightPo - FragPo);
    floatLightWeakPara = 1.0/(constantPara + linearPara *LFDistance + quadraticPara * (LFDistance*LFDistance)); vec3 res = (ambient + diffuse + specular)*lightWeakPara;Copy the code

The light map

In a texture map, depending on the material, the effect will be different, as in the case below, metal frame and wood under the same light will definitely be different.

In order to distinguish lighting effects from each other when displaying them, the concept of light mapping should be introduced ~ as shown below

In this map, the corresponding wood part is black VEC3 (0.0); The metal frame is gray, so that it can be used as a reference coefficient when calculating diffuse or specular reflection, so that it can present a different effect.

vec3 spe = texture(specularTexture,outTexCoord).rgb; Vec3 viewDir = normalize(viewpo-fragpo); vec3 viewDir = normalize(viewpo-fragpo); vec3 reflectDir = reflect(-lightDir,outNormal);floatThe spec = pow (Max (dot (viewDir, reflectDir), 0.0), spL. Reflectance); vec3 specular = point_specularStrength * spec * spe; // Use light map textureCopy the code