---
title: "GLSL Support"
canonical: "https://documentation.chaos.com/space/VMAX/113575804/GLSL%20Support"
format: markdown
---
##  **Overview** 

---

##  **Additional Preprocessor Defines** 

---

`__VRAY_GLSL__=110`

`__VRAY_HOST__=300`


## **Additional Type Qualifiers**

---

`__channel`

```
#version 110
 
__channel vec2 UVSpace = vec2(0.314);
void main() {
  UVSpace = vec2(gl_TexCoord[0]);
  gl_FragColor = vec4(0.3, 0.8, 0.2, 1.0);
}
```

`__persistent`

```
#version 110
 
__persistent __channel vec2 UVSpace = vec2(0.314);
 
void main() {
  UVSpace = vec2(gl_TexCoord[0]);
  discard;
  gl_FragColor = vec4(0.3, 0.8, 0.2, 1.0);
}
```

`__color`

```
#version 110
 
__color uniform vec3 input_color = vec3(1.0, 0.5, 0.25);
 
uniform float alpha = 1.0;
uniform float gamma = 1.0;
 
void main() {
  gl_FragColor = vec4(pow(input_color, vec3(1.0 / gamma)), alpha);
}
```

##  **Built-In Varying Variables** 

---

```
varying vec4 gl_TexCoord[16];
```

```
varying vec3 vr_Position;
```

```
varying vec3 vr_Normal;
```

```
varying vec3 vr_TexTangent;
```

```
varying vec3 vr_TexBinormal;
```

```
varying vec3 vr_Direction;
```

```
varying vec3 vr_Velocity;
```

```
varying int vr_TotalRayDepth;
```

```
varying int vr_DiffuseRayDepth;
```

```
varying int vr_NumSuperSamples;
```

```
varying int vr_SuperSampleIndex;
```

```
varying int vr_RayFlags;
```

```
varying vec3 vr_Origin;
```

```
varying vec3 vr_GeomNormal;
```

```
varying vec3 vr_TextureDu[16];
```

```
varying vec3 vr_TextureDv[16];
```

 

## **Built-In Uniform Variables** 

---

```
uniform int vr_NumLights;
```

```
uniform mat4 vr_CameraToWorld;
```

```
uniform mat4 vr_WorldToCamera;
```

```
uniform mat4 vr_CameraToObject;
```

```
uniform mat4 vr_ObjectToCamera;
```

```
uniform vr_FrameDataSettings vr_FrameData;
```


##  **Built-In Constants** 

---

```
const int VR_TRACE_REFRACT;
```

```
const int VR_TRACE_REFLECT;
```

```
const int VR_TRACE_TRANSPARENT;
```

```
const int VR_TRACE_ENVIRONMENT;
```

```
const int VR_REFLECT_FLAG;
```

```
const int VR_REFRACT_FLAG;
```

```
const int VR_SHADOW_FLAG;
```

```
const int VR_INDIRECT_FLAG;
```

```
const int VR_GLOSSY_FLAG;
```

```
const int VR_ENVIRONMENT_FLAG;
```

```
const int VR_SPECULAR_DISPERSAL;
```

```
const int VR_GLOSSY_DISPERSAL;
```

```
const int VR_DIFFUSE_DISPERSAL;
```


##  **Built-In Types** 

---

```
struct vr_LightIterator {
	vec3 direction; // unit vector pointing towards the light source in camera coordinates.
	float dot_nl; // dot product of the surface normal (possibly bumped) and the light direction.
	vec3 contribution; // the direct light contribution from this light including atmospheric effects and distance falloff.
};
```

```
struct vr_FrameDataSettings {
	int frameIndex; // Current frame index.
	float frameTime; // Time of the current frame in ticks.
	float frameStart; // Start of the frame in time. Usually frameStart <= frameTime <= frameEnd.
	float frameEnd; // End of the frame in time. Usually frameStart <= frameTime <= frameEnd.
	bool isOrthographic; // True if camera rays are parallel.
	float focalLength; // The camera's focal length.
	float aperture; // The camera's aperture.
	float aspectRatio; // The pixel aspect ratio.
	vec2 imagePlaneOffset; // The camera plane offset.
	float dofRadius; // The depth of field radius.
	float dofFocus; // The distance from the camera position to the focal plane.
	ivec2 imageResolution; // Width and height of the entire output image in pixels ignoring the render region.
	ivec4 regionMargin; // Render region margin in pixels.
};
```

```
struct vr_Color {
	float r; // Red color component.
	float g; // Green color component.
	float b; // Blue color component.
	float a; // Alpha color component.
};
```

```
uniform vr_Color diffuse_color = vr_Color(0.9, 0.2, 0.8, 1.0);
```

