Implementing a Texture

From LuxCoreRender Wiki
Revision as of 17:21, 6 April 2020 by Byob (talk | contribs) (→‎OpenCL Code)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Note: this guide is not yet finished. All necessary steps for creating are texture are included, with C++ and OpenCL code, but some of the steps are not explained in detail yet.

C++ Code

Files that need to be created:

  • Header: include/slg/textures/yourtexturename.h
  • Source: src/slg/textures/yourtexturename.cpp

Files that need to be edited:

  • Base texture header: include/slg/textures/texture.h
  • Sceneparse: src/slg/scene/parsetextures.cpp
  • CMakeLists.txt: src/slg/CMakeLists.txt

Commit with example: adding the "Divide" texture: https://github.com/LuxCoreRender/LuxCore/commit/ce6e23c244b1bb426c1dcd13099a41982e565b88

Creating the header file

Creating the source file

Each texture has to implement the following methods:

Y()

The average luminance of the whole texture. You can use the Y() method of the Spectrum class to get this value.

In case this information cannot be computed, 1.0 should be returned.

Filter()

The average mean of the whole texture. You can use the Filter() method of the Spectrum class to get this value.

In case this information cannot be computed, 1.0 should be returned.

GetFloatValue(HitPoint)

This method is called when a texture slot of a material/volume/texture requests a float value from the texture. For example, the roughness slot of a glossy2 material would call this method, because the roughness is a floating point input.

It should return the float value at this particular hitpoint.

GetSpectrumValue(HitPoint)

This method is called when a Spectrum (RGB color) value is requested from the texture.

It should return the color value at this particular hitpoint.

If your texture is only usable for floating point math, you can return a Spectrum constructed from the floating point result:

return Spectrum(GetFloatValue(hitPoint));

Modifying the base texture header

Open the file include/slg/textures/texture.h
Add your new texture type to the TextureType enum.

Modifying Sceneparse

Open src/slg/scene/parsetextures.cpp
Include the new header file you created for your texture (the list is alphabetic).

Next, go to the method Scene::CreateTexture, scroll down until the end of the big if/else statement and add a new else if for your texture.

Modifying CMakeLists.txt

Open src/slg/CMakeLists.txt
Search for set(SLG_CORE_SRCS and add your source filepath among the other textures (they are sorted alphabetically).

Compile and Test

To test your plugin, compile LuxCore: Compiling_LuxCore

After the compilation succeeds, you will need a scene to test your plugin. The easiest method is to edit one of the .scn files in the scenes/luxball directory.

TODO Example

Now, run luxcoreui from the root LuxCore directory with

./bin/luxcoreui ./scenes/luxball/luxball-sunset.cfg

TODO result example image

OpenCL Code

Note: This section is currently outdated after the OpenCL material/texture rework in v2.4!

Files that need to be edited:

  • include/slg/textures/texture_funcs.cl
  • include/slg/textures/texture_types.cl
  • src/slg/engines/pathoclbase/compiletextures.cpp
  • src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp

include/slg/textures/texture_funcs.cl

//------------------------------------------------------------------------------
// Your texture
//------------------------------------------------------------------------------

#if defined(PARAM_ENABLE_TEX_YOURS)

OPENCL_FORCE_NOT_INLINE float YourTexture_ConstEvaluateFloat(__global HitPoint *hitPoint,
		const float tex1, const float tex2) {
	// The actual work is done here (this function is executed when a float value of your texture is requested)
	return tex1 * tex2;
}

OPENCL_FORCE_NOT_INLINE float3 YourTexture_ConstEvaluateSpectrum(__global HitPoint *hitPoint,
		const float3 tex1, const float3 tex2) {
	// The actual work is done here (this function is executed when a color value of your texture is requested)
	return tex1 * tex2;
}

#endif

include/slg/textures/texture_types.cl

Add a new texture type for your texture to the TextureType enum.

If your texture has input parameters, create a new struct in the form

typedef struct {
	unsigned int tex1Index, tex2Index;
} YourTexParam;

and add it to the big union in the Texture struct.

src/slg/engines/pathoclbase/compiletextures.cpp

Include the C++ header of your texture.

Add a new case for your function to the CompiledScene::CompileTextures() method.

Add a new case for your function to the CompiledScene::GetTexturesEvaluationSourceCode() method.

src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp

Add a new if statement for your texture to the PathOCLBaseOCLRenderThread::InitKernels() method.