```
struct vr_DiffuseBRDFSettings {
	vec3 color; // The diffuse color for the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	vec3 normal; // The normal for which to calculate the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	float roughness; // Diffuse deviation in the [0.0, 1.0] range. Default value is 0.0.
	vec3 transparency; // The transparency of the BRDF. Default value is vec3(0.0, 0.0, 0.0).
};
```

```
struct vr_GlossyBRDFSettings {
	vec3 color; // The specular(reflection) color for the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	vec3 normal; // The normal for which to calculate the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	float highlightGlossiness; // Highlight glossiness of the BRDF in the [0.0, 1.0] range. Default value is 0.7.
	float reflectionGlossiness; // Reflection glossiness of the BRDF in the [0.0, 1.0] range. Default value is 0.7.
	int subdivs; // Amount of samples for the glossy reflection. Default value is 8.
	float anisotropy; // Anisotropy of the BRDF in the (-1.0, 1.0) range. Default value is 0.0.
	bool traceReflections; // Set if the BRDF should trace reflections. Default value is true.
	vec3 transparency; // The transparency of the BRDF. Default value is vec3(0.0, 0.0, 0.0).
	float softenEdge; // Amount of softening the transition from dark to bright areas in specular reflections in the [-1.0, 1.0] range. Default value is 0.001.
	float anisoRotation; // Rotation of the BRDF anisotropy in degrees. Default value is 0.0.
};
```

```
struct vr_MirrorBRDFSettings {
	vec3 color; // Filter color of the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	vec3 normal; // The normal for which to calculate the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	vec3 transparency; // The transparency of the BRDF. Default value is vec3(0.0, 0.0, 0.0).
};
```

```
struct vr_GlassBRDFSettings {
	vec3 color; // Filter color of the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	vec3 normal; // The normal for which to calculate the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	float glossiness; // Glossiness of the BRDF in the [0.0, 1.0] range. Default value is 0.7.
	float ior; // Surface index of refraction for the BRDF. Default value is 1.5.
	int subdivs; // Amount of samples for the glossy reflections/refraction. Default value is 8.
	vec3 transparency; // The transparency of the BRDF. Default value is vec3(0.0, 0.0, 0.0).
};
```

```
struct vr_LightBRDFSettings {
	vec3 color; // Light color of the BRDF. Default value is vec3(1.0, 1.0, 1.0).
	vec3 transparency; // The transparency of the BRDF. Default value is vec3(0.0, 0.0, 0.0).
	bool doubleSided; // Makes the BRDF double sided. Default value is false.
	bool emitOnBackSide; // Makes the BRDF emit light from its back side as well. If this is off, the material is rendered as black on the back sides. Default value is true.
};
```

```
struct vr_TraceOptions {
	int rayType; // One of the built-in constants VR_TRACE_REFLECT, VR_TRACE_REFRACT, VR_TRACE_TRANSPARENT or VR_TRACE_ENVIRONMENT. See Built-in constants. Default values is VR_TRACE_REFLECT.
	int rayGroup; // One of the VR_SPECULAR_DISPERSAL or VR_GLOSSY_DISPERSAL built-in constants. See Built-in constants. Default value is VR_SPECULAR_DISPERSAL.
	float ior; // Surface index of refraction at the current hit point. Ignored unless tracing a refracted ray. Default value is 1.44.
	vec3 ray; // User specified ray to be traced. Must be a unit vector in camera space. Default value is vec3(0.0, 0.0, 0.0).
	vec3 normal; // The surface normal (possibly bumped) according to which the reflections/refraction will be calculated. Must be a unit vector in camera space. Default value is vec3(0.0, 0.0, 0.0).
};
```

```
struct vr_OcclusionOptions {
	float radius; // This parameters determines the amount of area (in units) where the ambient occlusion is calculated. Default value is 10.0.
	float distribution; // This parameter forces the sampling rays to gather closer to the surface normal. For evenly distributed samples use 0.0. For maximum surface normal concentrated sampling use 1.0. Allowed value range is [0.0, 1.0]. Default value is 0.0.
	float falloff; // This parameter controls the speed of the transition between occluded and unoccluded areas. Default value is 0.0.
	int subdivs; // This parameter holds the number of samples that V-Ray takes to calculate the occlusion effect. Lower values render faster but produce a more noisy result. Default value is 8.
};
```


##  **Built-In Functions** 

---

```
void vr_evalLight(int lightIndex, vec3 position, vec3 normal, out vr_LightIterator light);
```

```
vec4 vr_trace(vr_TraceOptions traceOptions);
```

```
vec3 vr_irradiance(vec3 normal, float importance);
```

```
vec3 vr_randomSample(int sampleIndex, int totalSamples)
```

```
vec3 vr_textureSize(sampler1D sampler);
```

```
float vr_occlusion(vr_OcclusionOptions options);
```

```
vec4 textureCube(samplerCube sampler, vec3 sampleDir);
```


## **Built-in BRDF functions**

---

```
void vr_brdf_diffuse(vr_DiffuseBRDFSettings brdfSettings);
```

```
void vr_brdf_phong(vr_GlossyBRDFSettings brdfSettings);
```

```
void vr_brdf_blinn(vr_GlossyBRDFSettings brdfSettings);
```

```
void vr_brdf_ward(vr_GlossyBRDFSettings brdfSettings);
```

```
void vr_brdf_glass(vr_GlassBRDFSettings brdfSettings);
```

```
void vr_brdf_mirror(vr_MirrorBRDFSettings brdfSettings);
```

```
void vr_brdf_light(vr_LightBRDFSettings brdfSettings);
```


##  **Unsupported GLSL Features** 

---

```
vec3 tangent = vr_TexTangent;
vec3 binormal = vr_TexBinormal;
vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
mat3 vr_TextureToCamera = mat3(tangent, binormal, normal);
```


## **GPU Support**

---

| **Feature** | **GPU Support** |
| --- | --- |
| **Built-in variables** |
| **gl_NormalMatrix ** | Always identity matrix. |
| **gl_ModelViewMatrixTranspose ** | Always identity matrix. |
| **gl_TextureMatrix ** | Always identity matrix. |
| **gl_TextureMatrixInverse ** | Always identity matrix. |
| **gl_TextureMatrixInverseTranspose** | Always identity matrix. |
| **gl_TextureMatrixTranspose** | Always identity matrix. |
| **gl_ModelViewMatrixInverseTranspose ** | Always identity matrix. |
| **gl_FogFragCoord ** | Always is a zero.> Macro (anchor) |
| **gl_TexCoord[] ** | All gl_TexCoord[] elements are identical, i.e. multiple UVW channels are not supported. <sup>[1](#1)</sup> |
| **Built-in functions** |
| **dFdx(); dFdy() ** | Always return zero. |
| **fwidth() ** | Always returns zero. |
| **V-Ray extensions to GLSL** |
| **vr_Velocity ** | Always is a zero. |
| **vr_NumSuperSamples ** | Always is 1. |
| **vr_SuperSampleIndex ** | Always is 1. |
| **vr_TextureDu[] ** | Not supported. |
| **vr_TextureDv[] ** | Not supported. |
| **vr_VertexData[] ** | Not supported. |
| **vr_FrameData ** | Only the following are supported:<br>vr_FrameData.focalLength  
vr_FrameData.aperture  
vr_FrameData.dofFocus  
vr_FrameData.dofRadius  
vr_FrameData.imageResolution  
vr_FrameData.imagePlaneOffset |
| ** vr_trace() ** | Not supported. |
| **vr_evalLight() ** | Not supported. If attempted to call it will assign the following constants to the output light iterator:<br>light.dot_nl = -1.0  
light.contribution = vec3(0.0, 0.0, 0.0)  
light.direction = vec3(0.0, 0.0, 0.0) |
| ** vr_intersect() ** | > Macro (anchor)

 Not supported. |
| **BRDF** | Only the following BRDF calls are supported <sup>[2](#2)</sup>:<br>vr_brdf_diffuse()  
vr_brdf_glass()  
vr_brdf_mirror()  
vr_brdf_ggx() |
| **Keywords** | The following keywords are ignored:<br>__channel<br>__persistent |


## **Examples** 

---

###  **Example: Cool Metallic** 

```
#version 110

__color uniform vec4 front_color = vec4(1.0, 1.0, 0.0, 1.0);
__color uniform vec4 background_color = vec4(1.0, 0.0, 1.0, 1.0);
uniform float amount = 0.8;
uniform float diffuse_scalar = 0.7;
uniform float specular_scalar = 0.06;
uniform float specular_shininess = 200.0;

float phong_specular(vec3 light_dir, vec3 view_dir, vec3 normal, float specular_shininess) {
	vec3 reflection = reflect(view_dir, normal);
	float cos_rl = clamp(dot(reflection, light_dir), 0.0, 1.0);
	return (pow(cos_rl, specular_shininess) * (specular_shininess + 2.0));
}

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec3 position = vr_Position;
	vec3 direction = vr_Direction;
 
	float dot_dn = clamp(-dot(direction, normal), 0.0, 1.0);
	float mix_value = 1.0 - pow(dot_dn, 1.0 / amount);
 
	vec4 diffuse_color = mix(front_color, background_color, mix_value);
	vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);
 
	vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
	vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);
 
	vec4 raw_diffuse = vec4(vec3(diffuse_color) * diffuse_scalar, 1.0);
	vec4 raw_specular = vec4(vec3(specular_color) * specular_scalar, 1.0);

	vec4 temp = raw_diffuse + raw_specular;
	float max_color_comp = max(max(temp.r,temp.g),temp.b);
	if (max_color_comp > 1.0) {
		raw_diffuse.rgb /= max_color_comp;
		raw_specular.rgb /= max_color_comp;
	}
 
	vr_LightIterator light;
	for (int i = 0; i < vr_NumLights; ++i) {
		vr_evalLight(i, position, normal, light);
		float cos_nl = clamp(light.dot_nl, 0.0, 1.0);
		if (cos_nl > 0.0) {
			diffuse += vec4(vec3(cos_nl) * light.contribution, 0.0);
			float specular_coeff = phong_specular(light.direction, direction, normal, specular_shininess);
			specular += vec4(vec3(specular_coeff * cos_nl) * light.contribution, 0.0);
		}
	}

	diffuse *= raw_diffuse;
	specular *= raw_specular;
 
	vec3 gi_contribution = vr_irradiance(normal, 1.0);
	diffuse += vec4(raw_diffuse.rgb * gi_contribution, 0.0);
 
	gl_FragColor = diffuse + specular;
}
```


---

### **Example: Generator Stripe**


```
#version 110

__color uniform vec4 strip_color = vec4(1.0, 0.5, 1.0, 1.0);
__color uniform vec4 background_color = vec4(1.0, 1.0, 0.2, 1.0);
uniform float width = 0.5;
uniform float fuzz = 0.5;
uniform float scale = 5.0;
uniform float diffuse_scalar = 0.7;
uniform float specular_scalar = 0.06;
uniform float specular_shininess = 10.0;
 
float phong_specular(vec3 light_dir, vec3 view_dir, vec3 normal, float specular_shininess) {
	vec3 reflection = reflect(view_dir, normal);
	float cos_rl = clamp(dot(reflection, light_dir), 0.0, 1.0);
	return (pow(cos_rl, specular_shininess) * (specular_shininess + 2.0));
}

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec3 position = vr_Position;
	vec3 direction = vr_Direction;
 
	float scaled_coord_t = fract(gl_TexCoord[0].t * scale);
	float fract1 = clamp(scaled_coord_t / fuzz, 0.0, 1.0);
	float fract2 = clamp((scaled_coord_t - width) / fuzz, 0.0, 1.0);
 
	fract1 *= (1.0 - fract2);
	fract1 = smoothstep(0.0, 1.0, fract1);
 
	vec4 diffuse_color = mix(strip_color, background_color, fract1);
	vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);
 
	vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
	vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);
	vec4 raw_diffuse = vec4(vec3(diffuse_color) * diffuse_scalar, 1.0);
	vec4 raw_specular = vec4(vec3(specular_color) * specular_scalar, 1.0);

	vec4 temp = raw_diffuse + raw_specular;
	float max_color_comp = max(max(temp.r,temp.g),temp.b);
	if (max_color_comp > 1.0) {
		raw_diffuse.rgb /= max_color_comp;
		raw_specular.rgb /= max_color_comp;
	}
 
	vr_LightIterator light;
	for(int i = 0; i < vr_NumLights; ++i) {
		vr_evalLight(i, position, normal, light);
		float cos_nl = clamp(light.dot_nl, 0.0, 1.0);
		if (cos_nl > 0.0) {
			diffuse += vec4(vec3(cos_nl) * light.contribution, 0.0);
			float specular_coeff = phong_specular(light.direction, direction, normal, specular_shininess);
			specular += vec4(vec3(specular_coeff * cos_nl) * light.contribution, 0.0);
		}
	}
 
	diffuse *= raw_diffuse;
	specular *= raw_specular;
 
	vec3 gi_contribution = vr_irradiance(normal, 1.0);
	diffuse += vec4(raw_diffuse.rgb * gi_contribution, 0.0);
 
	gl_FragColor = diffuse + specular;
}
```


---

### **Example: Glossy Glass** 


```
#version 110

const int requiredSamples = 8;

uniform float refraction_ior = 1.44;
uniform float amount = 0.1;
uniform float blend = 1.0;

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec3 direction = vr_Direction;

	vr_TraceOptions options;
	options.rayGroup = VR_SPECULAR_DISPERSAL;
	options.ior = refraction_ior;
	options.normal = normal;

	if((vr_RayFlags & VR_INDIRECT_FLAG) != 0) {
		options.rayType = VR_TRACE_REFLECT;
		vec4 reflection = vr_trace(options);

		options.rayType = VR_TRACE_REFRACT;
		vec4 refraction = vr_trace(options);

		float cos_dn = clamp(-dot(direction, normal), 0.0, 1.0);
		float lerpFactor = (1.0 - pow(cos_dn, 1.0 / blend));
		gl_FragColor = mix(refraction, reflection, lerpFactor);

		return;
	}

	vec3 tangent = vr_TexTangent;
	vec3 binormal = vr_TexBinormal;
	int numSuperSamples = vr_NumSuperSamples;
	int superSampleIndex = vr_SuperSampleIndex;

	float sum = 0.0;
	float weights[requiredSamples];
	vec4 samples[requiredSamples];
	vec4 result = vec4(0.0);

	// determine how much more samples will be taken for this hit point
	int nSamples = (requiredSamples > numSuperSamples) ? requiredSamples : numSuperSamples; // max
	nSamples /= numSuperSamples;
	int startSampleIndex = superSampleIndex * nSamples;

	options.rayGroup = VR_GLOSSY_DISPERSAL;
	for(int i = 0; i < nSamples; ++i) {
		vec3 randomSample = vr_randomSample(startSampleIndex + i, nSamples);
		vec2 offset = randomSample.xy - 0.5;
		offset *= (2.0 * amount);

		vec3 bumpedNormal = normal + offset.x * tangent + offset.y * binormal;
		options.normal = bumpedNormal;
 
		options.rayType = VR_TRACE_REFLECT;
		vec4 reflection = vr_trace(options);

		options.rayType = VR_TRACE_REFRACT;
		vec4 refraction = vr_trace(options);

		float cos_dn = clamp(-dot(direction, bumpedNormal), 0.0, 1.0);
		float lerpFactor = (1.0 - pow(cos_dn, 1.0 / blend));

		samples[i] = mix(refraction, reflection, lerpFactor);
		weights[i] = dot(normal, bumpedNormal);
		sum += weights[i];
	}

	float inverseSum = 1.0 / sum;
	for(int i = 0; i < nSamples; ++i) {
		weights[i] *= inverseSum;
		result += weights[i] * samples[i];
	}
 
	gl_FragColor = result;
}
```


---

###  **Example: Glossy Phong** 


```
#version 110

uniform float amount = 0.1;
uniform float diffuse_scalar = 0.7;
__color uniform vec4 diffuse_color = vec4(0.9, 0.2, 0.8, 1.0);
uniform float specular_scalar = 0.06;
uniform float specular_shininess = 20.0;

const int requiredSamples = 16;

float phong_specular(vec3 light_dir, vec3 direction, vec3 normal) {
	vec3 reflection = reflect(direction, normal);
	float cos_rl = clamp(dot(reflection, light_dir), 0.0, 1.0);
	return (pow(cos_rl, specular_shininess) * (specular_shininess + 2.0));
}

void main() {
	bool isGIRay = ((vr_RayFlags & VR_INDIRECT_FLAG) != 0);
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec3 direction = vr_Direction;
	vec3 position = vr_Position;

	vec4 raw_diffuse = vec4(vec3(diffuse_color) * diffuse_scalar, 1.0);
	vec4 raw_specular = vec4(vec3(specular_scalar), 1.0);

	vec4 temp = raw_diffuse + raw_specular;
	float max_color_comp = max(max(temp.r,temp.g),temp.b);
	if (max_color_comp > 1.0) {
		raw_diffuse.rgb /= max_color_comp;
		raw_specular.rgb /= max_color_comp;
	}

	vec4 diffuse_contrib = vec4(0.0, 0.0, 0.0, 1.0);
	vec4 specular_contrib = vec4(0.0, 0.0, 0.0, 1.0);

	// if this is a GI ray do not try to estimate glossy highlights accurately
	if(isGIRay) {
		vr_LightIterator light;
		for(int j = 0; j < vr_NumLights; ++j) {
			vr_evalLight(j, position, normal, light);

			float cos_nl = clamp(light.dot_nl, 0.0, 1.0);
			if (cos_nl > 0.0) {
				diffuse_contrib += vec4(cos_nl * light.contribution, 0.0);
				float specular_coeff = phong_specular(light.direction, direction, normal);
				specular_contrib += vec4(specular_coeff * cos_nl * light.contribution, 0.0);
			}
		}
	} else {
		vec3 tangent = vr_TexTangent;
		vec3 binormal = vr_TexBinormal;
		int numSuperSamples = vr_NumSuperSamples;
		int superSampleIndex = vr_SuperSampleIndex;

		float sum = 0.0;
		float weights[requiredSamples];
		vec4 specular_samples[requiredSamples];

		// determine how much more samples will be taken for this hit point
		int nSamples = (requiredSamples > numSuperSamples) ? requiredSamples : numSuperSamples; // max
		nSamples /= numSuperSamples;
		int startSampleIndex = superSampleIndex * nSamples;

		for(int i = 0; i < nSamples; ++i) {
			vec3 randomSample = vr_randomSample(startSampleIndex + i, nSamples);
			vec2 offset = (randomSample.xy - 0.5) * 2.0;
			offset *= amount;

			vec3 bumpedNormal = normalize(normal + offset.x * tangent + offset.y * binormal);

			vr_LightIterator light;
			for(int j = 0; j < vr_NumLights; ++j) {
				vr_evalLight(j, position, bumpedNormal, light);
				float cos_nl = clamp(light.dot_nl, 0.0, 1.0);
				if(cos_nl > 0.0) {
					diffuse_contrib += vec4(cos_nl * light.contribution, 0.0);
					float specular_coeff = phong_specular(light.direction, direction, bumpedNormal);
					specular_samples[i] += vec4(specular_coeff * light.contribution, 0.0);
				}
			}

			weights[i] = dot(normal, bumpedNormal);
			sum += weights[i];
		}

		float inverseSum = 1.0 / sum;
		for(int i = 0; i < nSamples; ++i) {
			weights[i] *= inverseSum;
			specular_contrib += weights[i] * specular_samples[i];
		}
 
		diffuse_contrib /= float(nSamples);
	}

	diffuse_contrib += vec4(vr_irradiance(normal, 1.0), 0.0);
	diffuse_contrib *= raw_diffuse;
	specular_contrib *= raw_specular;

	gl_FragColor = diffuse_contrib + specular_contrib;
}
```


---

###  **Example: Glossy Reflection** 


```
#version 110

uniform float amount = 0.1;

const int requiredSamples = 16;

void main() {
 
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
 
	vr_TraceOptions options;
	options.rayType = VR_TRACE_REFLECT;
	options.rayGroup = VR_SPECULAR_DISPERSAL;
	options.normal = normal;

	if((vr_RayFlags & VR_INDIRECT_FLAG) != 0) {
		gl_FragColor = vr_trace(options);
		return;
	}
 
	vec3 tangent = vr_TexTangent;
	vec3 binormal = vr_TexBinormal;
	int numSuperSamples = vr_NumSuperSamples;
	int superSampleIndex = vr_SuperSampleIndex;

	float sum = 0.0;
	float weights[requiredSamples];
	vec4 samples[requiredSamples];
	vec4 result = vec4(0.0);

	// determine how much more samples will be taken for this hit point
	int nSamples = (requiredSamples > numSuperSamples) ? requiredSamples : numSuperSamples; // max
	nSamples /= numSuperSamples;
	int startSampleIndex = superSampleIndex * nSamples;

	options.rayGroup = VR_GLOSSY_DISPERSAL;
	for(int i = 0; i < nSamples; ++i) {
		vec3 randomSample = vr_randomSample(startSampleIndex + i, nSamples);
		vec2 offset = (randomSample.xy - 0.5) * 2.0;
		offset *= amount;

		vec3 bumpedNormal = normalize(normal + offset.x * tangent + offset.y * binormal);
		options.normal = bumpedNormal;

		samples[i] = vr_trace(options);
		weights[i] = dot(normal, bumpedNormal);
		sum += weights[i];
	}
 
	float inverseSum = 1.0 / sum;
	for(int i = 0; i < nSamples; ++i) {
		weights[i] *= inverseSum;
		result += weights[i] * samples[i];
	}
 
	gl_FragColor = result;
}
```


---

###  **Example: Oren-Nayar** 


```
#version 110

__color uniform vec4 diffuse_color = vec4(1.0, 1.0, 0.0, 1.0);
uniform float diffuse_scalar = 0.7;
__color uniform vec4 specular_color = vec4(1.0, 1.0, 1.0 ,1.0);
uniform float specular_scalar = 0.06;
uniform float diffuse_deviation = 0.5;
uniform float specular_shininess = 10.0;

float orennayar_diffuse(vec3 light_dir, vec3 view_dir, vec3 normal) {
	float sigma_sqred = diffuse_deviation * diffuse_deviation;
	float A = 1.0 - (sigma_sqred / (2.0 * (sigma_sqred + 0.33)));
	float B = (0.45 * sigma_sqred) / (sigma_sqred + 0.09);
	float cosThetaI = dot(light_dir, normal);
	float cosThetaO = -dot(view_dir, normal);
	float sinThetaI = sqrt(max(0.0, 1.0 - (cosThetaI * cosThetaI)));
	float sinThetaO = sqrt(max(0.0, 1.0 - (cosThetaO * cosThetaO)));
	float cosPhiI = dot(light_dir, vr_TexTangent);
	float cosPhiO = -dot(view_dir, vr_TexTangent);
	float sinPhiI = sqrt(max(0.0, 1.0 - (cosPhiI * cosPhiI)));
	float sinPhiO = sqrt(max(0.0, 1.0 - (cosPhiO * cosPhiO)));
	float temp = max(0.0, (cosPhiI * cosPhiO) + (sinPhiI * sinPhiO));
	float sinAlpha;
	float tanBeta;
	if (cosThetaI > cosThetaO) {
		sinAlpha = sinThetaO;
		tanBeta = (sinThetaI / cosThetaI);
	} else {
		sinAlpha = sinThetaI;
		tanBeta = (sinThetaO / cosThetaO);
	}
	float result = (A + (B * temp * sinAlpha * tanBeta));
	return clamp(result, 0.0, 1.0);
}
 
float phong_specular(vec3 light_dir, vec3 view_dir, vec3 normal) {
	vec3 reflection = reflect(view_dir, normal);
	float cos_rl = clamp(dot(reflection, light_dir), 0.0, 1.0);
	return (pow(cos_rl, specular_shininess) * (specular_shininess + 2.0));
}

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
	vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);

	vec4 diffuse_contrib = vec4(vec3(diffuse_color) * diffuse_scalar, 1.0);
	vec4 specular_contrib = vec4(vec3(specular_color) * specular_scalar, 1.0);

	vec4 temp = diffuse_contrib + specular_contrib;
	float max_color_component = max(max(temp.r,temp.g),temp.b);
	if (max_color_component > 1.0) {
		diffuse_contrib.rgb /= max_color_component;
		specular_contrib.rgb /= max_color_component;
	}

	vec3 view_dir = vr_Direction;

	vr_LightIterator lightIter;
	for(int i = 0; i < vr_NumLights; ++i) {
		vr_evalLight(i, vr_Position, normal, lightIter);
		float cos_nl = clamp(lightIter.dot_nl, 0.0, 1.0);
		if (cos_nl > 0.0) {
			float diffuse_term = orennayar_diffuse(lightIter.direction, view_dir, normal);
			diffuse += vec4(vec3(diffuse_term * cos_nl) * lightIter.contribution, 0.0);
			float specular_term = phong_specular(lightIter.direction, view_dir, normal);
			specular += vec4(vec3(specular_term * cos_nl) * lightIter.contribution, 0.0);
		}
	}

	diffuse *= diffuse_contrib;
	specular *= specular_contrib;

	vec3 gi_contrib = vr_irradiance(normal, 1.0);
	diffuse += vec4(vec3(diffuse_contrib) * gi_contrib, 0.0);

	gl_FragColor = diffuse + specular;
}
```

---

###  **Example: Turbulence** 


```
#version 110

uniform float noise_scale = 2.0;
uniform float noise_gain = 0.8;
uniform float noise_lacunarity = 3.0;
__color uniform vec4 color1 = vec4(1.0, 1.0, 0.0, 1.0);
__color uniform vec4 color2 = vec4(1.0, 0.0, 0.0, 1.0);
uniform float diffuse_scalar = 0.8;
uniform float specular_scalar = 0.02;
uniform float specular_shininess = 10.0;

const int octaves_count = 4;

float phong_specular(vec3 light_dir, vec3 view_dir, vec3 normal, float specular_shininess) {
	vec3 reflection = reflect(view_dir, normal);
	float cos_rl = clamp(dot(reflection, light_dir), 0.0, 1.0);
	return (pow(cos_rl, specular_shininess) * (specular_shininess + 2.0));
}

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec3 position = vr_Position;
	vec3 direction = vr_Direction;
	vec3 noise_position = vec3(gl_TexCoord[0]);

	vec3 scaled_position = noise_position * vec3(noise_scale);
	float noise_amplitude = 2.0;
	float noise_frequency = 0.5;
	vec3 noise_value = vec3(0.0);

	if((vr_RayFlags & VR_INDIRECT_FLAG) != 0) {
		noise_value = vec3(0.5);
	} else {
		for (int i = 0; i < octaves_count; ++i) {
			noise_value += abs(noise3(scaled_position * vec3(noise_frequency))) * vec3(noise_amplitude);
			noise_frequency *= noise_lacunarity;
			noise_amplitude *= noise_gain;
		}
	}

	vec4 diffuse_color = mix(color1, color2, vec4(noise_value, 1.0));
	vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);

	vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
	vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);

	vec4 raw_diffuse = vec4(vec3(diffuse_color) * diffuse_scalar, 1.0);
	vec4 raw_specular = vec4(vec3(specular_color) * specular_scalar, 1.0);

	vec4 temp = raw_diffuse + raw_specular;
	float max_color_comp = max(max(temp.r,temp.g),temp.b);
	if (max_color_comp > 1.0) {
		raw_diffuse.rgb /= max_color_comp;
		raw_specular.rgb /= max_color_comp;
	}

	vr_LightIterator light;
	for(int i = 0; i < vr_NumLights; ++i) {
		vr_evalLight(i, position, normal, light);
		float cos_nl = clamp(light.dot_nl, 0.0, 1.0);
		if (cos_nl > 0.0) {
			diffuse += vec4(vec3(cos_nl) * light.contribution, 0.0);
			float specular_coeff = phong_specular(light.direction, direction, normal, specular_shininess);
			specular += vec4(vec3(specular_coeff * cos_nl) * light.contribution, 0.0);
		}
	}

	diffuse *= raw_diffuse;
	specular *= raw_specular;
 
	vec3 gi_contribution = vr_irradiance(normal, 1.0);
	
	diffuse += vec4(raw_diffuse.rgb * gi_contribution, 0.0);
 
	gl_FragColor = diffuse + specular;
}
```

---

###  **Example: Blinn Material** 


```
#version 110

uniform sampler2D diffuseTex;
__color uniform vec4 specular = vec4(1.0, 1.0, 1.0, 1.0);
uniform float highlightGlossiness = 0.8;
uniform sampler2D anisotropyTex;

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;
	vec2 uv_coords = vec2(gl_TexCoord[0]);

	vr_DiffuseBRDFSettings diffuseSettings;
	diffuseSettings.color = vec3(texture2D(diffuseTex, uv_coords));
	diffuseSettings.normal = normal;
	vr_brdf_diffuse(diffuseSettings);

	vr_GlossyBRDFSettings blinnSettings;
	blinnSettings.color = vec3(specular);
	blinnSettings.normal = normal;
	blinnSettings.highlightGlossiness = highlightGlossiness;
	blinnSettings.anisotropy = 2.0 * texture2D(anisotropyTex, uv_coords).x - 1.0;
	blinnSettings.traceReflections = false;
	vr_brdf_blinn(blinnSettings);

	gl_FragColor = vec4(vec3(0.0), 1.0);
}
```

---

###  **Example: Transparent Material** 


```
#version 110

__color uniform vec4 diffuse = vec4(0.6, 0.2, 1.0, 1.0);
uniform sampler2D transparency;

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;

	vr_DiffuseBRDFSettings diffuseSettings;
	diffuseSettings.color = vec3(diffuse);
	diffuseSettings.normal = normal;
	vr_brdf_diffuse(diffuseSettings);

	vec3 textureSample = vec3(texture2D(transparency, vec2(gl_TexCoord[0])));
	float alpha = dot(textureSample, vec3(0.3333333));
	gl_FragColor = vec4(vec3(0.0), alpha);
}
```


---

###  **Example: Render Channels** 


```
#version 110

__color uniform vec4 diffuse = vec4(0.3, 0.8, 0.2, 1.0);
__channel vec3 NormalSpace = vec3(0.314);

void main() {
	vec3 normal = (gl_FrontFacing) ? vr_Normal : -vr_Normal;

	NormalSpace = normal;

	vr_DiffuseBRDFSettings diffuseSettings;
	diffuseSettings.color = vec3(diffuse);
	diffuseSettings.normal = normal;
	vr_brdf_diffuse(diffuseSettings);

	gl_FragColor.a = 1.0;
}
```


##  **Notes** 

---

- **OpenGL Shading Language** specification officially supported is **1.10.59**
- <span style="color: #172b4d">**texture()**</span><span style="color: #172b4d"> is a synonym for </span><span style="color: #172b4d">**texture2D().**</span><span style="color: #172b4d"> It was added for compatibility with shaders written in GLSL 1.5. The V-Ray implementation of GLSL follows the GLSL 1.10 specification, but with a bunch of extensions to support more modern codebases. The texture() function</span><span style="color: #172b4d">** overload**</span><span style="color: #172b4d"> is one of them. Additionally, there is another set of texture overloads: </span><span style="color: #172b4d">**vec4 texture2D(sampler2D sampler, int reserved)**</span><span style="color: #172b4d"> and </span><span style="color: #172b4d">**vec4 texture(sampler2D sampler, int reserved)**</span><span style="color: #172b4d">, which are equivalent. They can be used to sample the given texture at the current UV-coordinates of the current intersection point, as these overloads do not require to explicitly specify a </span><span style="color: #172b4d">**coord**</span><span style="color: #172b4d"> argument. The </span><span style="color: #172b4d">**reserved**</span><span style="color: #172b4d"> parameter is not used and should be -1. These fixed-coordinates sampling functions are only available in V-Ray though and ideally one should guard such calls in </span><span style="color: #172b4d">**#ifdef **</span><span style="color: #172b4d">***_***</span>***VRAY_GLSL***<span style="color: #172b4d">***_***</span><span style="color: #172b4d">* *</span><span style="color: #172b4d">blocks.</span>